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
26 #include "wined3d_private.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
30 /*****************************************************************************
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 },
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 },
52 {WINED3DFMT_CxV8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
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 },
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 },
110 GLint glInternal, glGammaInternal, 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
119 static const GlPixelFormatDescTemplate gl_formats_template[] = {
120 /*{ internal ,srgbInternal ,format ,type }*/
121 {WINED3DFMT_UNKNOWN ,0 ,0 ,0 ,0 },
123 {WINED3DFMT_UYVY ,0 ,0 ,0 ,0 },
124 {WINED3DFMT_YUY2 ,0 ,0 ,0 ,0 },
125 {WINED3DFMT_DXT1 ,GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
126 {WINED3DFMT_DXT2 ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
127 {WINED3DFMT_DXT3 ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
128 {WINED3DFMT_DXT4 ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
129 {WINED3DFMT_DXT5 ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
130 {WINED3DFMT_MULTI2_ARGB8 ,0 ,0 ,0 ,0 },
131 {WINED3DFMT_G8R8_G8B8 ,0 ,0 ,0 ,0 },
132 {WINED3DFMT_R8G8_B8G8 ,0 ,0 ,0 ,0 },
134 {WINED3DFMT_R32F ,GL_RGB32F_ARB ,GL_RGB32F_ARB ,GL_RED ,GL_FLOAT },
135 {WINED3DFMT_G32R32F ,0 ,0 ,0 ,0 },
136 {WINED3DFMT_A32B32G32R32F ,GL_RGBA32F_ARB ,GL_RGBA32F_ARB ,GL_RGBA ,GL_FLOAT },
138 {WINED3DFMT_CxV8U8 ,0 ,0 ,0 ,0 },
140 {WINED3DFMT_R16F ,GL_RGB16F_ARB ,GL_RGB16F_ARB ,GL_RED ,GL_HALF_FLOAT_ARB },
141 {WINED3DFMT_G16R16F ,0 ,0 ,0 ,0 },
142 {WINED3DFMT_A16B16G16R16F ,GL_RGBA16F_ARB ,GL_RGBA16F_ARB ,GL_RGBA ,GL_HALF_FLOAT_ARB },
143 /* Palettized formats */
144 {WINED3DFMT_A8P8, 0 ,0 ,0 ,0 },
145 {WINED3DFMT_P8, GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX ,GL_UNSIGNED_BYTE },
146 /* Standard ARGB formats */
147 {WINED3DFMT_R8G8B8 ,GL_RGB8 ,GL_RGB8 ,GL_BGR ,GL_UNSIGNED_BYTE },
148 {WINED3DFMT_A8R8G8B8 ,GL_RGBA8 ,GL_SRGB8_ALPHA8_EXT ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
149 {WINED3DFMT_X8R8G8B8 ,GL_RGB8 ,GL_SRGB8_EXT ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
150 {WINED3DFMT_R5G6B5 ,GL_RGB5 ,GL_RGB5 ,GL_RGB ,GL_UNSIGNED_SHORT_5_6_5 },
151 {WINED3DFMT_X1R5G5B5 ,GL_RGB5 ,GL_RGB5_A1 ,GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV },
152 {WINED3DFMT_A1R5G5B5 ,GL_RGB5_A1 ,GL_RGB5_A1 ,GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV },
153 {WINED3DFMT_A4R4G4B4 ,GL_RGBA4 ,GL_SRGB8_ALPHA8_EXT ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
154 {WINED3DFMT_R3G3B2 ,GL_R3_G3_B2 ,GL_R3_G3_B2 ,GL_RGB ,GL_UNSIGNED_BYTE_3_3_2 },
155 {WINED3DFMT_A8 ,GL_ALPHA8 ,GL_ALPHA8 ,GL_ALPHA ,GL_UNSIGNED_BYTE },
156 {WINED3DFMT_A8R3G3B2 ,0 ,0 ,0 ,0 },
157 {WINED3DFMT_X4R4G4B4 ,GL_RGB4 ,GL_RGB4 ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
158 {WINED3DFMT_A2B10G10R10 ,GL_RGBA ,GL_RGBA ,GL_RGBA ,GL_UNSIGNED_INT_2_10_10_10_REV },
159 {WINED3DFMT_A8B8G8R8 ,GL_RGBA8 ,GL_RGBA8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
160 {WINED3DFMT_X8B8G8R8 ,GL_RGB8 ,GL_RGB8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
161 {WINED3DFMT_G16R16 ,0 ,0 ,0 ,0 },
162 {WINED3DFMT_A2R10G10B10 ,GL_RGBA ,GL_RGBA ,GL_BGRA ,GL_UNSIGNED_INT_2_10_10_10_REV },
163 {WINED3DFMT_A16B16G16R16 ,GL_RGBA16_EXT ,GL_RGBA16_EXT ,GL_RGBA ,GL_UNSIGNED_SHORT },
165 {WINED3DFMT_L8 ,GL_LUMINANCE8 ,GL_SLUMINANCE8_EXT ,GL_LUMINANCE ,GL_UNSIGNED_BYTE },
166 {WINED3DFMT_A8L8 ,GL_LUMINANCE8_ALPHA8 ,GL_SLUMINANCE8_ALPHA8_EXT ,GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE },
167 {WINED3DFMT_A4L4 ,GL_LUMINANCE4_ALPHA4 ,GL_LUMINANCE4_ALPHA4 ,GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE },
168 /* Bump mapping stuff */
169 {WINED3DFMT_V8U8 ,GL_DSDT8_NV ,GL_DSDT8_NV ,GL_DSDT_NV ,GL_BYTE },
170 {WINED3DFMT_L6V5U5 ,GL_DSDT8_MAG8_NV ,GL_DSDT8_MAG8_NV ,GL_DSDT_MAG_NV ,GL_BYTE },
171 {WINED3DFMT_X8L8V8U8 ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT8_MAG8_INTENSITY8_NV ,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 ,GL_RGBA ,GL_BYTE },
173 {WINED3DFMT_V16U16 ,GL_SIGNED_HILO16_NV ,GL_SIGNED_HILO16_NV ,GL_HILO_NV ,GL_SHORT },
174 {WINED3DFMT_W11V11U10 ,0 ,0 ,0 ,0 },
175 {WINED3DFMT_A2W10V10U10 ,0 ,0 ,0 ,0 },
176 /* Depth stencil formats */
177 {WINED3DFMT_D16_LOCKABLE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT },
178 {WINED3DFMT_D32 ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
179 {WINED3DFMT_D15S1 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT },
180 {WINED3DFMT_D24S8 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
181 {WINED3DFMT_D24X8 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
182 {WINED3DFMT_D24X4S4 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
183 {WINED3DFMT_D16 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT },
184 {WINED3DFMT_L16 ,GL_LUMINANCE16_EXT ,GL_LUMINANCE16_EXT ,GL_LUMINANCE ,GL_UNSIGNED_SHORT },
185 {WINED3DFMT_D32F_LOCKABLE ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT ,GL_FLOAT },
186 {WINED3DFMT_D24FS8 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_FLOAT },
187 /* Is this a vertex buffer? */
188 {WINED3DFMT_VERTEXDATA ,0 ,0 ,0 ,0 },
189 {WINED3DFMT_INDEX16 ,0 ,0 ,0 ,0 },
190 {WINED3DFMT_INDEX32 ,0 ,0 ,0 ,0 },
191 {WINED3DFMT_Q16W16V16U16 ,GL_COLOR_INDEX ,GL_COLOR_INDEX ,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) {
202 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
203 if(formats[i].format == fmt) {
211 #define GLINFO_LOCATION (*gl_info)
212 BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
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
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;
233 /* V8U8 and V16U16 are always tidied up in the pixel shader - blue is set to 1.0.
234 * They can't be switched with other formats, but they can be switched with each other,
235 * except if GL_ATI_envmap_bumpmap is supported. In this case, V8U8 uses the gl native format,
236 * but V16U16 is converted.
238 dst = getFmtIdx(WINED3DFMT_V8U8);
239 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
240 dst = getFmtIdx(WINED3DFMT_V16U16);
241 if(!GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
242 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
244 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V16U16;
247 if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
248 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
251 dst = getFmtIdx(WINED3DFMT_L6V5U5);
252 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_L6V5U5;
253 dst = getFmtIdx(WINED3DFMT_X8L8V8U8);
254 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_X8L8V8U8;
255 dst = getFmtIdx(WINED3DFMT_Q8W8V8U8);
256 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_Q8W8V8U8;
258 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
259 * are converted at surface loading time, but they do not need any modification in
260 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
261 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
267 #undef GLINFO_LOCATION
269 #define GLINFO_LOCATION This->adapter->gl_info
271 const StaticPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, WineD3D_GL_Info *gl_info, const GlPixelFormatDesc **glDesc)
273 int idx = getFmtIdx(fmt);
276 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
277 /* Get the caller a valid pointer */
278 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
282 ERR("OpenGL pixel format information was requested, but no gl info structure passed\n");
285 *glDesc = &gl_info->gl_formats[idx];
287 return &formats[idx];
290 /*****************************************************************************
291 * Trace formatting of useful values
293 const char* debug_d3dformat(WINED3DFORMAT fmt) {
295 #define FMT_TO_STR(fmt) case fmt: return #fmt
296 FMT_TO_STR(WINED3DFMT_UNKNOWN);
297 FMT_TO_STR(WINED3DFMT_R8G8B8);
298 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
299 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
300 FMT_TO_STR(WINED3DFMT_R5G6B5);
301 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
302 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
303 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
304 FMT_TO_STR(WINED3DFMT_R3G3B2);
305 FMT_TO_STR(WINED3DFMT_A8);
306 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
307 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
308 FMT_TO_STR(WINED3DFMT_A2B10G10R10);
309 FMT_TO_STR(WINED3DFMT_A8B8G8R8);
310 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
311 FMT_TO_STR(WINED3DFMT_G16R16);
312 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
313 FMT_TO_STR(WINED3DFMT_A16B16G16R16);
314 FMT_TO_STR(WINED3DFMT_A8P8);
315 FMT_TO_STR(WINED3DFMT_P8);
316 FMT_TO_STR(WINED3DFMT_L8);
317 FMT_TO_STR(WINED3DFMT_A8L8);
318 FMT_TO_STR(WINED3DFMT_A4L4);
319 FMT_TO_STR(WINED3DFMT_V8U8);
320 FMT_TO_STR(WINED3DFMT_L6V5U5);
321 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
322 FMT_TO_STR(WINED3DFMT_Q8W8V8U8);
323 FMT_TO_STR(WINED3DFMT_V16U16);
324 FMT_TO_STR(WINED3DFMT_W11V11U10);
325 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
326 FMT_TO_STR(WINED3DFMT_UYVY);
327 FMT_TO_STR(WINED3DFMT_YUY2);
328 FMT_TO_STR(WINED3DFMT_DXT1);
329 FMT_TO_STR(WINED3DFMT_DXT2);
330 FMT_TO_STR(WINED3DFMT_DXT3);
331 FMT_TO_STR(WINED3DFMT_DXT4);
332 FMT_TO_STR(WINED3DFMT_DXT5);
333 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
334 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
335 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
336 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
337 FMT_TO_STR(WINED3DFMT_D32);
338 FMT_TO_STR(WINED3DFMT_D15S1);
339 FMT_TO_STR(WINED3DFMT_D24S8);
340 FMT_TO_STR(WINED3DFMT_D24X8);
341 FMT_TO_STR(WINED3DFMT_D24X4S4);
342 FMT_TO_STR(WINED3DFMT_D16);
343 FMT_TO_STR(WINED3DFMT_L16);
344 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
345 FMT_TO_STR(WINED3DFMT_D24FS8);
346 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
347 FMT_TO_STR(WINED3DFMT_INDEX16);
348 FMT_TO_STR(WINED3DFMT_INDEX32);
349 FMT_TO_STR(WINED3DFMT_Q16W16V16U16);
350 FMT_TO_STR(WINED3DFMT_R16F);
351 FMT_TO_STR(WINED3DFMT_G16R16F);
352 FMT_TO_STR(WINED3DFMT_A16B16G16R16F);
353 FMT_TO_STR(WINED3DFMT_R32F);
354 FMT_TO_STR(WINED3DFMT_G32R32F);
355 FMT_TO_STR(WINED3DFMT_A32B32G32R32F);
356 FMT_TO_STR(WINED3DFMT_CxV8U8);
361 fourcc[0] = (char)(fmt);
362 fourcc[1] = (char)(fmt >> 8);
363 fourcc[2] = (char)(fmt >> 16);
364 fourcc[3] = (char)(fmt >> 24);
366 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
367 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
369 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
371 return "unrecognized";
375 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
377 #define DEVTYPE_TO_STR(dev) case dev: return #dev
378 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
379 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
380 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
381 #undef DEVTYPE_TO_STR
383 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
384 return "unrecognized";
388 const char* debug_d3dusage(DWORD usage) {
389 switch (usage & WINED3DUSAGE_MASK) {
390 #define WINED3DUSAGE_TO_STR(u) case u: return #u
391 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
392 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
393 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
394 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
395 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
396 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
397 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
398 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
399 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
400 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
401 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
402 #undef WINED3DUSAGE_TO_STR
403 case 0: return "none";
405 FIXME("Unrecognized %u Usage!\n", usage);
406 return "unrecognized";
410 const char* debug_d3dusagequery(DWORD usagequery) {
411 switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
412 #define WINED3DUSAGEQUERY_TO_STR(u) case u: return #u
413 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
414 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
415 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
416 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
417 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
418 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
419 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
420 #undef WINED3DUSAGEQUERY_TO_STR
421 case 0: return "none";
423 FIXME("Unrecognized %u Usage Query!\n", usagequery);
424 return "unrecognized";
428 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
430 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
431 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
432 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
433 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
434 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
435 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
436 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
437 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
438 #undef WINED3DDECLMETHOD_TO_STR
440 FIXME("Unrecognized %u declaration method!\n", method);
441 return "unrecognized";
445 const char* debug_d3ddecltype(WINED3DDECLTYPE type) {
447 #define WINED3DDECLTYPE_TO_STR(u) case u: return #u
448 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT1);
449 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT2);
450 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT3);
451 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT4);
452 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_D3DCOLOR);
453 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4);
454 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2);
455 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4);
456 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4N);
457 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2N);
458 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4N);
459 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT2N);
460 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT4N);
461 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UDEC3);
462 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_DEC3N);
463 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_2);
464 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_4);
465 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UNUSED);
466 #undef WINED3DDECLTYPE_TO_STR
468 FIXME("Unrecognized %u declaration type!\n", type);
469 return "unrecognized";
473 const char* debug_d3ddeclusage(BYTE usage) {
475 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
476 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
477 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
478 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
479 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
480 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
481 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
482 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
483 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
484 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
485 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
486 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
487 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
488 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
489 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
490 #undef WINED3DDECLUSAGE_TO_STR
492 FIXME("Unrecognized %u declaration usage!\n", usage);
493 return "unrecognized";
497 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
499 #define RES_TO_STR(res) case res: return #res;
500 RES_TO_STR(WINED3DRTYPE_SURFACE);
501 RES_TO_STR(WINED3DRTYPE_VOLUME);
502 RES_TO_STR(WINED3DRTYPE_TEXTURE);
503 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
504 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
505 RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER);
506 RES_TO_STR(WINED3DRTYPE_INDEXBUFFER);
509 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
510 return "unrecognized";
514 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
515 switch (PrimitiveType) {
516 #define PRIM_TO_STR(prim) case prim: return #prim;
517 PRIM_TO_STR(WINED3DPT_POINTLIST);
518 PRIM_TO_STR(WINED3DPT_LINELIST);
519 PRIM_TO_STR(WINED3DPT_LINESTRIP);
520 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
521 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
522 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
525 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
526 return "unrecognized";
530 const char* debug_d3drenderstate(DWORD state) {
532 #define D3DSTATE_TO_STR(u) case u: return #u
533 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
534 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
535 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
536 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
537 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
538 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
539 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
540 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
541 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
542 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
543 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
544 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
545 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
546 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
547 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
548 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
549 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
550 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
551 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
552 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
553 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
554 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
555 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
556 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
557 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
558 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
559 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
560 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
561 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
562 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
563 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
564 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
565 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
566 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
567 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
568 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
569 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
570 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
571 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
572 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
573 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
574 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
575 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
576 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
577 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
578 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
579 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
580 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
581 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
582 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
583 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
584 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
585 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
586 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
587 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
588 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
589 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
590 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
591 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
592 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
593 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
594 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
595 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
596 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
597 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
598 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
599 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
600 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
601 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
602 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
603 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
604 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
605 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
606 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
607 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
608 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
609 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
610 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
611 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
612 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
613 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
614 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
615 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
616 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
617 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
618 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
619 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
620 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
621 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
622 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
623 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
624 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
625 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
626 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
627 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
628 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
629 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
630 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
631 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
632 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
633 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
634 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
635 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
636 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
637 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
638 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
639 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
640 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
641 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
642 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
643 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
644 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
645 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
646 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
647 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
648 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
649 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
650 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
651 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
652 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
653 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
654 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
655 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
656 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
657 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
658 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
659 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
660 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
661 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
662 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
663 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
664 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
665 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
666 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
667 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
668 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
669 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
670 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
671 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
672 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
673 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
674 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
675 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
676 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
677 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
678 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
679 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
680 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
681 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
682 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
683 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
684 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
685 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
686 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
687 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
688 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
689 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
690 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
691 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
692 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
693 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
694 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
695 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
696 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
697 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
698 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
699 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
700 #undef D3DSTATE_TO_STR
702 FIXME("Unrecognized %u render state!\n", state);
703 return "unrecognized";
707 const char* debug_d3dsamplerstate(DWORD state) {
709 #define D3DSTATE_TO_STR(u) case u: return #u
710 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
711 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
712 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
713 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
714 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
715 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
716 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
717 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
718 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
719 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
720 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
721 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
722 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
723 #undef D3DSTATE_TO_STR
725 FIXME("Unrecognized %u sampler state!\n", state);
726 return "unrecognized";
730 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
731 switch (filter_type) {
732 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
733 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
734 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
735 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
736 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
737 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
738 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
739 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
740 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
741 #undef D3DTEXTUREFILTERTYPE_TO_STR
743 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
744 return "unrecognized";
748 const char* debug_d3dtexturestate(DWORD state) {
750 #define D3DSTATE_TO_STR(u) case u: return #u
751 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
752 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
753 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
754 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
755 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
756 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
757 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
758 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
759 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
760 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
761 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
762 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
763 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
764 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
765 D3DSTATE_TO_STR(WINED3DTSS_ADDRESSW );
766 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
767 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
768 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
769 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
770 #undef D3DSTATE_TO_STR
772 /* Note WINED3DTSS are not consecutive, so skip these */
775 FIXME("Unrecognized %u texture state!\n", state);
776 return "unrecognized";
780 static const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
782 #define D3DTOP_TO_STR(u) case u: return #u
783 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
784 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
785 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
786 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
787 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
788 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
789 D3DTOP_TO_STR(WINED3DTOP_ADD);
790 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
791 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
792 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
793 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
794 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
795 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
796 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
797 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
798 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
799 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
800 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
801 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
802 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
803 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
804 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
805 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
806 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
807 D3DTOP_TO_STR(WINED3DTOP_LERP);
810 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
811 return "unrecognized";
815 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
817 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
818 TSTYPE_TO_STR(WINED3DTS_VIEW);
819 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
820 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
821 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
822 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
823 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
824 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
825 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
826 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
827 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
828 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
831 if (tstype > 256 && tstype < 512) {
832 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
833 return ("WINED3DTS_WORLDMATRIX > 0");
835 FIXME("Unrecognized %u WINED3DTS\n", tstype);
836 return "unrecognized";
840 const char* debug_d3dpool(WINED3DPOOL Pool) {
842 #define POOL_TO_STR(p) case p: return #p;
843 POOL_TO_STR(WINED3DPOOL_DEFAULT);
844 POOL_TO_STR(WINED3DPOOL_MANAGED);
845 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
846 POOL_TO_STR(WINED3DPOOL_SCRATCH);
849 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
850 return "unrecognized";
854 const char *debug_fbostatus(GLenum status) {
856 #define FBOSTATUS_TO_STR(u) case u: return #u
857 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
858 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
859 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
860 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
861 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
862 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
863 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
864 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
865 #undef FBOSTATUS_TO_STR
867 FIXME("Unrecognied FBO status 0x%08x\n", status);
868 return "unrecognized";
872 const char *debug_glerror(GLenum error) {
874 #define GLERROR_TO_STR(u) case u: return #u
875 GLERROR_TO_STR(GL_NO_ERROR);
876 GLERROR_TO_STR(GL_INVALID_ENUM);
877 GLERROR_TO_STR(GL_INVALID_VALUE);
878 GLERROR_TO_STR(GL_INVALID_OPERATION);
879 GLERROR_TO_STR(GL_STACK_OVERFLOW);
880 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
881 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
882 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
883 #undef GLERROR_TO_STR
885 FIXME("Unrecognied GL error 0x%08x\n", error);
886 return "unrecognized";
890 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
892 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
893 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
894 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
895 default: return "unrecognized";
899 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
901 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
902 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
903 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
904 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
905 default: return "unrecognized";
909 /*****************************************************************************
910 * Useful functions mapping GL <-> D3D values
912 GLenum StencilOp(DWORD op) {
914 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
915 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
916 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
917 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
918 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
919 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
920 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
921 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
923 FIXME("Unrecognized stencil op %d\n", op);
928 GLenum CompareFunc(DWORD func) {
929 switch ((WINED3DCMPFUNC)func) {
930 case WINED3DCMP_NEVER : return GL_NEVER;
931 case WINED3DCMP_LESS : return GL_LESS;
932 case WINED3DCMP_EQUAL : return GL_EQUAL;
933 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
934 case WINED3DCMP_GREATER : return GL_GREATER;
935 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
936 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
937 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
939 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
944 static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) {
946 case WINED3DTA_DIFFUSE:
947 return GL_PRIMARY_COLOR_NV;
949 case WINED3DTA_CURRENT:
950 if (stage) return GL_SPARE0_NV;
951 else return GL_PRIMARY_COLOR_NV;
953 case WINED3DTA_TEXTURE:
954 if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx;
955 else return GL_PRIMARY_COLOR_NV;
957 case WINED3DTA_TFACTOR:
958 return GL_CONSTANT_COLOR0_NV;
960 case WINED3DTA_SPECULAR:
961 return GL_SECONDARY_COLOR_NV;
964 /* TODO: Support WINED3DTSS_RESULTARG */
965 FIXME("WINED3DTA_TEMP, not properly supported.\n");
968 case WINED3DTA_CONSTANT:
969 /* TODO: Support per stage constants (WINED3DTSS_CONSTANT, NV_register_combiners2) */
970 FIXME("WINED3DTA_CONSTANT, not properly supported.\n");
971 return GL_CONSTANT_COLOR1_NV;
974 FIXME("Unrecognized texture arg %#x\n", d3dta);
979 static GLenum invert_mapping(GLenum mapping) {
980 if (mapping == GL_UNSIGNED_INVERT_NV) return GL_SIGNED_IDENTITY_NV;
981 else if (mapping == GL_SIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV;
983 FIXME("Unhandled mapping %#x\n", mapping);
987 static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) {
988 /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should
990 if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV;
991 else *mapping = GL_SIGNED_IDENTITY_NV;
993 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input
994 * should be used for all input components. */
995 if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA;
996 else *component_usage = GL_RGB;
998 *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx);
1004 GLenum component_usage[3];
1007 static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1008 if (op == WINED3DTOP_DISABLE) return FALSE;
1009 if (This->stateBlock->textures[stage]) return FALSE;
1011 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1012 && op != WINED3DTOP_SELECTARG2) return TRUE;
1013 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1014 && op != WINED3DTOP_SELECTARG1) return TRUE;
1015 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1016 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1021 void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx) {
1022 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface;
1023 tex_op_args tex_op_args = {{0}, {0}, {0}};
1024 GLenum portion = is_alpha ? GL_ALPHA : GL_RGB;
1025 GLenum target = GL_COMBINER0_NV + stage;
1027 TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1028 stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx);
1030 /* If a texture stage references an invalid texture unit the stage just
1031 * passes through the result from the previous stage */
1032 if (is_invalid_op(This, stage, op, arg1, arg2, arg3)) {
1033 arg1 = WINED3DTA_CURRENT;
1034 op = WINED3DTOP_SELECTARG1;
1037 get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0],
1038 &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx);
1039 get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1],
1040 &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx);
1041 get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2],
1042 &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx);
1045 /* This is called by a state handler which has the gl lock held and a context for the thread */
1048 case WINED3DTOP_DISABLE:
1049 /* Only for alpha */
1050 if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n");
1051 /* Input, prev_alpha*1 */
1052 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1053 GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
1054 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1055 GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
1058 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1059 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1062 case WINED3DTOP_SELECTARG1:
1063 case WINED3DTOP_SELECTARG2:
1065 if (op == WINED3DTOP_SELECTARG1) {
1066 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1067 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1069 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1070 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1072 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1073 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1076 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1077 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1080 case WINED3DTOP_MODULATE:
1081 case WINED3DTOP_MODULATE2X:
1082 case WINED3DTOP_MODULATE4X:
1083 /* Input, arg1*arg2 */
1084 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1085 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1086 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1087 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1090 if (op == WINED3DTOP_MODULATE) {
1091 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1092 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1093 } else if (op == WINED3DTOP_MODULATE2X) {
1094 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1095 GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1096 } else if (op == WINED3DTOP_MODULATE4X) {
1097 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1098 GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1102 case WINED3DTOP_ADD:
1103 case WINED3DTOP_ADDSIGNED:
1104 case WINED3DTOP_ADDSIGNED2X:
1105 /* Input, arg1*1+arg2*1 */
1106 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1107 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1108 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1109 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1110 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1111 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1112 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1113 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1116 if (op == WINED3DTOP_ADD) {
1117 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1118 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1119 } else if (op == WINED3DTOP_ADDSIGNED) {
1120 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1121 GL_SPARE0_NV, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
1122 } else if (op == WINED3DTOP_ADDSIGNED2X) {
1123 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1124 GL_SPARE0_NV, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
1128 case WINED3DTOP_SUBTRACT:
1129 /* Input, arg1*1+-arg2*1 */
1130 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1131 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1132 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1133 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1134 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1135 tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1]));
1136 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1137 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1140 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1141 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1144 case WINED3DTOP_ADDSMOOTH:
1145 /* Input, arg1*1+(1-arg1)*arg2 */
1146 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1147 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1148 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1149 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1150 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1151 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1152 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1153 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1156 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1157 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1160 case WINED3DTOP_BLENDDIFFUSEALPHA:
1161 case WINED3DTOP_BLENDTEXTUREALPHA:
1162 case WINED3DTOP_BLENDFACTORALPHA:
1163 case WINED3DTOP_BLENDTEXTUREALPHAPM:
1164 case WINED3DTOP_BLENDCURRENTALPHA:
1166 GLenum alpha_src = GL_PRIMARY_COLOR_NV;
1167 if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx);
1168 else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
1169 else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx);
1170 else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
1171 else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx);
1172 else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op));
1174 /* Input, arg1*alpha_src+arg2*(1-alpha_src) */
1175 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1176 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1177 if (op == WINED3DTOP_BLENDTEXTUREALPHAPM)
1179 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1180 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1182 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1183 alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
1185 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1186 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1187 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1188 alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
1191 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1192 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1196 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1197 /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */
1198 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n");
1199 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1200 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1201 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1202 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1203 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1204 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1205 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1206 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1209 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1210 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1213 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1214 /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */
1215 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n");
1216 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1217 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1218 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1219 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1220 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1221 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1222 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1223 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1226 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1227 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1230 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1231 /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */
1232 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n");
1233 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1234 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA));
1235 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1236 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1237 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1238 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1239 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1240 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1243 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1244 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1247 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1248 /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */
1249 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n");
1250 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1251 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1252 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1253 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1254 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1255 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1256 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1257 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1260 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1261 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1264 case WINED3DTOP_DOTPRODUCT3:
1265 /* Input, arg1 . arg2 */
1266 /* FIXME: DX7 uses a different calculation? */
1267 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1268 tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0]));
1269 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1270 tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1]));
1273 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1274 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE));
1277 case WINED3DTOP_MULTIPLYADD:
1278 /* Input, arg1*1+arg2*arg3 */
1279 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1280 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1281 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1282 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1283 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1284 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1285 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1286 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1289 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1290 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1293 case WINED3DTOP_LERP:
1294 /* Input, arg1*arg2+(1-arg1)*arg3 */
1295 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1296 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1297 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1298 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1299 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1300 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1301 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1302 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1305 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1306 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1309 case WINED3DTOP_BUMPENVMAPLUMINANCE:
1310 case WINED3DTOP_BUMPENVMAP:
1311 if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
1312 /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to
1313 * perform bump mapping and source from the current stage. Pretty much a SELECTARG2.
1314 * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1
1315 * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the next stage
1317 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1318 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1319 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1320 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1321 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1322 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1327 FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1328 stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
1331 checkGLcall("set_tex_op_nvrc()\n");
1335 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
1336 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
1337 * input should be used for all input components. The WINED3DTA_COMPLEMENT
1338 * flag specifies the complement of the input should be used. */
1339 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
1340 BOOL complement = arg & WINED3DTA_COMPLEMENT;
1342 /* Calculate the operand */
1344 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
1345 else *operand = GL_ONE_MINUS_SRC_COLOR;
1347 if (from_alpha) *operand = GL_SRC_ALPHA;
1348 else *operand = GL_SRC_COLOR;
1351 /* Calculate the source */
1352 switch (arg & WINED3DTA_SELECTMASK) {
1353 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
1354 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
1355 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
1356 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
1357 case WINED3DTA_SPECULAR:
1359 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
1360 * 'Secondary color' and isn't supported until base GL supports it
1361 * There is no concept of temp registers as far as I can tell
1363 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
1364 *source = GL_TEXTURE;
1367 FIXME("Unrecognized texture arg %#x\n", arg);
1368 *source = GL_TEXTURE;
1373 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
1374 #if defined (GL_VERSION_1_3)
1375 # define useext(A) A
1376 # define combine_ext 1
1377 #elif defined (GL_EXT_texture_env_combine)
1378 # define useext(A) A##_EXT
1379 # define combine_ext 1
1380 #elif defined (GL_ARB_texture_env_combine)
1381 # define useext(A) A##_ARB
1382 # define combine_ext 1
1387 #if !defined(combine_ext)
1388 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1390 FIXME("Requires opengl combine extensions to work\n");
1394 /* Setup the texture operations texture stage states */
1395 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1397 GLenum src1, src2, src3;
1398 GLenum opr1, opr2, opr3;
1400 GLenum src0_target, src1_target, src2_target;
1401 GLenum opr0_target, opr1_target, opr2_target;
1403 GLenum opr=0, invopr, src3_target, opr3_target;
1404 BOOL Handled = FALSE;
1405 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
1407 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
1409 /* This is called by a state handler which has the gl lock held and a context for the thread */
1411 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
1412 the form (a1 <operation> a2). However, some of the more complex operations
1413 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
1414 in a third parameter called a0. Therefore these are operations of the form
1415 a0 <operation> a1 <operation> a2, ie the new parameter goes to the front.
1417 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
1418 functions below, expect their syntax to differ slightly to those listed in the
1419 manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
1420 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
1423 comb_target = useext(GL_COMBINE_ALPHA);
1424 src0_target = useext(GL_SOURCE0_ALPHA);
1425 src1_target = useext(GL_SOURCE1_ALPHA);
1426 src2_target = useext(GL_SOURCE2_ALPHA);
1427 opr0_target = useext(GL_OPERAND0_ALPHA);
1428 opr1_target = useext(GL_OPERAND1_ALPHA);
1429 opr2_target = useext(GL_OPERAND2_ALPHA);
1430 scal_target = GL_ALPHA_SCALE;
1433 comb_target = useext(GL_COMBINE_RGB);
1434 src0_target = useext(GL_SOURCE0_RGB);
1435 src1_target = useext(GL_SOURCE1_RGB);
1436 src2_target = useext(GL_SOURCE2_RGB);
1437 opr0_target = useext(GL_OPERAND0_RGB);
1438 opr1_target = useext(GL_OPERAND1_RGB);
1439 opr2_target = useext(GL_OPERAND2_RGB);
1440 scal_target = useext(GL_RGB_SCALE);
1443 /* If a texture stage references an invalid texture unit the stage just
1444 * passes through the result from the previous stage */
1445 if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) {
1446 arg1 = WINED3DTA_CURRENT;
1447 op = WINED3DTOP_SELECTARG1;
1450 /* From MSDN (WINED3DTSS_ALPHAARG1) :
1451 The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage,
1452 then the default argument is WINED3DTA_DIFFUSE.
1453 FIXME? If texture added/removed, may need to reset back as well? */
1454 if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
1455 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
1457 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
1459 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
1460 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
1462 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
1464 Handled = TRUE; /* Assume will be handled */
1466 /* Other texture operations require special extensions: */
1467 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1470 invopr = GL_ONE_MINUS_SRC_ALPHA;
1471 src3_target = GL_SOURCE3_ALPHA_NV;
1472 opr3_target = GL_OPERAND3_ALPHA_NV;
1475 invopr = GL_ONE_MINUS_SRC_COLOR;
1476 src3_target = GL_SOURCE3_RGB_NV;
1477 opr3_target = GL_OPERAND3_RGB_NV;
1480 case WINED3DTOP_DISABLE: /* Only for alpha */
1481 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1482 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1483 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1484 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1485 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1486 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1487 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1488 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1489 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1490 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1491 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1492 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1493 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1494 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1495 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1496 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1497 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1498 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1500 case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */
1501 case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
1502 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1503 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1504 if (op == WINED3DTOP_SELECTARG1) {
1505 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1506 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1507 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1508 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1510 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1511 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1512 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1513 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1515 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1516 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1517 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1518 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1519 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1520 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1521 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1522 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1523 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1524 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1525 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1526 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1529 case WINED3DTOP_MODULATE:
1530 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1531 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1532 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1533 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1534 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1535 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1536 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1537 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1538 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1539 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1540 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1541 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1542 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1543 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1544 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1545 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1546 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1547 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1548 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1549 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1551 case WINED3DTOP_MODULATE2X:
1552 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1553 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1554 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1555 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1556 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1557 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1558 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1559 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1560 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1561 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1562 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1563 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1564 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1565 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1566 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1567 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1568 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1569 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1570 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1571 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1573 case WINED3DTOP_MODULATE4X:
1574 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1575 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1576 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1577 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1578 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1579 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1580 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1581 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1582 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1583 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1584 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1585 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1586 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1587 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1588 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1589 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1590 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1591 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1592 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
1593 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
1596 case WINED3DTOP_ADD:
1597 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1598 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1599 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1600 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1601 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1602 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1603 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1604 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1605 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1606 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1607 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1608 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1609 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1610 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1611 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1612 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1613 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1614 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1615 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1616 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1619 case WINED3DTOP_ADDSIGNED:
1620 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1621 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1622 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1623 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1624 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1625 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1626 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1627 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1628 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1629 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1630 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1631 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1632 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1633 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1634 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1635 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1636 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1637 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1638 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1639 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1642 case WINED3DTOP_ADDSIGNED2X:
1643 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1644 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1645 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1646 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1647 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1648 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1649 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1650 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1651 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1652 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1653 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1654 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1655 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1656 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1657 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1658 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1659 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1660 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1661 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1662 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1665 case WINED3DTOP_ADDSMOOTH:
1666 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1667 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1668 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1669 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1670 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1671 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1672 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1673 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1674 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1675 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1676 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1677 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1678 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1679 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1680 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1681 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1683 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1684 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1685 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1686 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1688 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1689 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1690 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1691 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1694 case WINED3DTOP_BLENDDIFFUSEALPHA:
1695 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1696 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1697 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1698 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1699 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1700 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1701 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
1702 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
1703 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1704 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1705 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1706 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1707 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1708 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1709 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
1710 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
1711 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1712 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1713 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1714 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1716 case WINED3DTOP_BLENDTEXTUREALPHA:
1717 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1718 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1719 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1720 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1721 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1722 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1723 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
1724 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
1725 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1726 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1727 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1728 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1729 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1730 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1731 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1732 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1733 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1734 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1735 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1736 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1738 case WINED3DTOP_BLENDFACTORALPHA:
1739 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1740 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1741 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1742 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1743 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1744 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1745 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
1746 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
1747 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1748 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1749 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1750 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1751 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1752 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1753 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
1754 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
1755 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1756 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1757 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1758 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1760 case WINED3DTOP_BLENDTEXTUREALPHAPM:
1761 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1762 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1763 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1764 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1765 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1766 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1767 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1768 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1769 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1770 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1771 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1772 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1773 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1774 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1775 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1776 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1777 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1778 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1779 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1780 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1782 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1783 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1784 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1785 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
1786 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1787 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1788 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
1789 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1790 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1791 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1792 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1793 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
1794 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1795 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1796 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
1797 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1798 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1800 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1801 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1803 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1804 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1805 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1806 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1808 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1809 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1810 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1811 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1812 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1813 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1814 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1815 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1816 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1817 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1818 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1819 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1820 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1822 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1823 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1825 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1826 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1827 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1828 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1829 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1830 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1831 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1832 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1834 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1835 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1836 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1837 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1838 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1839 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1840 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1841 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1842 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1843 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1844 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1845 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1846 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1847 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1848 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1849 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1850 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1852 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1853 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1854 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1855 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1857 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1858 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1859 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1860 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1862 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1863 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1864 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1865 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1866 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1868 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1869 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1870 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1871 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1873 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
1874 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
1875 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1876 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1877 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1878 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1879 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1880 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1882 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1883 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1885 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1886 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1887 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1888 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1889 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1890 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1891 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1892 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1894 case WINED3DTOP_MULTIPLYADD:
1895 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1896 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1897 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
1898 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1899 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
1900 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1901 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1902 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1903 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1904 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1905 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1906 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1907 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1908 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1909 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
1910 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
1911 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
1912 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
1913 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1914 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1917 case WINED3DTOP_BUMPENVMAP:
1921 case WINED3DTOP_BUMPENVMAPLUMINANCE:
1922 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
1928 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
1929 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
1933 } /* GL_NV_texture_env_combine4 */
1935 Handled = TRUE; /* Again, assume handled */
1937 case WINED3DTOP_DISABLE: /* Only for alpha */
1938 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1939 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1940 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1941 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
1942 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1943 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
1944 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1945 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1947 case WINED3DTOP_SELECTARG1:
1948 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1949 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1950 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1951 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1952 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1953 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1954 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1955 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1957 case WINED3DTOP_SELECTARG2:
1958 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1959 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1960 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1961 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1962 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1963 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1964 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1965 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1967 case WINED3DTOP_MODULATE:
1968 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1969 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1970 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1971 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1972 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1973 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1974 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1975 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1976 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1977 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1978 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1979 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1981 case WINED3DTOP_MODULATE2X:
1982 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1983 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1984 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1985 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1986 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1987 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1988 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1989 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1990 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1991 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1992 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1993 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1995 case WINED3DTOP_MODULATE4X:
1996 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1997 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1998 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1999 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2000 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2001 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2002 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2003 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2004 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2005 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2006 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2007 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2009 case WINED3DTOP_ADD:
2010 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2011 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2012 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2013 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2014 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2015 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2016 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2017 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2018 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2019 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2020 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2021 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2023 case WINED3DTOP_ADDSIGNED:
2024 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2025 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
2026 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2027 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2028 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2029 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2030 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2031 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2032 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2033 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2034 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2035 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2037 case WINED3DTOP_ADDSIGNED2X:
2038 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2039 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2040 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2041 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2042 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2043 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2044 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2045 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2046 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2047 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2048 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2049 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2051 case WINED3DTOP_SUBTRACT:
2052 if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
2053 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2054 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
2055 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2056 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2057 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2058 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2059 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2060 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2061 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2062 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2063 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2064 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2066 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2070 case WINED3DTOP_BLENDDIFFUSEALPHA:
2071 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2072 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2073 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2074 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2075 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2076 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2077 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2078 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2079 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2080 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2081 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
2082 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2083 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2084 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2085 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2086 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2088 case WINED3DTOP_BLENDTEXTUREALPHA:
2089 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2090 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2091 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2092 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2093 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2094 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2095 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2096 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2097 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2098 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2099 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2100 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2101 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2102 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2103 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2104 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2106 case WINED3DTOP_BLENDFACTORALPHA:
2107 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2108 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2109 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2110 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2111 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2112 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2113 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2114 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2115 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2116 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2117 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
2118 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2119 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2120 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2121 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2122 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2124 case WINED3DTOP_BLENDCURRENTALPHA:
2125 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2126 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2127 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2128 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2129 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2130 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2131 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2132 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2133 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2134 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2135 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
2136 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2137 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2138 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2139 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2140 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2142 case WINED3DTOP_DOTPRODUCT3:
2143 if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
2144 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2145 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2146 } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
2147 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2148 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2150 FIXME("This version of opengl does not support GL_DOT3\n");
2152 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2153 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2154 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2155 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2156 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2157 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2158 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2159 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2160 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2161 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2163 case WINED3DTOP_LERP:
2164 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2165 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2166 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2167 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2168 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2169 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2170 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2171 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2172 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2173 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2174 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2175 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2176 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2177 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2178 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2179 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2181 case WINED3DTOP_ADDSMOOTH:
2182 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2183 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2184 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2185 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2186 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2188 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2189 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2190 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2191 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2193 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2194 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2195 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2196 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2197 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2198 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2199 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2200 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2201 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2202 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2203 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2204 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2208 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2209 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2210 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2211 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2212 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2213 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2214 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2215 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2216 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2217 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2218 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2219 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2220 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2221 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2222 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2223 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2224 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2225 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2229 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2230 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2231 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2232 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2233 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2234 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2236 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2237 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2238 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2239 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2241 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2242 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2243 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2244 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2245 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2246 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2247 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2248 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2249 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2250 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2251 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2252 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2256 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2257 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2258 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2259 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2260 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2261 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2262 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2263 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2264 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2265 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2267 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2268 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2269 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2270 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2272 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2273 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2274 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2275 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2276 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2277 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2278 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2279 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2283 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2284 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2285 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2286 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2287 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2288 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2290 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2291 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2292 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2293 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2295 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2296 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2297 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2298 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2299 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2300 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2301 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2302 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2303 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2304 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2305 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2306 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2310 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2311 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2312 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2313 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2314 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2315 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2317 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2318 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2319 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2320 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2322 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2323 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2324 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2325 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2327 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2328 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2329 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2330 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2332 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2333 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2334 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2335 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2336 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2337 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2338 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2339 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2343 case WINED3DTOP_MULTIPLYADD:
2344 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2345 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2346 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2347 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2348 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2349 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2350 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2351 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2352 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2353 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2354 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2355 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2356 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2357 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2358 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2359 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2360 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2364 case WINED3DTOP_BUMPENVMAPLUMINANCE:
2365 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2366 /* Some apps use BUMPENVMAPLUMINANCE instead of D3DTOP_BUMPENVMAP, although
2367 * they check for the non-luminance cap flag. Well, give them what they asked
2370 WARN("Application uses WINED3DTOP_BUMPENVMAPLUMINANCE\n");
2376 case WINED3DTOP_BUMPENVMAP:
2377 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2378 TRACE("Using ati bumpmap on stage %d, target %d\n", Stage, Stage + 1);
2379 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI);
2380 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI)");
2381 glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1);
2382 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1)");
2383 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2384 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2385 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2386 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2387 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2388 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2389 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2390 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2391 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2392 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2393 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2394 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2398 } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2399 /* Technically texture shader support without register combiners is possible, but not expected to occur
2400 * on real world cards, so for now a fixme should be enough
2402 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
2409 BOOL combineOK = TRUE;
2410 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2414 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP];
2416 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP];
2419 /* Note: If COMBINE4 in effect can't go back to combine! */
2421 case WINED3DTOP_ADDSMOOTH:
2422 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2423 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2424 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2425 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2426 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2427 case WINED3DTOP_MULTIPLYADD:
2428 /* Ignore those implemented in both cases */
2430 case WINED3DTOP_SELECTARG1:
2431 case WINED3DTOP_SELECTARG2:
2436 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
2443 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
2444 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
2450 /* After all the extensions, if still unhandled, report fixme */
2451 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
2452 #undef GLINFO_LOCATION
2456 /* Setup this textures matrix according to the texture flags*/
2457 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype)
2461 glMatrixMode(GL_TEXTURE);
2462 checkGLcall("glMatrixMode(GL_TEXTURE)");
2464 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2466 checkGLcall("glLoadIdentity()");
2470 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2471 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2475 memcpy(mat, smat, 16 * sizeof(float));
2477 if (flags & WINED3DTTFF_PROJECTED) {
2478 switch (flags & ~WINED3DTTFF_PROJECTED) {
2479 case WINED3DTTFF_COUNT2:
2480 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2481 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2483 case WINED3DTTFF_COUNT3:
2484 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2485 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2488 } else if(!calculatedCoords) { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2490 case WINED3DDECLTYPE_FLOAT1:
2491 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2492 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2493 * the input value to the transformation will be 0, so the matrix value is irrelevant
2500 case WINED3DDECLTYPE_FLOAT2:
2501 /* See above, just 3rd and 4th coord
2508 case WINED3DDECLTYPE_FLOAT3: /* Opengl defaults match dx defaults */
2509 case WINED3DDECLTYPE_FLOAT4: /* No defaults apply, all app defined */
2511 /* This is to prevent swaping the matrix lines and put the default 4th coord = 1.0
2512 * into a bad place. The division elimination below will apply to make sure the
2513 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2515 case WINED3DDECLTYPE_UNUSED: /* No texture coords, 0/0/0/1 defaults are passed */
2518 FIXME("Unexpected fixed function texture coord input\n");
2520 switch (flags & ~WINED3DTTFF_PROJECTED) {
2521 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2522 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2523 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2524 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2525 * the 4th coord evaluates to 1.0 to eliminate that.
2527 * If the fixed function pipeline is used, the 4th value remains unused,
2528 * so there is no danger in doing this. With vertex shaders we have a
2529 * problem. Should an app hit that problem, the code here would have to
2530 * check for pixel shaders, and the shader has to undo the default gl divide.
2532 * A more serious problem occurs if the app passes 4 coordinates in, and the
2533 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2534 * or a replacement shader
2536 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2541 checkGLcall("glLoadMatrixf(mat)");
2544 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
2546 /* This small helper function is used to convert a bitmask into the number of masked bits */
2547 unsigned int count_bits(unsigned int mask)
2550 for (count = 0; mask; ++count)
2557 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2558 * The later function requires individual color components. */
2559 BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2561 const StaticPixelFormatDesc *desc;
2563 TRACE("fmt: %s\n", debug_d3dformat(fmt));
2566 case WINED3DFMT_X8R8G8B8:
2567 case WINED3DFMT_R8G8B8:
2568 case WINED3DFMT_A8R8G8B8:
2569 case WINED3DFMT_A2R10G10B10:
2570 case WINED3DFMT_X1R5G5B5:
2571 case WINED3DFMT_A1R5G5B5:
2572 case WINED3DFMT_R5G6B5:
2573 case WINED3DFMT_X4R4G4B4:
2574 case WINED3DFMT_A4R4G4B4:
2575 case WINED3DFMT_R3G3B2:
2576 case WINED3DFMT_A8P8:
2580 ERR("Unsupported format: %s\n", debug_d3dformat(fmt));
2584 desc = getFormatDescEntry(fmt, NULL, NULL);
2587 ERR("Unable to look up format: 0x%x\n", fmt);
2590 *redSize = count_bits(desc->redMask);
2591 *greenSize = count_bits(desc->greenMask);
2592 *blueSize = count_bits(desc->blueMask);
2593 *alphaSize = count_bits(desc->alphaMask);
2594 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2596 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n", *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(fmt));
2600 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2601 BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize)
2603 const StaticPixelFormatDesc *desc;
2605 TRACE("fmt: %s\n", debug_d3dformat(fmt));
2608 case WINED3DFMT_D16_LOCKABLE:
2609 case WINED3DFMT_D16:
2610 case WINED3DFMT_D15S1:
2611 case WINED3DFMT_D24X8:
2612 case WINED3DFMT_D24X4S4:
2613 case WINED3DFMT_D24S8:
2614 case WINED3DFMT_D24FS8:
2615 case WINED3DFMT_D32:
2618 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(fmt));
2622 desc = getFormatDescEntry(fmt, NULL, NULL);
2625 ERR("Unable to look up format: 0x%x\n", fmt);
2628 *depthSize = desc->depthSize;
2629 *stencilSize = desc->stencilSize;
2631 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n", *depthSize, *stencilSize, debug_d3dformat(fmt));
2635 #undef GLINFO_LOCATION
2637 /* DirectDraw stuff */
2638 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2640 case 8: return WINED3DFMT_P8;
2641 case 15: return WINED3DFMT_X1R5G5B5;
2642 case 16: return WINED3DFMT_R5G6B5;
2643 case 24: return WINED3DFMT_R8G8B8;
2644 case 32: return WINED3DFMT_X8R8G8B8;
2645 default: return WINED3DFMT_UNKNOWN;
2649 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2652 /* Now do the multiplication 'by hand'.
2653 I know that all this could be optimised, but this will be done later :-) */
2654 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);
2655 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);
2656 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);
2657 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);
2659 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);
2660 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);
2661 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);
2662 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);
2664 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);
2665 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);
2666 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);
2667 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);
2669 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);
2670 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);
2671 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);
2672 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);
2674 /* And copy the new matrix in the good storage.. */
2675 memcpy(dest, &temp, 16 * sizeof(float));
2678 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2681 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2683 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2684 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2685 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2686 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2687 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2688 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2689 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2690 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2691 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2692 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2693 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2694 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2695 default: ERR("Unexpected position mask\n");
2697 for (i = 0; i < numTextures; i++) {
2698 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2704 /***********************************************************************
2707 * Calculates the dimensions of the opengl texture used for blits.
2708 * Handled oversized opengl textures and updates the source rectangle
2712 * This: Surface to operate on
2713 * Rect: Requested rectangle
2716 * TRUE if the texture part can be loaded,
2719 *********************************************************************/
2720 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
2722 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
2723 int x1 = Rect->left, x2 = Rect->right;
2724 int y1 = Rect->top, y2 = Rect->bottom;
2725 GLint maxSize = GL_LIMITS(texture_size);
2727 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2728 Rect->left, Rect->top, Rect->right, Rect->bottom);
2730 /* The sizes might be reversed */
2731 if(Rect->left > Rect->right) {
2735 if(Rect->top > Rect->bottom) {
2740 /* No oversized texture? This is easy */
2741 if(!(This->Flags & SFLAG_OVERSIZE)) {
2742 /* Which rect from the texture do I need? */
2743 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2744 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2745 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2746 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2750 /* Check if we can succeed at all */
2751 if( (x2 - x1) > maxSize ||
2752 (y2 - y1) > maxSize ) {
2753 TRACE("Requested rectangle is too large for gl\n");
2757 /* A part of the texture has to be picked. First, check if
2758 * some texture part is loaded already, if yes try to re-use it.
2759 * If the texture is dirty, or the part can't be used,
2760 * re-position the part to load
2762 if(This->Flags & SFLAG_INTEXTURE) {
2763 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2764 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2765 /* Ok, the rectangle is ok, re-use it */
2766 TRACE("Using existing gl Texture\n");
2768 /* Rectangle is not ok, dirtify the texture to reload it */
2769 TRACE("Dirtifying texture to force reload\n");
2770 This->Flags &= ~SFLAG_INTEXTURE;
2774 /* Now if we are dirty(no else if!) */
2775 if(!(This->Flags & SFLAG_INTEXTURE)) {
2776 /* Set the new rectangle. Use the following strategy:
2777 * 1) Use as big textures as possible.
2778 * 2) Place the texture part in the way that the requested
2779 * part is in the middle of the texture(well, almost)
2780 * 3) If the texture is moved over the edges of the
2781 * surface, replace it nicely
2782 * 4) If the coord is not limiting the texture size,
2783 * use the whole size
2785 if((This->pow2Width) > maxSize) {
2786 This->glRect.left = x1 - maxSize / 2;
2787 if(This->glRect.left < 0) {
2788 This->glRect.left = 0;
2790 This->glRect.right = This->glRect.left + maxSize;
2791 if(This->glRect.right > This->currentDesc.Width) {
2792 This->glRect.right = This->currentDesc.Width;
2793 This->glRect.left = This->glRect.right - maxSize;
2796 This->glRect.left = 0;
2797 This->glRect.right = This->pow2Width;
2800 if(This->pow2Height > maxSize) {
2801 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2802 if(This->glRect.top < 0) This->glRect.top = 0;
2803 This->glRect.bottom = This->glRect.left + maxSize;
2804 if(This->glRect.bottom > This->currentDesc.Height) {
2805 This->glRect.bottom = This->currentDesc.Height;
2806 This->glRect.top = This->glRect.bottom - maxSize;
2809 This->glRect.top = 0;
2810 This->glRect.bottom = This->pow2Height;
2812 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2813 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2816 /* Re-calculate the rect to draw */
2817 Rect->left -= This->glRect.left;
2818 Rect->right -= This->glRect.left;
2819 Rect->top -= This->glRect.top;
2820 Rect->bottom -= This->glRect.top;
2822 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2823 * or the pow2Width / pow2Height of the surface
2825 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2826 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2827 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2828 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2832 #undef GLINFO_LOCATION
2834 /* Hash table functions */
2836 hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
2838 hash_table_t *table;
2839 unsigned int initial_size = 8;
2841 table = HeapAlloc(GetProcessHeap(), 0, sizeof(hash_table_t) + (initial_size * sizeof(struct list)));
2844 ERR("Failed to allocate table, returning NULL.\n");
2848 table->hash_function = hash_function;
2849 table->compare_function = compare_function;
2851 table->grow_size = initial_size - (initial_size >> 2);
2852 table->shrink_size = 0;
2854 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
2855 if (!table->buckets)
2857 ERR("Failed to allocate table buckets, returning NULL.\n");
2858 HeapFree(GetProcessHeap(), 0, table);
2861 table->bucket_count = initial_size;
2863 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(hash_table_entry_t));
2864 if (!table->entries)
2866 ERR("Failed to allocate table entries, returning NULL.\n");
2867 HeapFree(GetProcessHeap(), 0, table->buckets);
2868 HeapFree(GetProcessHeap(), 0, table);
2871 table->entry_count = 0;
2873 list_init(&table->free_entries);
2879 void hash_table_destroy(hash_table_t *table)
2883 for (i = 0; i < table->entry_count; ++i)
2885 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
2888 HeapFree(GetProcessHeap(), 0, table->entries);
2889 HeapFree(GetProcessHeap(), 0, table->buckets);
2890 HeapFree(GetProcessHeap(), 0, table);
2893 static inline hash_table_entry_t *hash_table_get_by_idx(hash_table_t *table, void *key, unsigned int idx)
2895 hash_table_entry_t *entry;
2897 if (table->buckets[idx].next)
2898 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), hash_table_entry_t, entry)
2899 if (table->compare_function(entry->key, key)) return entry;
2904 static BOOL hash_table_resize(hash_table_t *table, unsigned int new_bucket_count)
2906 unsigned int new_entry_count = 0;
2907 hash_table_entry_t *new_entries;
2908 struct list *new_buckets;
2909 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
2912 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
2915 ERR("Failed to allocate new buckets, returning FALSE.\n");
2919 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(hash_table_entry_t));
2922 ERR("Failed to allocate new entries, returning FALSE.\n");
2923 HeapFree(GetProcessHeap(), 0, new_buckets);
2927 for (i = 0; i < table->bucket_count; ++i)
2929 if (table->buckets[i].next)
2931 hash_table_entry_t *entry, *entry2;
2933 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], hash_table_entry_t, entry)
2936 hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
2937 *new_entry = *entry;
2939 j = new_entry->hash & (new_bucket_count - 1);
2941 if (!new_buckets[j].next) list_init(&new_buckets[j]);
2942 list_add_head(&new_buckets[j], &new_entry->entry);
2947 HeapFree(GetProcessHeap(), 0, table->buckets);
2948 table->buckets = new_buckets;
2950 HeapFree(GetProcessHeap(), 0, table->entries);
2951 table->entries = new_entries;
2953 table->entry_count = new_entry_count;
2954 list_init(&table->free_entries);
2956 table->bucket_count = new_bucket_count;
2957 table->grow_size = grow_size;
2958 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
2963 void hash_table_put(hash_table_t *table, void *key, void *value)
2967 hash_table_entry_t *entry;
2969 hash = table->hash_function(key);
2970 idx = hash & (table->bucket_count - 1);
2971 entry = hash_table_get_by_idx(table, key, idx);
2975 HeapFree(GetProcessHeap(), 0, key);
2976 entry->value = value;
2980 HeapFree(GetProcessHeap(), 0, entry->key);
2983 /* Remove the entry */
2984 list_remove(&entry->entry);
2985 list_add_head(&table->free_entries, &entry->entry);
2989 /* Shrink if necessary */
2990 if (table->count < table->shrink_size) {
2991 if (!hash_table_resize(table, table->bucket_count >> 1))
2993 ERR("Failed to shrink the table...\n");
3003 /* Grow if necessary */
3004 if (table->count >= table->grow_size)
3006 if (!hash_table_resize(table, table->bucket_count << 1))
3008 ERR("Failed to grow the table, returning.\n");
3012 idx = hash & (table->bucket_count - 1);
3015 /* Find an entry to insert */
3016 if (!list_empty(&table->free_entries))
3018 struct list *elem = list_head(&table->free_entries);
3021 entry = LIST_ENTRY(elem, hash_table_entry_t, entry);
3023 entry = table->entries + (table->entry_count++);
3026 /* Insert the entry */
3028 entry->value = value;
3030 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
3031 list_add_head(&table->buckets[idx], &entry->entry);
3036 void hash_table_remove(hash_table_t *table, void *key)
3038 hash_table_put(table, key, NULL);
3041 void *hash_table_get(hash_table_t *table, void *key)
3044 hash_table_entry_t *entry;
3046 idx = table->hash_function(key) & (table->bucket_count - 1);
3047 entry = hash_table_get_by_idx(table, key, idx);
3049 return entry ? entry->value : NULL;