shell32: Localize 'new folder' string.
[wine/wine-kai.git] / dlls / wined3d / utils.c
blob2b7aa40a5a39066ceda15707de96125aa2dfad06
1 /*
2 * Utility functions for the WineD3D Library
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2007 Henri Verbeet
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "config.h"
26 #include "wined3d_private.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
30 /*****************************************************************************
31 * Pixel format array
33 static const StaticPixelFormatDesc formats[] = {
34 /*{WINED3DFORMAT ,alphamask ,redmask ,greenmask ,bluemask ,bpp ,depth ,stencil, isFourcc*/
35 {WINED3DFMT_UNKNOWN ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
36 /* FourCC formats, kept here to have WINED3DFMT_R8G8B8(=20) at position 20 */
37 {WINED3DFMT_UYVY ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
38 {WINED3DFMT_YUY2 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
39 {WINED3DFMT_DXT1 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
40 {WINED3DFMT_DXT2 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
41 {WINED3DFMT_DXT3 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
42 {WINED3DFMT_DXT4 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
43 {WINED3DFMT_DXT5 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
44 {WINED3DFMT_MULTI2_ARGB8,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
45 {WINED3DFMT_G8R8_G8B8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
46 {WINED3DFMT_R8G8_B8G8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
47 /* IEEE formats */
48 {WINED3DFMT_R32F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
49 {WINED3DFMT_G32R32F ,0x0 ,0x0 ,0x0 ,0x0 ,8 ,0 ,0 ,FALSE },
50 {WINED3DFMT_A32B32G32R32F,0x0 ,0x0 ,0x0 ,0x0 ,16 ,0 ,0 ,FALSE },
51 /* Hmm? */
52 {WINED3DFMT_CxV8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
53 /* Float */
54 {WINED3DFMT_R16F ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
55 {WINED3DFMT_G16R16F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
56 {WINED3DFMT_A16B16G16R16F,0x0 ,0x0 ,0x0 ,0x0 ,8 ,0 ,0 ,FALSE },
57 /* Palettized formats */
58 {WINED3DFMT_A8P8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
59 {WINED3DFMT_P8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
60 /* Standard ARGB formats. Keep WINED3DFMT_R8G8B8(=20) at position 20 */
61 {WINED3DFMT_R8G8B8 ,0x0 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,3 ,0 ,0 ,FALSE },
62 {WINED3DFMT_A8R8G8B8 ,0xff000000 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,0 ,0 ,FALSE },
63 {WINED3DFMT_X8R8G8B8 ,0x0 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,0 ,0 ,FALSE },
64 {WINED3DFMT_R5G6B5 ,0x0 ,0x0000F800 ,0x000007e0 ,0x0000001f ,2 ,0 ,0 ,FALSE },
65 {WINED3DFMT_X1R5G5B5 ,0x0 ,0x00007c00 ,0x000003e0 ,0x0000001f ,2 ,0 ,0 ,FALSE },
66 {WINED3DFMT_A1R5G5B5 ,0x00008000 ,0x00007c00 ,0x000003e0 ,0x0000001f ,2 ,0 ,0 ,FALSE },
67 {WINED3DFMT_A4R4G4B4 ,0x0000f000 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,0 ,0 ,FALSE },
68 {WINED3DFMT_R3G3B2 ,0x0 ,0x000000e0 ,0x0000001c ,0x00000003 ,1 ,0 ,0 ,FALSE },
69 {WINED3DFMT_A8 ,0x000000ff ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
70 {WINED3DFMT_A8R3G3B2 ,0x0000ff00 ,0x000000e0 ,0x0000001c ,0x00000003 ,2 ,0 ,0 ,FALSE },
71 {WINED3DFMT_X4R4G4B4 ,0x0 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,0 ,0 ,FALSE },
72 {WINED3DFMT_A2B10G10R10 ,0xb0000000 ,0x000003ff ,0x000ffc00 ,0x3ff00000 ,4 ,0 ,0 ,FALSE },
73 {WINED3DFMT_A8B8G8R8 ,0xff000000 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,0 ,0 ,FALSE },
74 {WINED3DFMT_X8B8G8R8 ,0x0 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,0 ,0 ,FALSE },
75 {WINED3DFMT_G16R16 ,0x0 ,0x0000ffff ,0xffff0000 ,0x0 ,4 ,0 ,0 ,FALSE },
76 {WINED3DFMT_A2R10G10B10 ,0xb0000000 ,0x3ff00000 ,0x000ffc00 ,0x000003ff ,4 ,0 ,0 ,FALSE },
77 {WINED3DFMT_A16B16G16R16,0x0 ,0x0000ffff ,0xffff0000 ,0x0 ,8 ,0 ,0 ,FALSE },
78 /* Luminance */
79 {WINED3DFMT_L8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
80 {WINED3DFMT_A8L8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
81 {WINED3DFMT_A4L4 ,0x000000f0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
82 /* Bump mapping stuff */
83 {WINED3DFMT_V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
84 {WINED3DFMT_L6V5U5 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
85 {WINED3DFMT_X8L8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
86 {WINED3DFMT_Q8W8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
87 {WINED3DFMT_V16U16 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
88 {WINED3DFMT_W11V11U10 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
89 {WINED3DFMT_A2W10V10U10 ,0xb0000000 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
90 /* Depth stencil formats */
91 {WINED3DFMT_D16_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,2 ,16 ,0 ,FALSE },
92 {WINED3DFMT_D32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,32 ,0 ,FALSE },
93 {WINED3DFMT_D15S1 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,15 ,1 ,FALSE },
94 {WINED3DFMT_D24S8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,8 ,FALSE },
95 {WINED3DFMT_D24X8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,0 ,FALSE },
96 {WINED3DFMT_D24X4S4 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,4 ,FALSE },
97 {WINED3DFMT_D16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,16 ,0 ,FALSE },
98 {WINED3DFMT_L16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,16 ,0 ,FALSE },
99 {WINED3DFMT_D32F_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,4 ,32 ,0 ,FALSE },
100 {WINED3DFMT_D24FS8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,8 ,FALSE },
101 /* Is this a vertex buffer? */
102 {WINED3DFMT_VERTEXDATA ,0x0 ,0x0 ,0x0 ,0x0 ,0 ,0 ,0 ,FALSE },
103 {WINED3DFMT_INDEX16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
104 {WINED3DFMT_INDEX32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
105 {WINED3DFMT_Q16W16V16U16,0x0 ,0x0 ,0x0 ,0x0 ,8 ,0 ,0 ,FALSE },
108 typedef struct {
109 WINED3DFORMAT fmt;
110 GLint glInternal, glGammaInternal, rtInternal, glFormat, glType;
111 } GlPixelFormatDescTemplate;
113 /*****************************************************************************
114 * OpenGL format template. Contains unexciting formats which do not need
115 * extension checks. The order in this table is independent of the order in
116 * the table StaticPixelFormatDesc above. Not all formats have to be in this
117 * table.
119 static const GlPixelFormatDescTemplate gl_formats_template[] = {
120 /*{ internal ,srgbInternal , rtInternal, format ,type }*/
121 {WINED3DFMT_UNKNOWN ,0 ,0 , 0, 0 ,0 },
122 /* FourCC formats */
123 {WINED3DFMT_UYVY ,0 ,0 , 0, 0 ,0 },
124 {WINED3DFMT_YUY2 ,0 ,0 , 0, 0 ,0 },
125 {WINED3DFMT_DXT1 ,GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT , 0, GL_RGBA ,GL_UNSIGNED_BYTE },
126 {WINED3DFMT_DXT2 ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT , 0, GL_RGBA ,GL_UNSIGNED_BYTE },
127 {WINED3DFMT_DXT3 ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT , 0, GL_RGBA ,GL_UNSIGNED_BYTE },
128 {WINED3DFMT_DXT4 ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT , 0, GL_RGBA ,GL_UNSIGNED_BYTE },
129 {WINED3DFMT_DXT5 ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT , 0, GL_RGBA ,GL_UNSIGNED_BYTE },
130 {WINED3DFMT_MULTI2_ARGB8 ,0 ,0 , 0, 0 ,0 },
131 {WINED3DFMT_G8R8_G8B8 ,0 ,0 , 0, 0 ,0 },
132 {WINED3DFMT_R8G8_B8G8 ,0 ,0 , 0, 0 ,0 },
133 /* IEEE formats */
134 {WINED3DFMT_R32F ,GL_RGB32F_ARB ,GL_RGB32F_ARB , 0, GL_RED ,GL_FLOAT },
135 {WINED3DFMT_G32R32F ,0 ,0 , 0, 0 ,0 },
136 {WINED3DFMT_A32B32G32R32F ,GL_RGBA32F_ARB ,GL_RGBA32F_ARB , 0, GL_RGBA ,GL_FLOAT },
137 /* Hmm? */
138 {WINED3DFMT_CxV8U8 ,0 ,0 , 0, 0 ,0 },
139 /* Float */
140 {WINED3DFMT_R16F ,GL_RGB16F_ARB ,GL_RGB16F_ARB , 0, GL_RED ,GL_HALF_FLOAT_ARB },
141 {WINED3DFMT_G16R16F ,0 ,0 , 0, 0 ,0 },
142 {WINED3DFMT_A16B16G16R16F ,GL_RGBA16F_ARB ,GL_RGBA16F_ARB , 0, GL_RGBA ,GL_HALF_FLOAT_ARB },
143 /* Palettized formats */
144 {WINED3DFMT_A8P8, 0 ,0 , 0, 0 ,0 },
145 {WINED3DFMT_P8, GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX8_EXT , 0, GL_COLOR_INDEX ,GL_UNSIGNED_BYTE },
146 /* Standard ARGB formats */
147 {WINED3DFMT_R8G8B8 ,GL_RGB8 ,GL_RGB8 , 0, GL_BGR ,GL_UNSIGNED_BYTE },
148 {WINED3DFMT_A8R8G8B8 ,GL_RGBA8 ,GL_SRGB8_ALPHA8_EXT , 0, GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
149 {WINED3DFMT_X8R8G8B8 ,GL_RGB8 ,GL_SRGB8_EXT , 0, GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
150 {WINED3DFMT_R5G6B5 ,GL_RGB5 ,GL_RGB5 , GL_RGB8, GL_RGB ,GL_UNSIGNED_SHORT_5_6_5 },
151 {WINED3DFMT_X1R5G5B5 ,GL_RGB5 ,GL_RGB5_A1 , 0, GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV },
152 {WINED3DFMT_A1R5G5B5 ,GL_RGB5_A1 ,GL_RGB5_A1 , 0, GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV },
153 {WINED3DFMT_A4R4G4B4 ,GL_RGBA4 ,GL_SRGB8_ALPHA8_EXT , 0, GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
154 {WINED3DFMT_R3G3B2 ,GL_R3_G3_B2 ,GL_R3_G3_B2 , 0, GL_RGB ,GL_UNSIGNED_BYTE_3_3_2 },
155 {WINED3DFMT_A8 ,GL_ALPHA8 ,GL_ALPHA8 , 0, GL_ALPHA ,GL_UNSIGNED_BYTE },
156 {WINED3DFMT_A8R3G3B2 ,0 ,0 , 0, 0 ,0 },
157 {WINED3DFMT_X4R4G4B4 ,GL_RGB4 ,GL_RGB4 , 0, GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
158 {WINED3DFMT_A2B10G10R10 ,GL_RGBA ,GL_RGBA , 0, GL_RGBA ,GL_UNSIGNED_INT_2_10_10_10_REV },
159 {WINED3DFMT_A8B8G8R8 ,GL_RGBA8 ,GL_RGBA8 , 0, GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
160 {WINED3DFMT_X8B8G8R8 ,GL_RGB8 ,GL_RGB8 , 0, GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
161 {WINED3DFMT_G16R16 ,0 ,0 , 0, 0 ,0 },
162 {WINED3DFMT_A2R10G10B10 ,GL_RGBA ,GL_RGBA , 0, GL_BGRA ,GL_UNSIGNED_INT_2_10_10_10_REV },
163 {WINED3DFMT_A16B16G16R16 ,GL_RGBA16_EXT ,GL_RGBA16_EXT , 0, GL_RGBA ,GL_UNSIGNED_SHORT },
164 /* Luminance */
165 {WINED3DFMT_L8 ,GL_LUMINANCE8 ,GL_SLUMINANCE8_EXT , 0, GL_LUMINANCE ,GL_UNSIGNED_BYTE },
166 {WINED3DFMT_A8L8 ,GL_LUMINANCE8_ALPHA8 ,GL_SLUMINANCE8_ALPHA8_EXT , 0, GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE },
167 {WINED3DFMT_A4L4 ,GL_LUMINANCE4_ALPHA4 ,GL_LUMINANCE4_ALPHA4 , 0, GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE },
168 /* Bump mapping stuff */
169 {WINED3DFMT_V8U8 ,GL_DSDT8_NV ,GL_DSDT8_NV , 0, GL_DSDT_NV ,GL_BYTE },
170 {WINED3DFMT_L6V5U5 ,GL_DSDT8_MAG8_NV ,GL_DSDT8_MAG8_NV , 0, GL_DSDT_MAG_NV ,GL_BYTE },
171 {WINED3DFMT_X8L8V8U8 ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT8_MAG8_INTENSITY8_NV , 0, GL_DSDT_MAG_VIB_NV ,GL_UNSIGNED_INT_8_8_S8_S8_REV_NV},
172 {WINED3DFMT_Q8W8V8U8 ,GL_SIGNED_RGBA8_NV ,GL_SIGNED_RGBA8_NV , 0, GL_RGBA ,GL_BYTE },
173 {WINED3DFMT_V16U16 ,GL_SIGNED_HILO16_NV ,GL_SIGNED_HILO16_NV , 0, GL_HILO_NV ,GL_SHORT },
174 {WINED3DFMT_W11V11U10 ,0 ,0 , 0, 0 ,0 },
175 {WINED3DFMT_A2W10V10U10 ,0 ,0 , 0, 0 ,0 },
176 /* Depth stencil formats */
177 {WINED3DFMT_D16_LOCKABLE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT },
178 {WINED3DFMT_D32 ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT32_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
179 {WINED3DFMT_D15S1 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT },
180 {WINED3DFMT_D24S8 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
181 {WINED3DFMT_D24X8 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
182 {WINED3DFMT_D24X4S4 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
183 {WINED3DFMT_D16 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT },
184 {WINED3DFMT_L16 ,GL_LUMINANCE16_EXT ,GL_LUMINANCE16_EXT , 0, GL_LUMINANCE ,GL_UNSIGNED_SHORT },
185 {WINED3DFMT_D32F_LOCKABLE ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT32_ARB , 0, GL_DEPTH_COMPONENT ,GL_FLOAT },
186 {WINED3DFMT_D24FS8 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_FLOAT },
187 /* Is this a vertex buffer? */
188 {WINED3DFMT_VERTEXDATA ,0 ,0 , 0, 0 ,0 },
189 {WINED3DFMT_INDEX16 ,0 ,0 , 0, 0 ,0 },
190 {WINED3DFMT_INDEX32 ,0 ,0 , 0, 0 ,0 },
191 {WINED3DFMT_Q16W16V16U16 ,GL_COLOR_INDEX ,GL_COLOR_INDEX , 0, GL_COLOR_INDEX ,GL_UNSIGNED_SHORT }
194 static inline int getFmtIdx(WINED3DFORMAT fmt) {
195 /* First check if the format is at the position of its value.
196 * This will catch the argb formats before the loop is entered
198 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
199 return fmt;
200 } else {
201 unsigned int i;
202 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
203 if(formats[i].format == fmt) {
204 return i;
208 return -1;
211 #define GLINFO_LOCATION (*gl_info)
212 BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
214 unsigned int src;
215 int dst;
217 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
218 sizeof(formats) / sizeof(formats[0]) * sizeof(gl_info->gl_formats[0]));
219 if(!gl_info->gl_formats) return FALSE;
221 /* If a format depends on some extensions, remove them from the table above and initialize them
222 * after this loop
224 for(src = 0; src < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); src++) {
225 dst = getFmtIdx(gl_formats_template[src].fmt);
226 gl_info->gl_formats[dst].glInternal = gl_formats_template[src].glInternal;
227 gl_info->gl_formats[dst].glGammaInternal = gl_formats_template[src].glGammaInternal;
228 gl_info->gl_formats[dst].glFormat = gl_formats_template[src].glFormat;
229 gl_info->gl_formats[dst].glType = gl_formats_template[src].glType;
230 gl_info->gl_formats[dst].conversion_group= WINED3DFMT_UNKNOWN;
232 if(wined3d_settings.offscreen_rendering_mode == ORM_FBO &&
233 gl_formats_template[src].rtInternal != 0) {
234 GLuint tex, fb;
235 GLenum status;
237 /* Check if the default internal format is supported as a frame buffer target, otherwise
238 * fall back to the render target internal.
240 * Try to stick to the standard format if possible, this limits precision differences
242 while(glGetError());
243 glGenTextures(1, &tex);
244 glBindTexture(GL_TEXTURE_2D, tex);
245 glTexImage2D(GL_TEXTURE_2D, 0, gl_formats_template[src].glInternal, 16, 16, 0,
246 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
248 GL_EXTCALL(glGenFramebuffersEXT(1, &fb));
249 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb));
250 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
251 GL_TEXTURE_2D, tex, 0));
253 status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
254 GL_EXTCALL(glDeleteFramebuffersEXT(1, &fb));
255 glDeleteTextures(1, &tex);
257 checkGLcall("Framebuffer format check");
259 if(status != GL_FRAMEBUFFER_COMPLETE_EXT) {
260 TRACE("Internal format of %s not supported as frame buffer target, using render target internal instead\n",
261 debug_d3dformat(gl_formats_template[src].fmt));
262 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].rtInternal;
263 } else {
264 TRACE("Format %s is supported as fbo target\n", debug_d3dformat(gl_formats_template[src].fmt));
265 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].glInternal;
268 } else {
269 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].glInternal;
273 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
274 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
275 * their extensions are not available.
277 * In theory, V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
278 * returns 0.0 when sampling from it, DirectX 1.0. This is disabled until we find
279 * an application that needs this because it causes performance problems due to
280 * shader recompiling in some games.
282 if(!GL_SUPPORT(ATI_ENVMAP_BUMPMAP) && !GL_SUPPORT(NV_TEXTURE_SHADER2)) {
283 /* signed -> unsigned fixup */
284 dst = getFmtIdx(WINED3DFMT_V8U8);
285 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
286 dst = getFmtIdx(WINED3DFMT_V16U16);
287 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
288 } else if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
289 /* signed -> unsigned fixup */
290 dst = getFmtIdx(WINED3DFMT_V16U16);
291 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V16U16;
292 } else {
293 /* Blue = 1.0 fixup, disabled for now */
294 #if 0
295 dst = getFmtIdx(WINED3DFMT_V8U8);
296 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
297 dst = getFmtIdx(WINED3DFMT_V16U16);
298 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
299 #endif
302 if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
303 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
304 * with each other
306 dst = getFmtIdx(WINED3DFMT_L6V5U5);
307 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_L6V5U5;
308 dst = getFmtIdx(WINED3DFMT_X8L8V8U8);
309 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_X8L8V8U8;
310 dst = getFmtIdx(WINED3DFMT_Q8W8V8U8);
311 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_Q8W8V8U8;
312 } else {
313 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
314 * are converted at surface loading time, but they do not need any modification in
315 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
316 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
320 return TRUE;
322 #undef GLINFO_LOCATION
324 #define GLINFO_LOCATION This->adapter->gl_info
326 const StaticPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, WineD3D_GL_Info *gl_info, const GlPixelFormatDesc **glDesc)
328 int idx = getFmtIdx(fmt);
330 if(idx == -1) {
331 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
332 /* Get the caller a valid pointer */
333 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
335 if(glDesc) {
336 if(!gl_info) {
337 ERR("OpenGL pixel format information was requested, but no gl info structure passed\n");
338 return NULL;
340 *glDesc = &gl_info->gl_formats[idx];
342 return &formats[idx];
345 /*****************************************************************************
346 * Trace formatting of useful values
348 const char* debug_d3dformat(WINED3DFORMAT fmt) {
349 switch (fmt) {
350 #define FMT_TO_STR(fmt) case fmt: return #fmt
351 FMT_TO_STR(WINED3DFMT_UNKNOWN);
352 FMT_TO_STR(WINED3DFMT_R8G8B8);
353 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
354 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
355 FMT_TO_STR(WINED3DFMT_R5G6B5);
356 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
357 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
358 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
359 FMT_TO_STR(WINED3DFMT_R3G3B2);
360 FMT_TO_STR(WINED3DFMT_A8);
361 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
362 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
363 FMT_TO_STR(WINED3DFMT_A2B10G10R10);
364 FMT_TO_STR(WINED3DFMT_A8B8G8R8);
365 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
366 FMT_TO_STR(WINED3DFMT_G16R16);
367 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
368 FMT_TO_STR(WINED3DFMT_A16B16G16R16);
369 FMT_TO_STR(WINED3DFMT_A8P8);
370 FMT_TO_STR(WINED3DFMT_P8);
371 FMT_TO_STR(WINED3DFMT_L8);
372 FMT_TO_STR(WINED3DFMT_A8L8);
373 FMT_TO_STR(WINED3DFMT_A4L4);
374 FMT_TO_STR(WINED3DFMT_V8U8);
375 FMT_TO_STR(WINED3DFMT_L6V5U5);
376 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
377 FMT_TO_STR(WINED3DFMT_Q8W8V8U8);
378 FMT_TO_STR(WINED3DFMT_V16U16);
379 FMT_TO_STR(WINED3DFMT_W11V11U10);
380 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
381 FMT_TO_STR(WINED3DFMT_UYVY);
382 FMT_TO_STR(WINED3DFMT_YUY2);
383 FMT_TO_STR(WINED3DFMT_DXT1);
384 FMT_TO_STR(WINED3DFMT_DXT2);
385 FMT_TO_STR(WINED3DFMT_DXT3);
386 FMT_TO_STR(WINED3DFMT_DXT4);
387 FMT_TO_STR(WINED3DFMT_DXT5);
388 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
389 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
390 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
391 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
392 FMT_TO_STR(WINED3DFMT_D32);
393 FMT_TO_STR(WINED3DFMT_D15S1);
394 FMT_TO_STR(WINED3DFMT_D24S8);
395 FMT_TO_STR(WINED3DFMT_D24X8);
396 FMT_TO_STR(WINED3DFMT_D24X4S4);
397 FMT_TO_STR(WINED3DFMT_D16);
398 FMT_TO_STR(WINED3DFMT_L16);
399 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
400 FMT_TO_STR(WINED3DFMT_D24FS8);
401 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
402 FMT_TO_STR(WINED3DFMT_INDEX16);
403 FMT_TO_STR(WINED3DFMT_INDEX32);
404 FMT_TO_STR(WINED3DFMT_Q16W16V16U16);
405 FMT_TO_STR(WINED3DFMT_R16F);
406 FMT_TO_STR(WINED3DFMT_G16R16F);
407 FMT_TO_STR(WINED3DFMT_A16B16G16R16F);
408 FMT_TO_STR(WINED3DFMT_R32F);
409 FMT_TO_STR(WINED3DFMT_G32R32F);
410 FMT_TO_STR(WINED3DFMT_A32B32G32R32F);
411 FMT_TO_STR(WINED3DFMT_CxV8U8);
412 #undef FMT_TO_STR
413 default:
415 char fourcc[5];
416 fourcc[0] = (char)(fmt);
417 fourcc[1] = (char)(fmt >> 8);
418 fourcc[2] = (char)(fmt >> 16);
419 fourcc[3] = (char)(fmt >> 24);
420 fourcc[4] = 0;
421 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
422 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
423 else
424 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
426 return "unrecognized";
430 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
431 switch (devtype) {
432 #define DEVTYPE_TO_STR(dev) case dev: return #dev
433 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
434 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
435 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
436 #undef DEVTYPE_TO_STR
437 default:
438 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
439 return "unrecognized";
443 const char* debug_d3dusage(DWORD usage) {
444 switch (usage & WINED3DUSAGE_MASK) {
445 #define WINED3DUSAGE_TO_STR(u) case u: return #u
446 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
447 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
448 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
449 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
450 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
451 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
452 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
453 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
454 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
455 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
456 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
457 #undef WINED3DUSAGE_TO_STR
458 case 0: return "none";
459 default:
460 FIXME("Unrecognized %u Usage!\n", usage);
461 return "unrecognized";
465 const char* debug_d3dusagequery(DWORD usagequery) {
466 switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
467 #define WINED3DUSAGEQUERY_TO_STR(u) case u: return #u
468 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
469 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
470 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
471 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
472 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
473 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
474 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
475 #undef WINED3DUSAGEQUERY_TO_STR
476 case 0: return "none";
477 default:
478 FIXME("Unrecognized %u Usage Query!\n", usagequery);
479 return "unrecognized";
483 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
484 switch (method) {
485 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
486 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
487 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
488 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
489 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
490 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
491 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
492 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
493 #undef WINED3DDECLMETHOD_TO_STR
494 default:
495 FIXME("Unrecognized %u declaration method!\n", method);
496 return "unrecognized";
500 const char* debug_d3ddecltype(WINED3DDECLTYPE type) {
501 switch (type) {
502 #define WINED3DDECLTYPE_TO_STR(u) case u: return #u
503 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT1);
504 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT2);
505 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT3);
506 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT4);
507 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_D3DCOLOR);
508 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4);
509 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2);
510 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4);
511 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4N);
512 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2N);
513 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4N);
514 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT2N);
515 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT4N);
516 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UDEC3);
517 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_DEC3N);
518 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_2);
519 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_4);
520 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UNUSED);
521 #undef WINED3DDECLTYPE_TO_STR
522 default:
523 FIXME("Unrecognized %u declaration type!\n", type);
524 return "unrecognized";
528 const char* debug_d3ddeclusage(BYTE usage) {
529 switch (usage) {
530 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
531 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
532 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
533 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
534 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
535 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
536 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
537 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
538 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
539 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
540 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
541 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
542 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
543 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
544 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
545 #undef WINED3DDECLUSAGE_TO_STR
546 default:
547 FIXME("Unrecognized %u declaration usage!\n", usage);
548 return "unrecognized";
552 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
553 switch (res) {
554 #define RES_TO_STR(res) case res: return #res;
555 RES_TO_STR(WINED3DRTYPE_SURFACE);
556 RES_TO_STR(WINED3DRTYPE_VOLUME);
557 RES_TO_STR(WINED3DRTYPE_TEXTURE);
558 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
559 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
560 RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER);
561 RES_TO_STR(WINED3DRTYPE_INDEXBUFFER);
562 #undef RES_TO_STR
563 default:
564 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
565 return "unrecognized";
569 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
570 switch (PrimitiveType) {
571 #define PRIM_TO_STR(prim) case prim: return #prim;
572 PRIM_TO_STR(WINED3DPT_POINTLIST);
573 PRIM_TO_STR(WINED3DPT_LINELIST);
574 PRIM_TO_STR(WINED3DPT_LINESTRIP);
575 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
576 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
577 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
578 #undef PRIM_TO_STR
579 default:
580 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
581 return "unrecognized";
585 const char* debug_d3drenderstate(DWORD state) {
586 switch (state) {
587 #define D3DSTATE_TO_STR(u) case u: return #u
588 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
589 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
590 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
591 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
592 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
593 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
594 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
595 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
596 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
597 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
598 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
599 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
600 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
601 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
602 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
603 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
604 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
605 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
606 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
607 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
608 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
609 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
610 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
611 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
612 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
613 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
614 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
615 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
616 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
617 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
618 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
619 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
620 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
621 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
622 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
623 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
624 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
625 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
626 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
627 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
628 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
629 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
630 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
631 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
632 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
633 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
634 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
635 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
636 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
637 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
638 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
639 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
640 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
641 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
642 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
643 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
644 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
645 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
646 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
647 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
648 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
649 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
650 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
651 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
652 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
653 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
654 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
655 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
656 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
657 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
658 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
659 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
660 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
661 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
662 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
663 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
664 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
665 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
666 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
667 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
668 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
669 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
670 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
671 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
672 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
673 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
674 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
675 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
676 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
677 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
678 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
679 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
680 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
681 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
682 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
683 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
684 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
685 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
686 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
687 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
688 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
689 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
690 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
691 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
692 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
693 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
694 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
695 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
696 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
697 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
698 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
699 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
700 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
701 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
702 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
703 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
704 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
705 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
706 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
707 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
708 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
709 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
710 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
711 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
712 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
713 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
714 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
715 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
716 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
717 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
718 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
719 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
720 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
721 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
722 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
723 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
724 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
725 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
726 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
727 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
728 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
729 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
730 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
731 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
732 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
733 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
734 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
735 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
736 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
737 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
738 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
739 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
740 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
741 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
742 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
743 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
744 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
745 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
746 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
747 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
748 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
749 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
750 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
751 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
752 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
753 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
754 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
755 #undef D3DSTATE_TO_STR
756 default:
757 FIXME("Unrecognized %u render state!\n", state);
758 return "unrecognized";
762 const char* debug_d3dsamplerstate(DWORD state) {
763 switch (state) {
764 #define D3DSTATE_TO_STR(u) case u: return #u
765 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
766 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
767 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
768 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
769 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
770 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
771 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
772 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
773 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
774 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
775 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
776 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
777 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
778 #undef D3DSTATE_TO_STR
779 default:
780 FIXME("Unrecognized %u sampler state!\n", state);
781 return "unrecognized";
785 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
786 switch (filter_type) {
787 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
788 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
789 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
790 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
791 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
792 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
793 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
794 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
795 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
796 #undef D3DTEXTUREFILTERTYPE_TO_STR
797 default:
798 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
799 return "unrecognized";
803 const char* debug_d3dtexturestate(DWORD state) {
804 switch (state) {
805 #define D3DSTATE_TO_STR(u) case u: return #u
806 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
807 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
808 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
809 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
810 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
811 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
812 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
813 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
814 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
815 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
816 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
817 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
818 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
819 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
820 D3DSTATE_TO_STR(WINED3DTSS_ADDRESSW );
821 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
822 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
823 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
824 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
825 #undef D3DSTATE_TO_STR
826 case 12:
827 /* Note WINED3DTSS are not consecutive, so skip these */
828 return "unused";
829 default:
830 FIXME("Unrecognized %u texture state!\n", state);
831 return "unrecognized";
835 static const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
836 switch (d3dtop) {
837 #define D3DTOP_TO_STR(u) case u: return #u
838 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
839 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
840 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
841 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
842 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
843 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
844 D3DTOP_TO_STR(WINED3DTOP_ADD);
845 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
846 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
847 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
848 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
849 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
850 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
851 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
852 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
853 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
854 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
855 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
856 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
857 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
858 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
859 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
860 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
861 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
862 D3DTOP_TO_STR(WINED3DTOP_LERP);
863 #undef D3DTOP_TO_STR
864 default:
865 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
866 return "unrecognized";
870 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
871 switch (tstype) {
872 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
873 TSTYPE_TO_STR(WINED3DTS_VIEW);
874 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
875 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
876 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
877 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
878 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
879 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
880 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
881 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
882 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
883 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
884 #undef TSTYPE_TO_STR
885 default:
886 if (tstype > 256 && tstype < 512) {
887 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
888 return ("WINED3DTS_WORLDMATRIX > 0");
890 FIXME("Unrecognized %u WINED3DTS\n", tstype);
891 return "unrecognized";
895 const char* debug_d3dpool(WINED3DPOOL Pool) {
896 switch (Pool) {
897 #define POOL_TO_STR(p) case p: return #p;
898 POOL_TO_STR(WINED3DPOOL_DEFAULT);
899 POOL_TO_STR(WINED3DPOOL_MANAGED);
900 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
901 POOL_TO_STR(WINED3DPOOL_SCRATCH);
902 #undef POOL_TO_STR
903 default:
904 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
905 return "unrecognized";
909 const char *debug_fbostatus(GLenum status) {
910 switch(status) {
911 #define FBOSTATUS_TO_STR(u) case u: return #u
912 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
913 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
914 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
915 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
916 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
917 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
918 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
919 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
920 #undef FBOSTATUS_TO_STR
921 default:
922 FIXME("Unrecognied FBO status 0x%08x\n", status);
923 return "unrecognized";
927 const char *debug_glerror(GLenum error) {
928 switch(error) {
929 #define GLERROR_TO_STR(u) case u: return #u
930 GLERROR_TO_STR(GL_NO_ERROR);
931 GLERROR_TO_STR(GL_INVALID_ENUM);
932 GLERROR_TO_STR(GL_INVALID_VALUE);
933 GLERROR_TO_STR(GL_INVALID_OPERATION);
934 GLERROR_TO_STR(GL_STACK_OVERFLOW);
935 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
936 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
937 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
938 #undef GLERROR_TO_STR
939 default:
940 FIXME("Unrecognied GL error 0x%08x\n", error);
941 return "unrecognized";
945 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
946 switch(basis) {
947 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
948 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
949 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
950 default: return "unrecognized";
954 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
955 switch(degree) {
956 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
957 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
958 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
959 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
960 default: return "unrecognized";
964 /*****************************************************************************
965 * Useful functions mapping GL <-> D3D values
967 GLenum StencilOp(DWORD op) {
968 switch(op) {
969 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
970 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
971 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
972 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
973 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
974 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
975 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
976 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
977 default:
978 FIXME("Unrecognized stencil op %d\n", op);
979 return GL_KEEP;
983 GLenum CompareFunc(DWORD func) {
984 switch ((WINED3DCMPFUNC)func) {
985 case WINED3DCMP_NEVER : return GL_NEVER;
986 case WINED3DCMP_LESS : return GL_LESS;
987 case WINED3DCMP_EQUAL : return GL_EQUAL;
988 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
989 case WINED3DCMP_GREATER : return GL_GREATER;
990 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
991 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
992 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
993 default:
994 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
995 return 0;
999 static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) {
1000 switch (d3dta) {
1001 case WINED3DTA_DIFFUSE:
1002 return GL_PRIMARY_COLOR_NV;
1004 case WINED3DTA_CURRENT:
1005 if (stage) return GL_SPARE0_NV;
1006 else return GL_PRIMARY_COLOR_NV;
1008 case WINED3DTA_TEXTURE:
1009 if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx;
1010 else return GL_PRIMARY_COLOR_NV;
1012 case WINED3DTA_TFACTOR:
1013 return GL_CONSTANT_COLOR0_NV;
1015 case WINED3DTA_SPECULAR:
1016 return GL_SECONDARY_COLOR_NV;
1018 case WINED3DTA_TEMP:
1019 /* TODO: Support WINED3DTSS_RESULTARG */
1020 FIXME("WINED3DTA_TEMP, not properly supported.\n");
1021 return GL_SPARE1_NV;
1023 case WINED3DTA_CONSTANT:
1024 /* TODO: Support per stage constants (WINED3DTSS_CONSTANT, NV_register_combiners2) */
1025 FIXME("WINED3DTA_CONSTANT, not properly supported.\n");
1026 return GL_CONSTANT_COLOR1_NV;
1028 default:
1029 FIXME("Unrecognized texture arg %#x\n", d3dta);
1030 return GL_TEXTURE;
1034 static GLenum invert_mapping(GLenum mapping) {
1035 if (mapping == GL_UNSIGNED_INVERT_NV) return GL_SIGNED_IDENTITY_NV;
1036 else if (mapping == GL_SIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV;
1038 FIXME("Unhandled mapping %#x\n", mapping);
1039 return mapping;
1042 static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) {
1043 /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should
1044 * be used. */
1045 if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV;
1046 else *mapping = GL_SIGNED_IDENTITY_NV;
1048 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input
1049 * should be used for all input components. */
1050 if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA;
1051 else *component_usage = GL_RGB;
1053 *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx);
1056 typedef struct {
1057 GLenum input[3];
1058 GLenum mapping[3];
1059 GLenum component_usage[3];
1060 } tex_op_args;
1062 static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1063 if (op == WINED3DTOP_DISABLE) return FALSE;
1064 if (This->stateBlock->textures[stage]) return FALSE;
1066 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1067 && op != WINED3DTOP_SELECTARG2) return TRUE;
1068 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1069 && op != WINED3DTOP_SELECTARG1) return TRUE;
1070 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1071 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1073 return FALSE;
1076 void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx) {
1077 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface;
1078 tex_op_args tex_op_args = {{0}, {0}, {0}};
1079 GLenum portion = is_alpha ? GL_ALPHA : GL_RGB;
1080 GLenum target = GL_COMBINER0_NV + stage;
1082 TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1083 stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx);
1085 /* If a texture stage references an invalid texture unit the stage just
1086 * passes through the result from the previous stage */
1087 if (is_invalid_op(This, stage, op, arg1, arg2, arg3)) {
1088 arg1 = WINED3DTA_CURRENT;
1089 op = WINED3DTOP_SELECTARG1;
1092 get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0],
1093 &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx);
1094 get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1],
1095 &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx);
1096 get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2],
1097 &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx);
1100 /* This is called by a state handler which has the gl lock held and a context for the thread */
1101 switch(op)
1103 case WINED3DTOP_DISABLE:
1104 /* Only for alpha */
1105 if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n");
1106 /* Input, prev_alpha*1 */
1107 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1108 GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
1109 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1110 GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
1112 /* Output */
1113 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1114 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1115 break;
1117 case WINED3DTOP_SELECTARG1:
1118 case WINED3DTOP_SELECTARG2:
1119 /* Input, arg*1 */
1120 if (op == WINED3DTOP_SELECTARG1) {
1121 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1122 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1123 } else {
1124 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1125 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1127 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1128 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1130 /* Output */
1131 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1132 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1133 break;
1135 case WINED3DTOP_MODULATE:
1136 case WINED3DTOP_MODULATE2X:
1137 case WINED3DTOP_MODULATE4X:
1138 /* Input, arg1*arg2 */
1139 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1140 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1141 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1142 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1144 /* Output */
1145 if (op == WINED3DTOP_MODULATE) {
1146 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1147 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1148 } else if (op == WINED3DTOP_MODULATE2X) {
1149 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1150 GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1151 } else if (op == WINED3DTOP_MODULATE4X) {
1152 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1153 GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1155 break;
1157 case WINED3DTOP_ADD:
1158 case WINED3DTOP_ADDSIGNED:
1159 case WINED3DTOP_ADDSIGNED2X:
1160 /* Input, arg1*1+arg2*1 */
1161 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1162 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1163 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1164 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1165 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1166 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1167 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1168 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1170 /* Output */
1171 if (op == WINED3DTOP_ADD) {
1172 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1173 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1174 } else if (op == WINED3DTOP_ADDSIGNED) {
1175 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1176 GL_SPARE0_NV, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
1177 } else if (op == WINED3DTOP_ADDSIGNED2X) {
1178 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1179 GL_SPARE0_NV, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
1181 break;
1183 case WINED3DTOP_SUBTRACT:
1184 /* Input, arg1*1+-arg2*1 */
1185 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1186 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1187 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1188 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1189 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1190 tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1]));
1191 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1192 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1194 /* Output */
1195 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1196 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1197 break;
1199 case WINED3DTOP_ADDSMOOTH:
1200 /* Input, arg1*1+(1-arg1)*arg2 */
1201 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1202 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1203 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1204 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1205 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1206 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1207 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1208 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1210 /* Output */
1211 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1212 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1213 break;
1215 case WINED3DTOP_BLENDDIFFUSEALPHA:
1216 case WINED3DTOP_BLENDTEXTUREALPHA:
1217 case WINED3DTOP_BLENDFACTORALPHA:
1218 case WINED3DTOP_BLENDTEXTUREALPHAPM:
1219 case WINED3DTOP_BLENDCURRENTALPHA:
1221 GLenum alpha_src = GL_PRIMARY_COLOR_NV;
1222 if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx);
1223 else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
1224 else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx);
1225 else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
1226 else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx);
1227 else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op));
1229 /* Input, arg1*alpha_src+arg2*(1-alpha_src) */
1230 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1231 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1232 if (op == WINED3DTOP_BLENDTEXTUREALPHAPM)
1234 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1235 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1236 } else {
1237 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1238 alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
1240 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1241 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1242 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1243 alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
1245 /* Output */
1246 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1247 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1248 break;
1251 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1252 /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */
1253 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n");
1254 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1255 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1256 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1257 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1258 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1259 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1260 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1261 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1263 /* Output */
1264 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1265 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1266 break;
1268 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1269 /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */
1270 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n");
1271 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1272 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1273 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1274 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1275 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1276 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1277 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1278 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1280 /* Output */
1281 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1282 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1283 break;
1285 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1286 /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */
1287 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n");
1288 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1289 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA));
1290 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1291 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1292 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1293 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1294 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1295 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1297 /* Output */
1298 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1299 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1300 break;
1302 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1303 /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */
1304 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n");
1305 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1306 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1307 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1308 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1309 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1310 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1311 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1312 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1314 /* Output */
1315 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1316 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1317 break;
1319 case WINED3DTOP_DOTPRODUCT3:
1320 /* Input, arg1 . arg2 */
1321 /* FIXME: DX7 uses a different calculation? */
1322 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1323 tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0]));
1324 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1325 tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1]));
1327 /* Output */
1328 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1329 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE));
1330 break;
1332 case WINED3DTOP_MULTIPLYADD:
1333 /* Input, arg1*1+arg2*arg3 */
1334 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1335 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1336 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1337 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1338 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1339 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1340 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1341 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1343 /* Output */
1344 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1345 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1346 break;
1348 case WINED3DTOP_LERP:
1349 /* Input, arg1*arg2+(1-arg1)*arg3 */
1350 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1351 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1352 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1353 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1354 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1355 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1356 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1357 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1359 /* Output */
1360 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1361 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1362 break;
1364 case WINED3DTOP_BUMPENVMAPLUMINANCE:
1365 case WINED3DTOP_BUMPENVMAP:
1366 if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
1367 /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to
1368 * perform bump mapping and source from the current stage. Pretty much a SELECTARG2.
1369 * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1
1370 * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the next stage
1372 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1373 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1374 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1375 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1376 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1377 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1378 break;
1381 default:
1382 FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1383 stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
1386 checkGLcall("set_tex_op_nvrc()\n");
1390 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
1391 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
1392 * input should be used for all input components. The WINED3DTA_COMPLEMENT
1393 * flag specifies the complement of the input should be used. */
1394 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
1395 BOOL complement = arg & WINED3DTA_COMPLEMENT;
1397 /* Calculate the operand */
1398 if (complement) {
1399 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
1400 else *operand = GL_ONE_MINUS_SRC_COLOR;
1401 } else {
1402 if (from_alpha) *operand = GL_SRC_ALPHA;
1403 else *operand = GL_SRC_COLOR;
1406 /* Calculate the source */
1407 switch (arg & WINED3DTA_SELECTMASK) {
1408 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
1409 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
1410 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
1411 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
1412 case WINED3DTA_SPECULAR:
1414 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
1415 * 'Secondary color' and isn't supported until base GL supports it
1416 * There is no concept of temp registers as far as I can tell
1418 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
1419 *source = GL_TEXTURE;
1420 break;
1421 default:
1422 FIXME("Unrecognized texture arg %#x\n", arg);
1423 *source = GL_TEXTURE;
1424 break;
1428 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
1429 #if defined (GL_VERSION_1_3)
1430 # define useext(A) A
1431 # define combine_ext 1
1432 #elif defined (GL_EXT_texture_env_combine)
1433 # define useext(A) A##_EXT
1434 # define combine_ext 1
1435 #elif defined (GL_ARB_texture_env_combine)
1436 # define useext(A) A##_ARB
1437 # define combine_ext 1
1438 #else
1439 # undef combine_ext
1440 #endif
1442 #if !defined(combine_ext)
1443 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1445 FIXME("Requires opengl combine extensions to work\n");
1446 return;
1448 #else
1449 /* Setup the texture operations texture stage states */
1450 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1452 GLenum src1, src2, src3;
1453 GLenum opr1, opr2, opr3;
1454 GLenum comb_target;
1455 GLenum src0_target, src1_target, src2_target;
1456 GLenum opr0_target, opr1_target, opr2_target;
1457 GLenum scal_target;
1458 GLenum opr=0, invopr, src3_target, opr3_target;
1459 BOOL Handled = FALSE;
1460 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
1462 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
1464 /* This is called by a state handler which has the gl lock held and a context for the thread */
1466 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
1467 the form (a1 <operation> a2). However, some of the more complex operations
1468 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
1469 in a third parameter called a0. Therefore these are operations of the form
1470 a0 <operation> a1 <operation> a2, ie the new parameter goes to the front.
1472 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
1473 functions below, expect their syntax to differ slightly to those listed in the
1474 manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
1475 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
1477 if (isAlpha) {
1478 comb_target = useext(GL_COMBINE_ALPHA);
1479 src0_target = useext(GL_SOURCE0_ALPHA);
1480 src1_target = useext(GL_SOURCE1_ALPHA);
1481 src2_target = useext(GL_SOURCE2_ALPHA);
1482 opr0_target = useext(GL_OPERAND0_ALPHA);
1483 opr1_target = useext(GL_OPERAND1_ALPHA);
1484 opr2_target = useext(GL_OPERAND2_ALPHA);
1485 scal_target = GL_ALPHA_SCALE;
1487 else {
1488 comb_target = useext(GL_COMBINE_RGB);
1489 src0_target = useext(GL_SOURCE0_RGB);
1490 src1_target = useext(GL_SOURCE1_RGB);
1491 src2_target = useext(GL_SOURCE2_RGB);
1492 opr0_target = useext(GL_OPERAND0_RGB);
1493 opr1_target = useext(GL_OPERAND1_RGB);
1494 opr2_target = useext(GL_OPERAND2_RGB);
1495 scal_target = useext(GL_RGB_SCALE);
1498 /* If a texture stage references an invalid texture unit the stage just
1499 * passes through the result from the previous stage */
1500 if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) {
1501 arg1 = WINED3DTA_CURRENT;
1502 op = WINED3DTOP_SELECTARG1;
1505 /* From MSDN (WINED3DTSS_ALPHAARG1) :
1506 The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage,
1507 then the default argument is WINED3DTA_DIFFUSE.
1508 FIXME? If texture added/removed, may need to reset back as well? */
1509 if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
1510 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
1511 } else {
1512 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
1514 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
1515 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
1517 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
1519 Handled = TRUE; /* Assume will be handled */
1521 /* Other texture operations require special extensions: */
1522 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1523 if (isAlpha) {
1524 opr = GL_SRC_ALPHA;
1525 invopr = GL_ONE_MINUS_SRC_ALPHA;
1526 src3_target = GL_SOURCE3_ALPHA_NV;
1527 opr3_target = GL_OPERAND3_ALPHA_NV;
1528 } else {
1529 opr = GL_SRC_COLOR;
1530 invopr = GL_ONE_MINUS_SRC_COLOR;
1531 src3_target = GL_SOURCE3_RGB_NV;
1532 opr3_target = GL_OPERAND3_RGB_NV;
1534 switch (op) {
1535 case WINED3DTOP_DISABLE: /* Only for alpha */
1536 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1537 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1538 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1539 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1540 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1541 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1542 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1543 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1544 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1545 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1546 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1547 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1548 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1549 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1550 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1551 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1552 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1553 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1554 break;
1555 case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */
1556 case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
1557 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1558 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1559 if (op == WINED3DTOP_SELECTARG1) {
1560 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1561 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1562 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1563 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1564 } else {
1565 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1566 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1567 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1568 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1570 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1571 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1572 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1573 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1574 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1575 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1576 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1577 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1578 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1579 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1580 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1581 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1582 break;
1584 case WINED3DTOP_MODULATE:
1585 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1586 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1587 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1588 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1589 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1590 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1591 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1592 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1593 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1594 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1595 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1596 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1597 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1598 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1599 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1600 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1601 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1602 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1603 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1604 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1605 break;
1606 case WINED3DTOP_MODULATE2X:
1607 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1608 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1609 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1610 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1611 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1612 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1613 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1614 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1615 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1616 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1617 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1618 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1619 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1620 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1621 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1622 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1623 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1624 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1625 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1626 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1627 break;
1628 case WINED3DTOP_MODULATE4X:
1629 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1630 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1631 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1632 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1633 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1634 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1635 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1636 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1637 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1638 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1639 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1640 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1641 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1642 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1643 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1644 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1645 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1646 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1647 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
1648 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
1649 break;
1651 case WINED3DTOP_ADD:
1652 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1653 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1654 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1655 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1656 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1657 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1658 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1659 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1660 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1661 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1662 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1663 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1664 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1665 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1666 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1667 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1668 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1669 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1670 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1671 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1672 break;
1674 case WINED3DTOP_ADDSIGNED:
1675 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1676 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1677 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1678 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1679 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1680 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1681 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1682 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1683 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1684 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1685 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1686 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1687 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1688 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1689 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1690 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1691 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1692 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1693 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1694 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1695 break;
1697 case WINED3DTOP_ADDSIGNED2X:
1698 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1699 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1700 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1701 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1702 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1703 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1704 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1705 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1706 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1707 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1708 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1709 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1710 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1711 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1712 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1713 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1714 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1715 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1716 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1717 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1718 break;
1720 case WINED3DTOP_ADDSMOOTH:
1721 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1722 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1723 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1724 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1725 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1726 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1727 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1728 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1729 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1730 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1731 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1732 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1733 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1734 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1735 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1736 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1737 switch (opr1) {
1738 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1739 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1740 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1741 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1743 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1744 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1745 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1746 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1747 break;
1749 case WINED3DTOP_BLENDDIFFUSEALPHA:
1750 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1751 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1752 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1753 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1754 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1755 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1756 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
1757 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
1758 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1759 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1760 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1761 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1762 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1763 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1764 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
1765 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
1766 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1767 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1768 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1769 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1770 break;
1771 case WINED3DTOP_BLENDTEXTUREALPHA:
1772 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1773 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1774 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1775 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1776 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1777 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1778 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
1779 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
1780 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1781 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1782 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1783 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1784 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1785 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1786 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1787 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1788 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1789 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1790 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1791 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1792 break;
1793 case WINED3DTOP_BLENDFACTORALPHA:
1794 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1795 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1796 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1797 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1798 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1799 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1800 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
1801 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
1802 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1803 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1804 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1805 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1806 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1807 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1808 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
1809 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
1810 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1811 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1812 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1813 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1814 break;
1815 case WINED3DTOP_BLENDTEXTUREALPHAPM:
1816 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1817 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1818 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1819 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1820 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1821 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1822 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1823 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1824 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1825 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1826 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1827 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1828 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1829 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1830 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1831 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1832 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1833 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1834 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1835 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1836 break;
1837 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1838 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1839 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1840 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
1841 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1842 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1843 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
1844 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1845 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1846 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1847 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1848 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
1849 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1850 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1851 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
1852 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1853 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1854 switch (opr) {
1855 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1856 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1858 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1859 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1860 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1861 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1862 break;
1863 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1864 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1865 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1866 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1867 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1868 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1869 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1870 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1871 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1872 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1873 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1874 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1875 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1876 switch (opr1) {
1877 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1878 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1880 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1881 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1882 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1883 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1884 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1885 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1886 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1887 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1888 break;
1889 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1890 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1891 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1892 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1893 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1894 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1895 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1896 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1897 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1898 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1899 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1900 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1901 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1902 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1903 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1904 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1905 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1906 switch (opr1) {
1907 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1908 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1909 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1910 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1912 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1913 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1914 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1915 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1916 break;
1917 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1918 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1919 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1920 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1921 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1922 switch (opr1) {
1923 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1924 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1925 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1926 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1928 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
1929 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
1930 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1931 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1932 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1933 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1934 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1935 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1936 switch (opr1) {
1937 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1938 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1940 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1941 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1942 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1943 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1944 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1945 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1946 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1947 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1948 break;
1949 case WINED3DTOP_MULTIPLYADD:
1950 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1951 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1952 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
1953 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1954 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
1955 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1956 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1957 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1958 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1959 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1960 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1961 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1962 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1963 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1964 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
1965 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
1966 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
1967 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
1968 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1969 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1970 break;
1972 case WINED3DTOP_BUMPENVMAP:
1976 case WINED3DTOP_BUMPENVMAPLUMINANCE:
1977 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
1979 default:
1980 Handled = FALSE;
1982 if (Handled) {
1983 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
1984 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
1986 return;
1988 } /* GL_NV_texture_env_combine4 */
1990 Handled = TRUE; /* Again, assume handled */
1991 switch (op) {
1992 case WINED3DTOP_DISABLE: /* Only for alpha */
1993 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1994 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1995 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1996 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
1997 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1998 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
1999 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2000 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2001 break;
2002 case WINED3DTOP_SELECTARG1:
2003 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2004 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2005 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2006 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2007 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2008 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2009 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2010 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2011 break;
2012 case WINED3DTOP_SELECTARG2:
2013 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2014 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2015 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2016 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2017 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2018 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2019 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2020 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2021 break;
2022 case WINED3DTOP_MODULATE:
2023 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2024 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2025 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2026 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2027 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2028 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2029 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2030 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2031 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2032 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2033 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2034 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2035 break;
2036 case WINED3DTOP_MODULATE2X:
2037 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2038 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2039 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2040 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2041 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2042 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2043 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2044 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2045 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2046 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2047 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2048 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2049 break;
2050 case WINED3DTOP_MODULATE4X:
2051 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2052 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2053 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2054 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2055 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2056 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2057 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2058 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2059 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2060 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2061 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2062 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2063 break;
2064 case WINED3DTOP_ADD:
2065 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2066 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2067 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2068 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2069 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2070 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2071 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2072 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2073 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2074 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2075 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2076 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2077 break;
2078 case WINED3DTOP_ADDSIGNED:
2079 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2080 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
2081 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2082 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2083 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2084 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2085 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2086 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2087 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2088 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2089 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2090 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2091 break;
2092 case WINED3DTOP_ADDSIGNED2X:
2093 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2094 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2095 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2096 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2097 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2098 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2099 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2100 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2101 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2102 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2103 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2104 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2105 break;
2106 case WINED3DTOP_SUBTRACT:
2107 if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
2108 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2109 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
2110 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2111 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2112 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2113 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2114 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2115 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2116 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2117 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2118 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2119 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2120 } else {
2121 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2123 break;
2125 case WINED3DTOP_BLENDDIFFUSEALPHA:
2126 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2127 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2128 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2129 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2130 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2131 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2132 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2133 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2134 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2135 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2136 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
2137 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2138 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2139 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2140 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2141 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2142 break;
2143 case WINED3DTOP_BLENDTEXTUREALPHA:
2144 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2145 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2146 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2147 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2148 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2149 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2150 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2151 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2152 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2153 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2154 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2155 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2156 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2157 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2158 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2159 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2160 break;
2161 case WINED3DTOP_BLENDFACTORALPHA:
2162 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2163 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2164 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2165 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2166 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2167 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2168 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2169 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2170 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2171 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2172 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
2173 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2174 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2175 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2176 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2177 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2178 break;
2179 case WINED3DTOP_BLENDCURRENTALPHA:
2180 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2181 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2182 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2183 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2184 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2185 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2186 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2187 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2188 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2189 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2190 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
2191 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2192 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2193 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2194 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2195 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2196 break;
2197 case WINED3DTOP_DOTPRODUCT3:
2198 if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
2199 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2200 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2201 } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
2202 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2203 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2204 } else {
2205 FIXME("This version of opengl does not support GL_DOT3\n");
2207 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2208 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2209 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2210 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2211 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2212 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2213 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2214 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2215 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2216 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2217 break;
2218 case WINED3DTOP_LERP:
2219 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2220 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2221 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2222 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2223 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2224 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2225 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2226 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2227 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2228 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2229 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2230 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2231 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2232 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2233 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2234 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2235 break;
2236 case WINED3DTOP_ADDSMOOTH:
2237 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2238 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2239 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2240 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2241 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2242 switch (opr1) {
2243 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2244 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2245 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2246 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2248 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2249 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2250 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2251 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2252 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2253 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2254 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2255 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2256 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2257 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2258 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2259 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2260 } else
2261 Handled = FALSE;
2262 break;
2263 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2264 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2265 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2266 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2267 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2268 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2269 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2270 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2271 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2272 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2273 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2274 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2275 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2276 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2277 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2278 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2279 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2280 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2281 } else
2282 Handled = FALSE;
2283 break;
2284 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2285 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2286 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2287 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2288 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2289 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2290 switch (opr1) {
2291 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2292 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2293 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2294 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2296 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2297 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2298 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2299 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2300 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2301 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2302 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2303 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2304 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2305 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2306 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2307 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2308 } else
2309 Handled = FALSE;
2310 break;
2311 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2312 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2313 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2314 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2315 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2316 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2317 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2318 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2319 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2320 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2321 switch (opr1) {
2322 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2323 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2324 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2325 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2327 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2328 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2329 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2330 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2331 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2332 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2333 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2334 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2335 } else
2336 Handled = FALSE;
2337 break;
2338 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2339 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2340 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2341 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2342 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2343 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2344 switch (opr1) {
2345 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2346 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2347 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2348 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2350 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2351 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2352 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2353 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2354 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2355 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2356 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2357 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2358 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2359 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2360 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2361 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2362 } else
2363 Handled = FALSE;
2364 break;
2365 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2366 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2367 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2368 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2369 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2370 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2371 switch (opr1) {
2372 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2373 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2374 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2375 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2377 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2378 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2379 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2380 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2381 switch (opr1) {
2382 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2383 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2384 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2385 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2387 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2388 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2389 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2390 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2391 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2392 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2393 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2394 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2395 } else
2396 Handled = FALSE;
2397 break;
2398 case WINED3DTOP_MULTIPLYADD:
2399 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2400 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2401 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2402 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2403 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2404 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2405 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2406 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2407 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2408 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2409 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2410 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2411 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2412 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2413 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2414 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2415 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2416 } else
2417 Handled = FALSE;
2418 break;
2419 case WINED3DTOP_BUMPENVMAPLUMINANCE:
2420 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2421 /* Some apps use BUMPENVMAPLUMINANCE instead of D3DTOP_BUMPENVMAP, although
2422 * they check for the non-luminance cap flag. Well, give them what they asked
2423 * for :-)
2425 WARN("Application uses WINED3DTOP_BUMPENVMAPLUMINANCE\n");
2426 } else {
2427 Handled = FALSE;
2428 break;
2430 /* Fall through */
2431 case WINED3DTOP_BUMPENVMAP:
2432 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2433 TRACE("Using ati bumpmap on stage %d, target %d\n", Stage, Stage + 1);
2434 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI);
2435 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI)");
2436 glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1);
2437 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1)");
2438 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2439 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2440 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2441 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2442 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2443 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2444 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2445 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2446 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2447 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2448 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2449 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2451 Handled = TRUE;
2452 break;
2453 } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2454 /* Technically texture shader support without register combiners is possible, but not expected to occur
2455 * on real world cards, so for now a fixme should be enough
2457 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
2459 default:
2460 Handled = FALSE;
2463 if (Handled) {
2464 BOOL combineOK = TRUE;
2465 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2466 DWORD op2;
2468 if (isAlpha) {
2469 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP];
2470 } else {
2471 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP];
2474 /* Note: If COMBINE4 in effect can't go back to combine! */
2475 switch (op2) {
2476 case WINED3DTOP_ADDSMOOTH:
2477 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2478 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2479 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2480 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2481 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2482 case WINED3DTOP_MULTIPLYADD:
2483 /* Ignore those implemented in both cases */
2484 switch (op) {
2485 case WINED3DTOP_SELECTARG1:
2486 case WINED3DTOP_SELECTARG2:
2487 combineOK = FALSE;
2488 Handled = FALSE;
2489 break;
2490 default:
2491 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
2492 return;
2497 if (combineOK) {
2498 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
2499 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
2501 return;
2505 /* After all the extensions, if still unhandled, report fixme */
2506 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
2507 #undef GLINFO_LOCATION
2509 #endif
2511 /* Setup this textures matrix according to the texture flags*/
2512 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype)
2514 float mat[16];
2516 glMatrixMode(GL_TEXTURE);
2517 checkGLcall("glMatrixMode(GL_TEXTURE)");
2519 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2520 glLoadIdentity();
2521 checkGLcall("glLoadIdentity()");
2522 return;
2525 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2526 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2527 return;
2530 memcpy(mat, smat, 16 * sizeof(float));
2532 if (flags & WINED3DTTFF_PROJECTED) {
2533 switch (flags & ~WINED3DTTFF_PROJECTED) {
2534 case WINED3DTTFF_COUNT2:
2535 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2536 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2537 break;
2538 case WINED3DTTFF_COUNT3:
2539 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2540 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2541 break;
2543 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2544 if(!calculatedCoords) {
2545 switch(coordtype) {
2546 case WINED3DDECLTYPE_FLOAT1:
2547 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2548 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2549 * the input value to the transformation will be 0, so the matrix value is irrelevant
2551 mat[12] = mat[4];
2552 mat[13] = mat[5];
2553 mat[14] = mat[6];
2554 mat[15] = mat[7];
2555 break;
2556 case WINED3DDECLTYPE_FLOAT2:
2557 /* See above, just 3rd and 4th coord
2559 mat[12] = mat[8];
2560 mat[13] = mat[9];
2561 mat[14] = mat[10];
2562 mat[15] = mat[11];
2563 break;
2564 case WINED3DDECLTYPE_FLOAT3: /* Opengl defaults match dx defaults */
2565 case WINED3DDECLTYPE_FLOAT4: /* No defaults apply, all app defined */
2567 /* This is to prevent swaping the matrix lines and put the default 4th coord = 1.0
2568 * into a bad place. The division elimination below will apply to make sure the
2569 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2571 case WINED3DDECLTYPE_UNUSED: /* No texture coords, 0/0/0/1 defaults are passed */
2572 break;
2573 default:
2574 FIXME("Unexpected fixed function texture coord input\n");
2577 switch (flags & ~WINED3DTTFF_PROJECTED) {
2578 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2579 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2580 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2581 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2582 * the 4th coord evaluates to 1.0 to eliminate that.
2584 * If the fixed function pipeline is used, the 4th value remains unused,
2585 * so there is no danger in doing this. With vertex shaders we have a
2586 * problem. Should an app hit that problem, the code here would have to
2587 * check for pixel shaders, and the shader has to undo the default gl divide.
2589 * A more serious problem occurs if the app passes 4 coordinates in, and the
2590 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2591 * or a replacement shader
2593 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2597 glLoadMatrixf(mat);
2598 checkGLcall("glLoadMatrixf(mat)");
2601 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
2603 /* This small helper function is used to convert a bitmask into the number of masked bits */
2604 unsigned int count_bits(unsigned int mask)
2606 unsigned int count;
2607 for (count = 0; mask; ++count)
2609 mask &= mask - 1;
2611 return count;
2614 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2615 * The later function requires individual color components. */
2616 BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2618 const StaticPixelFormatDesc *desc;
2620 TRACE("fmt: %s\n", debug_d3dformat(fmt));
2621 switch(fmt)
2623 case WINED3DFMT_X8R8G8B8:
2624 case WINED3DFMT_R8G8B8:
2625 case WINED3DFMT_A8R8G8B8:
2626 case WINED3DFMT_A2R10G10B10:
2627 case WINED3DFMT_X1R5G5B5:
2628 case WINED3DFMT_A1R5G5B5:
2629 case WINED3DFMT_R5G6B5:
2630 case WINED3DFMT_X4R4G4B4:
2631 case WINED3DFMT_A4R4G4B4:
2632 case WINED3DFMT_R3G3B2:
2633 case WINED3DFMT_A8P8:
2634 case WINED3DFMT_P8:
2635 break;
2636 default:
2637 ERR("Unsupported format: %s\n", debug_d3dformat(fmt));
2638 return FALSE;
2641 desc = getFormatDescEntry(fmt, NULL, NULL);
2642 if(!desc)
2644 ERR("Unable to look up format: 0x%x\n", fmt);
2645 return FALSE;
2647 *redSize = count_bits(desc->redMask);
2648 *greenSize = count_bits(desc->greenMask);
2649 *blueSize = count_bits(desc->blueMask);
2650 *alphaSize = count_bits(desc->alphaMask);
2651 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2653 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n", *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(fmt));
2654 return TRUE;
2657 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2658 BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize)
2660 const StaticPixelFormatDesc *desc;
2662 TRACE("fmt: %s\n", debug_d3dformat(fmt));
2663 switch(fmt)
2665 case WINED3DFMT_D16_LOCKABLE:
2666 case WINED3DFMT_D16:
2667 case WINED3DFMT_D15S1:
2668 case WINED3DFMT_D24X8:
2669 case WINED3DFMT_D24X4S4:
2670 case WINED3DFMT_D24S8:
2671 case WINED3DFMT_D24FS8:
2672 case WINED3DFMT_D32:
2673 break;
2674 default:
2675 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(fmt));
2676 return FALSE;
2679 desc = getFormatDescEntry(fmt, NULL, NULL);
2680 if(!desc)
2682 ERR("Unable to look up format: 0x%x\n", fmt);
2683 return FALSE;
2685 *depthSize = desc->depthSize;
2686 *stencilSize = desc->stencilSize;
2688 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n", *depthSize, *stencilSize, debug_d3dformat(fmt));
2689 return TRUE;
2692 #undef GLINFO_LOCATION
2694 /* DirectDraw stuff */
2695 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2696 switch(depth) {
2697 case 8: return WINED3DFMT_P8;
2698 case 15: return WINED3DFMT_X1R5G5B5;
2699 case 16: return WINED3DFMT_R5G6B5;
2700 case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
2701 case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplatMode to return X8R8G8B8 */
2702 default: return WINED3DFMT_UNKNOWN;
2706 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2707 WINED3DMATRIX temp;
2709 /* Now do the multiplication 'by hand'.
2710 I know that all this could be optimised, but this will be done later :-) */
2711 temp.u.s._11 = (src1->u.s._11 * src2->u.s._11) + (src1->u.s._21 * src2->u.s._12) + (src1->u.s._31 * src2->u.s._13) + (src1->u.s._41 * src2->u.s._14);
2712 temp.u.s._21 = (src1->u.s._11 * src2->u.s._21) + (src1->u.s._21 * src2->u.s._22) + (src1->u.s._31 * src2->u.s._23) + (src1->u.s._41 * src2->u.s._24);
2713 temp.u.s._31 = (src1->u.s._11 * src2->u.s._31) + (src1->u.s._21 * src2->u.s._32) + (src1->u.s._31 * src2->u.s._33) + (src1->u.s._41 * src2->u.s._34);
2714 temp.u.s._41 = (src1->u.s._11 * src2->u.s._41) + (src1->u.s._21 * src2->u.s._42) + (src1->u.s._31 * src2->u.s._43) + (src1->u.s._41 * src2->u.s._44);
2716 temp.u.s._12 = (src1->u.s._12 * src2->u.s._11) + (src1->u.s._22 * src2->u.s._12) + (src1->u.s._32 * src2->u.s._13) + (src1->u.s._42 * src2->u.s._14);
2717 temp.u.s._22 = (src1->u.s._12 * src2->u.s._21) + (src1->u.s._22 * src2->u.s._22) + (src1->u.s._32 * src2->u.s._23) + (src1->u.s._42 * src2->u.s._24);
2718 temp.u.s._32 = (src1->u.s._12 * src2->u.s._31) + (src1->u.s._22 * src2->u.s._32) + (src1->u.s._32 * src2->u.s._33) + (src1->u.s._42 * src2->u.s._34);
2719 temp.u.s._42 = (src1->u.s._12 * src2->u.s._41) + (src1->u.s._22 * src2->u.s._42) + (src1->u.s._32 * src2->u.s._43) + (src1->u.s._42 * src2->u.s._44);
2721 temp.u.s._13 = (src1->u.s._13 * src2->u.s._11) + (src1->u.s._23 * src2->u.s._12) + (src1->u.s._33 * src2->u.s._13) + (src1->u.s._43 * src2->u.s._14);
2722 temp.u.s._23 = (src1->u.s._13 * src2->u.s._21) + (src1->u.s._23 * src2->u.s._22) + (src1->u.s._33 * src2->u.s._23) + (src1->u.s._43 * src2->u.s._24);
2723 temp.u.s._33 = (src1->u.s._13 * src2->u.s._31) + (src1->u.s._23 * src2->u.s._32) + (src1->u.s._33 * src2->u.s._33) + (src1->u.s._43 * src2->u.s._34);
2724 temp.u.s._43 = (src1->u.s._13 * src2->u.s._41) + (src1->u.s._23 * src2->u.s._42) + (src1->u.s._33 * src2->u.s._43) + (src1->u.s._43 * src2->u.s._44);
2726 temp.u.s._14 = (src1->u.s._14 * src2->u.s._11) + (src1->u.s._24 * src2->u.s._12) + (src1->u.s._34 * src2->u.s._13) + (src1->u.s._44 * src2->u.s._14);
2727 temp.u.s._24 = (src1->u.s._14 * src2->u.s._21) + (src1->u.s._24 * src2->u.s._22) + (src1->u.s._34 * src2->u.s._23) + (src1->u.s._44 * src2->u.s._24);
2728 temp.u.s._34 = (src1->u.s._14 * src2->u.s._31) + (src1->u.s._24 * src2->u.s._32) + (src1->u.s._34 * src2->u.s._33) + (src1->u.s._44 * src2->u.s._34);
2729 temp.u.s._44 = (src1->u.s._14 * src2->u.s._41) + (src1->u.s._24 * src2->u.s._42) + (src1->u.s._34 * src2->u.s._43) + (src1->u.s._44 * src2->u.s._44);
2731 /* And copy the new matrix in the good storage.. */
2732 memcpy(dest, &temp, 16 * sizeof(float));
2735 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2736 DWORD size = 0;
2737 int i;
2738 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2740 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2741 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2742 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2743 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2744 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2745 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2746 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2747 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2748 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2749 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2750 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2751 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2752 default: ERR("Unexpected position mask\n");
2754 for (i = 0; i < numTextures; i++) {
2755 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2758 return size;
2761 /***********************************************************************
2762 * CalculateTexRect
2764 * Calculates the dimensions of the opengl texture used for blits.
2765 * Handled oversized opengl textures and updates the source rectangle
2766 * accordingly
2768 * Params:
2769 * This: Surface to operate on
2770 * Rect: Requested rectangle
2772 * Returns:
2773 * TRUE if the texture part can be loaded,
2774 * FALSE otherwise
2776 *********************************************************************/
2777 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
2779 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
2780 int x1 = Rect->left, x2 = Rect->right;
2781 int y1 = Rect->top, y2 = Rect->bottom;
2782 GLint maxSize = GL_LIMITS(texture_size);
2784 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2785 Rect->left, Rect->top, Rect->right, Rect->bottom);
2787 /* The sizes might be reversed */
2788 if(Rect->left > Rect->right) {
2789 x1 = Rect->right;
2790 x2 = Rect->left;
2792 if(Rect->top > Rect->bottom) {
2793 y1 = Rect->bottom;
2794 y2 = Rect->top;
2797 /* No oversized texture? This is easy */
2798 if(!(This->Flags & SFLAG_OVERSIZE)) {
2799 /* Which rect from the texture do I need? */
2800 if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
2801 glTexCoord[0] = (float) Rect->left;
2802 glTexCoord[2] = (float) Rect->top;
2803 glTexCoord[1] = (float) Rect->right;
2804 glTexCoord[3] = (float) Rect->bottom;
2805 } else {
2806 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2807 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2808 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2809 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2812 return TRUE;
2813 } else {
2814 /* Check if we can succeed at all */
2815 if( (x2 - x1) > maxSize ||
2816 (y2 - y1) > maxSize ) {
2817 TRACE("Requested rectangle is too large for gl\n");
2818 return FALSE;
2821 /* A part of the texture has to be picked. First, check if
2822 * some texture part is loaded already, if yes try to re-use it.
2823 * If the texture is dirty, or the part can't be used,
2824 * re-position the part to load
2826 if(This->Flags & SFLAG_INTEXTURE) {
2827 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2828 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2829 /* Ok, the rectangle is ok, re-use it */
2830 TRACE("Using existing gl Texture\n");
2831 } else {
2832 /* Rectangle is not ok, dirtify the texture to reload it */
2833 TRACE("Dirtifying texture to force reload\n");
2834 This->Flags &= ~SFLAG_INTEXTURE;
2838 /* Now if we are dirty(no else if!) */
2839 if(!(This->Flags & SFLAG_INTEXTURE)) {
2840 /* Set the new rectangle. Use the following strategy:
2841 * 1) Use as big textures as possible.
2842 * 2) Place the texture part in the way that the requested
2843 * part is in the middle of the texture(well, almost)
2844 * 3) If the texture is moved over the edges of the
2845 * surface, replace it nicely
2846 * 4) If the coord is not limiting the texture size,
2847 * use the whole size
2849 if((This->pow2Width) > maxSize) {
2850 This->glRect.left = x1 - maxSize / 2;
2851 if(This->glRect.left < 0) {
2852 This->glRect.left = 0;
2854 This->glRect.right = This->glRect.left + maxSize;
2855 if(This->glRect.right > This->currentDesc.Width) {
2856 This->glRect.right = This->currentDesc.Width;
2857 This->glRect.left = This->glRect.right - maxSize;
2859 } else {
2860 This->glRect.left = 0;
2861 This->glRect.right = This->pow2Width;
2864 if(This->pow2Height > maxSize) {
2865 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2866 if(This->glRect.top < 0) This->glRect.top = 0;
2867 This->glRect.bottom = This->glRect.left + maxSize;
2868 if(This->glRect.bottom > This->currentDesc.Height) {
2869 This->glRect.bottom = This->currentDesc.Height;
2870 This->glRect.top = This->glRect.bottom - maxSize;
2872 } else {
2873 This->glRect.top = 0;
2874 This->glRect.bottom = This->pow2Height;
2876 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2877 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2880 /* Re-calculate the rect to draw */
2881 Rect->left -= This->glRect.left;
2882 Rect->right -= This->glRect.left;
2883 Rect->top -= This->glRect.top;
2884 Rect->bottom -= This->glRect.top;
2886 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2887 * or the pow2Width / pow2Height of the surface.
2889 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
2890 * as regular GL_TEXTURE_2D.
2892 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2893 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2894 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2895 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2897 return TRUE;
2899 #undef GLINFO_LOCATION
2901 /* Hash table functions */
2903 hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
2905 hash_table_t *table;
2906 unsigned int initial_size = 8;
2908 table = HeapAlloc(GetProcessHeap(), 0, sizeof(hash_table_t) + (initial_size * sizeof(struct list)));
2909 if (!table)
2911 ERR("Failed to allocate table, returning NULL.\n");
2912 return NULL;
2915 table->hash_function = hash_function;
2916 table->compare_function = compare_function;
2918 table->grow_size = initial_size - (initial_size >> 2);
2919 table->shrink_size = 0;
2921 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
2922 if (!table->buckets)
2924 ERR("Failed to allocate table buckets, returning NULL.\n");
2925 HeapFree(GetProcessHeap(), 0, table);
2926 return NULL;
2928 table->bucket_count = initial_size;
2930 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(hash_table_entry_t));
2931 if (!table->entries)
2933 ERR("Failed to allocate table entries, returning NULL.\n");
2934 HeapFree(GetProcessHeap(), 0, table->buckets);
2935 HeapFree(GetProcessHeap(), 0, table);
2936 return NULL;
2938 table->entry_count = 0;
2940 list_init(&table->free_entries);
2941 table->count = 0;
2943 return table;
2946 void hash_table_destroy(hash_table_t *table)
2948 unsigned int i = 0;
2950 for (i = 0; i < table->entry_count; ++i)
2952 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
2955 HeapFree(GetProcessHeap(), 0, table->entries);
2956 HeapFree(GetProcessHeap(), 0, table->buckets);
2957 HeapFree(GetProcessHeap(), 0, table);
2960 static inline hash_table_entry_t *hash_table_get_by_idx(hash_table_t *table, void *key, unsigned int idx)
2962 hash_table_entry_t *entry;
2964 if (table->buckets[idx].next)
2965 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), hash_table_entry_t, entry)
2966 if (table->compare_function(entry->key, key)) return entry;
2968 return NULL;
2971 static BOOL hash_table_resize(hash_table_t *table, unsigned int new_bucket_count)
2973 unsigned int new_entry_count = 0;
2974 hash_table_entry_t *new_entries;
2975 struct list *new_buckets;
2976 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
2977 unsigned int i;
2979 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
2980 if (!new_buckets)
2982 ERR("Failed to allocate new buckets, returning FALSE.\n");
2983 return FALSE;
2986 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(hash_table_entry_t));
2987 if (!new_entries)
2989 ERR("Failed to allocate new entries, returning FALSE.\n");
2990 HeapFree(GetProcessHeap(), 0, new_buckets);
2991 return FALSE;
2994 for (i = 0; i < table->bucket_count; ++i)
2996 if (table->buckets[i].next)
2998 hash_table_entry_t *entry, *entry2;
3000 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], hash_table_entry_t, entry)
3002 int j;
3003 hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
3004 *new_entry = *entry;
3006 j = new_entry->hash & (new_bucket_count - 1);
3008 if (!new_buckets[j].next) list_init(&new_buckets[j]);
3009 list_add_head(&new_buckets[j], &new_entry->entry);
3014 HeapFree(GetProcessHeap(), 0, table->buckets);
3015 table->buckets = new_buckets;
3017 HeapFree(GetProcessHeap(), 0, table->entries);
3018 table->entries = new_entries;
3020 table->entry_count = new_entry_count;
3021 list_init(&table->free_entries);
3023 table->bucket_count = new_bucket_count;
3024 table->grow_size = grow_size;
3025 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
3027 return TRUE;
3030 void hash_table_put(hash_table_t *table, void *key, void *value)
3032 unsigned int idx;
3033 unsigned int hash;
3034 hash_table_entry_t *entry;
3036 hash = table->hash_function(key);
3037 idx = hash & (table->bucket_count - 1);
3038 entry = hash_table_get_by_idx(table, key, idx);
3040 if (entry)
3042 HeapFree(GetProcessHeap(), 0, key);
3043 entry->value = value;
3045 if (!value)
3047 HeapFree(GetProcessHeap(), 0, entry->key);
3048 entry->key = NULL;
3050 /* Remove the entry */
3051 list_remove(&entry->entry);
3052 list_add_head(&table->free_entries, &entry->entry);
3054 --table->count;
3056 /* Shrink if necessary */
3057 if (table->count < table->shrink_size) {
3058 if (!hash_table_resize(table, table->bucket_count >> 1))
3060 ERR("Failed to shrink the table...\n");
3065 return;
3068 if (!value) return;
3070 /* Grow if necessary */
3071 if (table->count >= table->grow_size)
3073 if (!hash_table_resize(table, table->bucket_count << 1))
3075 ERR("Failed to grow the table, returning.\n");
3076 return;
3079 idx = hash & (table->bucket_count - 1);
3082 /* Find an entry to insert */
3083 if (!list_empty(&table->free_entries))
3085 struct list *elem = list_head(&table->free_entries);
3087 list_remove(elem);
3088 entry = LIST_ENTRY(elem, hash_table_entry_t, entry);
3089 } else {
3090 entry = table->entries + (table->entry_count++);
3093 /* Insert the entry */
3094 entry->key = key;
3095 entry->value = value;
3096 entry->hash = hash;
3097 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
3098 list_add_head(&table->buckets[idx], &entry->entry);
3100 ++table->count;
3103 void hash_table_remove(hash_table_t *table, void *key)
3105 hash_table_put(table, key, NULL);
3108 void *hash_table_get(hash_table_t *table, void *key)
3110 unsigned int idx;
3111 hash_table_entry_t *entry;
3113 idx = table->hash_function(key) & (table->bucket_count - 1);
3114 entry = hash_table_get_by_idx(table, key, idx);
3116 return entry ? entry->value : NULL;