dsound/winealsa: Remove writelead for alsa directsound.
[wine/multimedia.git] / dlls / wined3d / utils.c
blob65bff5cc7b76cf140810ea71293bc093a0f26441
1 /*
2 * Utility functions for the WineD3D Library
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2007 Henri Verbeet
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "config.h"
26 #include "wined3d_private.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
30 #define GLINFO_LOCATION This->adapter->gl_info
32 /*****************************************************************************
33 * Pixel format array
35 static const PixelFormatDesc formats[] = {
36 /*{WINED3DFORMAT ,alphamask ,redmask ,greenmask ,bluemask ,bpp ,isFourcc ,internal ,srgbInternal ,format ,type }*/
37 {WINED3DFMT_UNKNOWN ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,0 ,0 ,0 ,0 },
38 /* FourCC formats, kept here to have WINED3DFMT_R8G8B8(=20) at position 20 */
39 {WINED3DFMT_UYVY ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 ,0 },
40 {WINED3DFMT_YUY2 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 ,0 },
41 {WINED3DFMT_DXT1 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
42 {WINED3DFMT_DXT2 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
43 {WINED3DFMT_DXT3 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
44 {WINED3DFMT_DXT4 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
45 {WINED3DFMT_DXT5 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
46 {WINED3DFMT_MULTI2_ARGB8,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 ,0 },
47 {WINED3DFMT_G8R8_G8B8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 ,0 },
48 {WINED3DFMT_R8G8_B8G8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 ,0 },
49 /* IEEE formats */
50 {WINED3DFMT_R32F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_RGB32F_ARB ,GL_RGB32F_ARB ,GL_RED ,GL_FLOAT },
51 {WINED3DFMT_G32R32F ,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,0 ,0 ,0 ,0 },
52 {WINED3DFMT_A32B32G32R32F,0x0 ,0x0 ,0x0 ,0x0 ,16 ,FALSE ,GL_RGBA32F_ARB ,GL_RGBA32F_ARB ,GL_RGBA ,GL_FLOAT },
53 /* Hmm? */
54 {WINED3DFMT_CxV8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,0 ,0 ,0 ,0 },
55 /* Float */
56 {WINED3DFMT_R16F ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_RGB16F_ARB ,GL_RGB16F_ARB ,GL_RED ,GL_HALF_FLOAT_ARB },
57 {WINED3DFMT_G16R16F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 ,0 },
58 {WINED3DFMT_A16B16G16R16F,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,GL_RGBA16F_ARB ,GL_RGBA16F_ARB ,GL_RGBA ,GL_HALF_FLOAT_ARB },
59 /* Palettized formats */
60 {WINED3DFMT_A8P8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,0 ,0 ,0 ,0 },
61 {WINED3DFMT_P8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX ,GL_UNSIGNED_BYTE },
62 /* Standard ARGB formats. Keep WINED3DFMT_R8G8B8(=20) at position 20 */
63 {WINED3DFMT_R8G8B8 ,0x0 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,3 ,FALSE ,GL_RGB8 ,GL_RGB8 ,GL_BGR ,GL_UNSIGNED_BYTE },
64 {WINED3DFMT_A8R8G8B8 ,0xff000000 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,FALSE ,GL_RGBA8 ,GL_SRGB8_ALPHA8_EXT ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
65 {WINED3DFMT_X8R8G8B8 ,0x0 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,FALSE ,GL_RGB8 ,GL_SRGB8_EXT ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
66 {WINED3DFMT_R5G6B5 ,0x0 ,0x0000F800 ,0x000007e0 ,0x0000001f ,2 ,FALSE ,GL_RGB5 ,GL_RGB5 ,GL_RGB ,GL_UNSIGNED_SHORT_5_6_5 },
67 {WINED3DFMT_X1R5G5B5 ,0x0 ,0x00007c00 ,0x000003e0 ,0x0000001f ,2 ,FALSE ,GL_RGB5_A1 ,GL_RGB5_A1 ,GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV },
68 {WINED3DFMT_A1R5G5B5 ,0x00008000 ,0x00007c00 ,0x000003e0 ,0x0000001f ,2 ,FALSE ,GL_RGB5_A1 ,GL_RGB5_A1 ,GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV },
69 {WINED3DFMT_A4R4G4B4 ,0x0000f000 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,FALSE ,GL_RGBA4 ,GL_SRGB8_ALPHA8_EXT ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
70 {WINED3DFMT_R3G3B2 ,0x0 ,0x000000e0 ,0x0000001c ,0x00000003 ,1 ,FALSE ,GL_R3_G3_B2 ,GL_R3_G3_B2 ,GL_RGB ,GL_UNSIGNED_BYTE_2_3_3_REV },
71 {WINED3DFMT_A8 ,0x000000ff ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,GL_ALPHA8 ,GL_ALPHA8 ,GL_ALPHA ,GL_UNSIGNED_BYTE },
72 {WINED3DFMT_A8R3G3B2 ,0x0000ff00 ,0x000000e0 ,0x0000001c ,0x00000003 ,2 ,FALSE ,0 ,0 ,0 ,0 },
73 {WINED3DFMT_X4R4G4B4 ,0x0 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,FALSE ,GL_RGB4 ,GL_RGB4 ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
74 {WINED3DFMT_A2B10G10R10 ,0xb0000000 ,0x000003ff ,0x000ffc00 ,0x3ff00000 ,4 ,FALSE ,GL_RGB ,GL_RGB ,GL_RGBA ,GL_UNSIGNED_INT_2_10_10_10_REV },
75 {WINED3DFMT_A8B8G8R8 ,0xff000000 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,FALSE ,GL_RGBA8 ,GL_RGBA8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
76 {WINED3DFMT_X8B8G8R8 ,0x0 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,FALSE ,GL_RGB8 ,GL_RGB8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
77 {WINED3DFMT_G16R16 ,0x0 ,0x0000ffff ,0xffff0000 ,0x0 ,4 ,FALSE ,0 ,0 ,0 ,0 },
78 {WINED3DFMT_A2R10G10B10 ,0xb0000000 ,0x3ff00000 ,0x000ffc00 ,0x000003ff ,4 ,FALSE ,GL_RGBA ,GL_RGBA ,GL_BGRA ,GL_UNSIGNED_INT_2_10_10_10_REV },
79 {WINED3DFMT_A16B16G16R16,0x0 ,0x0000ffff ,0xffff0000 ,0x0 ,8 ,FALSE ,GL_RGBA16_EXT ,GL_RGBA16_EXT ,GL_RGBA ,GL_UNSIGNED_SHORT },
80 /* Luminance */
81 {WINED3DFMT_L8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,GL_LUMINANCE8 ,GL_SLUMINANCE8_EXT ,GL_LUMINANCE ,GL_UNSIGNED_BYTE },
82 {WINED3DFMT_A8L8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_LUMINANCE8_ALPHA8 ,GL_SLUMINANCE8_ALPHA8_EXT ,GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE },
83 {WINED3DFMT_A4L4 ,0x000000f0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,GL_LUMINANCE4_ALPHA4 ,GL_LUMINANCE4_ALPHA4 ,GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE },
84 /* Bump mapping stuff */
85 {WINED3DFMT_V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_DSDT8_NV ,GL_DSDT8_NV ,GL_DSDT_NV ,GL_BYTE },
86 {WINED3DFMT_L6V5U5 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX ,GL_UNSIGNED_SHORT_5_5_5_1 },
87 {WINED3DFMT_X8L8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT_MAG_INTENSITY_NV ,GL_BYTE },
88 {WINED3DFMT_Q8W8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_SIGNED_RGBA8_NV ,GL_SIGNED_RGBA8_NV ,GL_RGBA ,GL_BYTE },
89 {WINED3DFMT_V16U16 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_SIGNED_HILO16_NV ,GL_SIGNED_HILO16_NV ,GL_HILO_NV ,GL_SHORT },
90 {WINED3DFMT_W11V11U10 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 ,0 },
91 {WINED3DFMT_A2W10V10U10 ,0xb0000000 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 ,0 },
92 /* Depth stencil formats */
93 {WINED3DFMT_D16_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT },
94 {WINED3DFMT_D32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
95 {WINED3DFMT_D15S1 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT },
96 {WINED3DFMT_D24S8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
97 {WINED3DFMT_D24X8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT,GL_UNSIGNED_INT },
98 {WINED3DFMT_D24X4S4 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT,GL_UNSIGNED_INT },
99 {WINED3DFMT_D16 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT,GL_UNSIGNED_SHORT },
100 {WINED3DFMT_L16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_LUMINANCE16_EXT ,GL_LUMINANCE16_EXT ,GL_LUMINANCE ,GL_UNSIGNED_SHORT },
101 {WINED3DFMT_D32F_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT ,GL_FLOAT },
102 {WINED3DFMT_D24FS8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_FLOAT },
103 /* Is this a vertex buffer? */
104 {WINED3DFMT_VERTEXDATA ,0x0 ,0x0 ,0x0 ,0x0 ,0 ,FALSE ,0 ,0 ,0 ,0 },
105 {WINED3DFMT_INDEX16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,0 ,0 ,0 ,0 },
106 {WINED3DFMT_INDEX32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 ,0 },
107 {WINED3DFMT_Q16W16V16U16,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,GL_COLOR_INDEX ,GL_COLOR_INDEX ,GL_COLOR_INDEX ,GL_UNSIGNED_SHORT }
110 const PixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt)
112 /* First check if the format is at the position of its value.
113 * This will catch the argb formats before the loop is entered
115 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
116 return &formats[fmt];
117 } else {
118 unsigned int i;
119 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
120 if(formats[i].format == fmt) {
121 return &formats[i];
125 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
126 if(fmt == WINED3DFMT_UNKNOWN) {
127 ERR("Format table corrupt - Can't find WINED3DFMT_UNKNOWN\n");
128 return NULL;
130 /* Get the caller a valid pointer */
131 return getFormatDescEntry(WINED3DFMT_UNKNOWN);
134 /*****************************************************************************
135 * Trace formatting of useful values
137 const char* debug_d3dformat(WINED3DFORMAT fmt) {
138 switch (fmt) {
139 #define FMT_TO_STR(fmt) case fmt: return #fmt
140 FMT_TO_STR(WINED3DFMT_UNKNOWN);
141 FMT_TO_STR(WINED3DFMT_R8G8B8);
142 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
143 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
144 FMT_TO_STR(WINED3DFMT_R5G6B5);
145 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
146 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
147 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
148 FMT_TO_STR(WINED3DFMT_R3G3B2);
149 FMT_TO_STR(WINED3DFMT_A8);
150 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
151 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
152 FMT_TO_STR(WINED3DFMT_A2B10G10R10);
153 FMT_TO_STR(WINED3DFMT_A8B8G8R8);
154 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
155 FMT_TO_STR(WINED3DFMT_G16R16);
156 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
157 FMT_TO_STR(WINED3DFMT_A16B16G16R16);
158 FMT_TO_STR(WINED3DFMT_A8P8);
159 FMT_TO_STR(WINED3DFMT_P8);
160 FMT_TO_STR(WINED3DFMT_L8);
161 FMT_TO_STR(WINED3DFMT_A8L8);
162 FMT_TO_STR(WINED3DFMT_A4L4);
163 FMT_TO_STR(WINED3DFMT_V8U8);
164 FMT_TO_STR(WINED3DFMT_L6V5U5);
165 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
166 FMT_TO_STR(WINED3DFMT_Q8W8V8U8);
167 FMT_TO_STR(WINED3DFMT_V16U16);
168 FMT_TO_STR(WINED3DFMT_W11V11U10);
169 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
170 FMT_TO_STR(WINED3DFMT_UYVY);
171 FMT_TO_STR(WINED3DFMT_YUY2);
172 FMT_TO_STR(WINED3DFMT_DXT1);
173 FMT_TO_STR(WINED3DFMT_DXT2);
174 FMT_TO_STR(WINED3DFMT_DXT3);
175 FMT_TO_STR(WINED3DFMT_DXT4);
176 FMT_TO_STR(WINED3DFMT_DXT5);
177 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
178 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
179 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
180 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
181 FMT_TO_STR(WINED3DFMT_D32);
182 FMT_TO_STR(WINED3DFMT_D15S1);
183 FMT_TO_STR(WINED3DFMT_D24S8);
184 FMT_TO_STR(WINED3DFMT_D24X8);
185 FMT_TO_STR(WINED3DFMT_D24X4S4);
186 FMT_TO_STR(WINED3DFMT_D16);
187 FMT_TO_STR(WINED3DFMT_L16);
188 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
189 FMT_TO_STR(WINED3DFMT_D24FS8);
190 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
191 FMT_TO_STR(WINED3DFMT_INDEX16);
192 FMT_TO_STR(WINED3DFMT_INDEX32);
193 FMT_TO_STR(WINED3DFMT_Q16W16V16U16);
194 FMT_TO_STR(WINED3DFMT_R16F);
195 FMT_TO_STR(WINED3DFMT_G16R16F);
196 FMT_TO_STR(WINED3DFMT_A16B16G16R16F);
197 FMT_TO_STR(WINED3DFMT_R32F);
198 FMT_TO_STR(WINED3DFMT_G32R32F);
199 FMT_TO_STR(WINED3DFMT_A32B32G32R32F);
200 FMT_TO_STR(WINED3DFMT_CxV8U8);
201 #undef FMT_TO_STR
202 default:
204 char fourcc[5];
205 fourcc[0] = (char)(fmt);
206 fourcc[1] = (char)(fmt >> 8);
207 fourcc[2] = (char)(fmt >> 16);
208 fourcc[3] = (char)(fmt >> 24);
209 fourcc[4] = 0;
210 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
211 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
212 else
213 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
215 return "unrecognized";
219 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
220 switch (devtype) {
221 #define DEVTYPE_TO_STR(dev) case dev: return #dev
222 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
223 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
224 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
225 #undef DEVTYPE_TO_STR
226 default:
227 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
228 return "unrecognized";
232 const char* debug_d3dusage(DWORD usage) {
233 switch (usage & WINED3DUSAGE_MASK) {
234 #define WINED3DUSAGE_TO_STR(u) case u: return #u
235 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
236 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
237 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
238 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
239 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
240 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
241 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
242 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
243 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
244 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
245 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
246 #undef WINED3DUSAGE_TO_STR
247 case 0: return "none";
248 default:
249 FIXME("Unrecognized %u Usage!\n", usage);
250 return "unrecognized";
254 const char* debug_d3dusagequery(DWORD usagequery) {
255 switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
256 #define WINED3DUSAGEQUERY_TO_STR(u) case u: return #u
257 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
258 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
259 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
260 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
261 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
262 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
263 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
264 #undef WINED3DUSAGEQUERY_TO_STR
265 case 0: return "none";
266 default:
267 FIXME("Unrecognized %u Usage Query!\n", usagequery);
268 return "unrecognized";
272 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
273 switch (method) {
274 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
275 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
276 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
277 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
278 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
279 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
280 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
281 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
282 #undef WINED3DDECLMETHOD_TO_STR
283 default:
284 FIXME("Unrecognized %u declaration method!\n", method);
285 return "unrecognized";
289 const char* debug_d3ddecltype(WINED3DDECLTYPE type) {
290 switch (type) {
291 #define WINED3DDECLTYPE_TO_STR(u) case u: return #u
292 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT1);
293 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT2);
294 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT3);
295 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT4);
296 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_D3DCOLOR);
297 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4);
298 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2);
299 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4);
300 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4N);
301 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2N);
302 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4N);
303 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT2N);
304 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT4N);
305 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UDEC3);
306 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_DEC3N);
307 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_2);
308 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_4);
309 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UNUSED);
310 #undef WINED3DDECLTYPE_TO_STR
311 default:
312 FIXME("Unrecognized %u declaration type!\n", type);
313 return "unrecognized";
317 const char* debug_d3ddeclusage(BYTE usage) {
318 switch (usage) {
319 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
320 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
321 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
322 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
323 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
324 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
325 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
326 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
327 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
328 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
329 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
330 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
331 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
332 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
333 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
334 #undef WINED3DDECLUSAGE_TO_STR
335 default:
336 FIXME("Unrecognized %u declaration usage!\n", usage);
337 return "unrecognized";
341 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
342 switch (res) {
343 #define RES_TO_STR(res) case res: return #res;
344 RES_TO_STR(WINED3DRTYPE_SURFACE);
345 RES_TO_STR(WINED3DRTYPE_VOLUME);
346 RES_TO_STR(WINED3DRTYPE_TEXTURE);
347 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
348 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
349 RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER);
350 RES_TO_STR(WINED3DRTYPE_INDEXBUFFER);
351 #undef RES_TO_STR
352 default:
353 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
354 return "unrecognized";
358 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
359 switch (PrimitiveType) {
360 #define PRIM_TO_STR(prim) case prim: return #prim;
361 PRIM_TO_STR(WINED3DPT_POINTLIST);
362 PRIM_TO_STR(WINED3DPT_LINELIST);
363 PRIM_TO_STR(WINED3DPT_LINESTRIP);
364 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
365 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
366 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
367 #undef PRIM_TO_STR
368 default:
369 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
370 return "unrecognized";
374 const char* debug_d3drenderstate(DWORD state) {
375 switch (state) {
376 #define D3DSTATE_TO_STR(u) case u: return #u
377 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
378 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
379 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
380 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
381 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
382 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
383 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
384 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
385 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
386 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
387 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
388 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
389 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
390 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
391 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
392 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
393 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
394 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
395 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
396 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
397 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
398 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
399 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
400 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
401 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
402 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
403 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
404 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
405 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
406 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
407 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
408 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
409 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
410 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
411 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
412 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
413 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
414 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
415 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
416 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
417 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
418 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
419 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
420 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
421 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
422 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
423 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
424 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
425 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
426 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
427 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
428 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
429 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
430 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
431 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
432 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
433 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
434 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
435 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
436 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
437 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
438 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
439 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
440 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
441 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
442 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
443 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
444 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
445 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
446 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
447 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
448 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
449 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
450 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
451 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
452 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
453 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
454 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
455 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
456 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
457 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
458 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
459 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
460 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
461 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
462 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
463 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
464 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
465 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
466 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
467 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
468 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
469 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
470 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
471 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
472 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
473 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
474 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
475 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
476 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
477 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
478 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
479 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
480 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
481 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
482 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
483 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
484 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
485 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
486 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
487 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
488 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
489 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
490 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
491 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
492 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
493 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
494 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
495 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
496 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
497 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
498 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
499 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
500 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
501 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
502 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
503 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
504 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
505 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
506 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
507 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
508 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
509 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
510 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
511 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
512 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
513 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
514 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
515 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
516 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
517 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
518 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
519 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
520 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
521 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
522 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
523 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
524 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
525 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
526 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
527 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
528 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
529 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
530 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
531 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
532 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
533 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
534 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
535 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
536 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
537 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
538 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
539 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
540 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
541 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
542 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
543 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
544 #undef D3DSTATE_TO_STR
545 default:
546 FIXME("Unrecognized %u render state!\n", state);
547 return "unrecognized";
551 const char* debug_d3dsamplerstate(DWORD state) {
552 switch (state) {
553 #define D3DSTATE_TO_STR(u) case u: return #u
554 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
555 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
556 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
557 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
558 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
559 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
560 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
561 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
562 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
563 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
564 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
565 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
566 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
567 #undef D3DSTATE_TO_STR
568 default:
569 FIXME("Unrecognized %u sampler state!\n", state);
570 return "unrecognized";
574 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
575 switch (filter_type) {
576 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
577 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
578 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
579 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
580 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
581 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
582 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
583 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
584 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
585 #undef D3DTEXTUREFILTERTYPE_TO_STR
586 default:
587 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
588 return "unrecognized";
592 const char* debug_d3dtexturestate(DWORD state) {
593 switch (state) {
594 #define D3DSTATE_TO_STR(u) case u: return #u
595 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
596 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
597 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
598 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
599 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
600 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
601 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
602 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
603 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
604 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
605 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
606 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
607 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
608 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
609 D3DSTATE_TO_STR(WINED3DTSS_ADDRESSW );
610 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
611 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
612 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
613 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
614 #undef D3DSTATE_TO_STR
615 case 12:
616 /* Note WINED3DTSS are not consecutive, so skip these */
617 return "unused";
618 break;
619 default:
620 FIXME("Unrecognized %u texture state!\n", state);
621 return "unrecognized";
625 static const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
626 switch (d3dtop) {
627 #define D3DTOP_TO_STR(u) case u: return #u
628 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
629 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
630 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
631 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
632 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
633 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
634 D3DTOP_TO_STR(WINED3DTOP_ADD);
635 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
636 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
637 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
638 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
639 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
640 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
641 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
642 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
643 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
644 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
645 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
646 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
647 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
648 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
649 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
650 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
651 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
652 D3DTOP_TO_STR(WINED3DTOP_LERP);
653 #undef D3DTOP_TO_STR
654 default:
655 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
656 return "unrecognized";
660 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
661 switch (tstype) {
662 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
663 TSTYPE_TO_STR(WINED3DTS_VIEW);
664 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
665 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
666 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
667 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
668 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
669 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
670 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
671 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
672 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
673 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
674 #undef TSTYPE_TO_STR
675 default:
676 if (tstype > 256 && tstype < 512) {
677 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
678 return ("WINED3DTS_WORLDMATRIX > 0");
680 FIXME("Unrecognized %u WINED3DTS\n", tstype);
681 return "unrecognized";
685 const char* debug_d3dpool(WINED3DPOOL Pool) {
686 switch (Pool) {
687 #define POOL_TO_STR(p) case p: return #p;
688 POOL_TO_STR(WINED3DPOOL_DEFAULT);
689 POOL_TO_STR(WINED3DPOOL_MANAGED);
690 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
691 POOL_TO_STR(WINED3DPOOL_SCRATCH);
692 #undef POOL_TO_STR
693 default:
694 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
695 return "unrecognized";
699 const char *debug_fbostatus(GLenum status) {
700 switch(status) {
701 #define FBOSTATUS_TO_STR(u) case u: return #u
702 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
703 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
704 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
705 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
706 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
707 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
708 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
709 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
710 #undef FBOSTATUS_TO_STR
711 default:
712 FIXME("Unrecognied FBO status 0x%08x\n", status);
713 return "unrecognized";
717 const char *debug_glerror(GLenum error) {
718 switch(error) {
719 #define GLERROR_TO_STR(u) case u: return #u
720 GLERROR_TO_STR(GL_NO_ERROR);
721 GLERROR_TO_STR(GL_INVALID_ENUM);
722 GLERROR_TO_STR(GL_INVALID_VALUE);
723 GLERROR_TO_STR(GL_INVALID_OPERATION);
724 GLERROR_TO_STR(GL_STACK_OVERFLOW);
725 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
726 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
727 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
728 #undef GLERROR_TO_STR
729 default:
730 FIXME("Unrecognied GL error 0x%08x\n", error);
731 return "unrecognized";
735 /*****************************************************************************
736 * Useful functions mapping GL <-> D3D values
738 GLenum StencilOp(DWORD op) {
739 switch(op) {
740 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
741 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
742 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
743 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
744 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
745 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
746 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
747 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
748 default:
749 FIXME("Unrecognized stencil op %d\n", op);
750 return GL_KEEP;
754 GLenum CompareFunc(DWORD func) {
755 switch ((WINED3DCMPFUNC)func) {
756 case WINED3DCMP_NEVER : return GL_NEVER;
757 case WINED3DCMP_LESS : return GL_LESS;
758 case WINED3DCMP_EQUAL : return GL_EQUAL;
759 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
760 case WINED3DCMP_GREATER : return GL_GREATER;
761 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
762 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
763 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
764 default:
765 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
766 return 0;
770 static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) {
771 switch (d3dta) {
772 case WINED3DTA_DIFFUSE:
773 return GL_PRIMARY_COLOR_NV;
775 case WINED3DTA_CURRENT:
776 if (stage) return GL_SPARE0_NV;
777 else return GL_PRIMARY_COLOR_NV;
779 case WINED3DTA_TEXTURE:
780 if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx;
781 else return GL_PRIMARY_COLOR_NV;
783 case WINED3DTA_TFACTOR:
784 return GL_CONSTANT_COLOR0_NV;
786 case WINED3DTA_SPECULAR:
787 return GL_SECONDARY_COLOR_NV;
789 case WINED3DTA_TEMP:
790 /* TODO: Support WINED3DTSS_RESULTARG */
791 FIXME("WINED3DTA_TEMP, not properly supported.\n");
792 return GL_SPARE1_NV;
794 case WINED3DTA_CONSTANT:
795 /* TODO: Support per stage constants (WINED3DTSS_CONSTANT, NV_register_combiners2) */
796 FIXME("WINED3DTA_CONSTANT, not properly supported.\n");
797 return GL_CONSTANT_COLOR1_NV;
799 default:
800 FIXME("Unrecognized texture arg %#x\n", d3dta);
801 return GL_TEXTURE;
805 static GLenum invert_mapping(GLenum mapping) {
806 if (mapping == GL_UNSIGNED_INVERT_NV) return GL_SIGNED_IDENTITY_NV;
807 else if (mapping == GL_SIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV;
809 FIXME("Unhandled mapping %#x\n", mapping);
810 return mapping;
813 static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) {
814 /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should
815 * be used. */
816 if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV;
817 else *mapping = GL_SIGNED_IDENTITY_NV;
819 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input
820 * should be used for all input components. */
821 if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA;
822 else *component_usage = GL_RGB;
824 *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx);
827 typedef struct {
828 GLenum input[3];
829 GLenum mapping[3];
830 GLenum component_usage[3];
831 } tex_op_args;
833 static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
834 if (op == WINED3DTOP_DISABLE) return FALSE;
835 if (This->stateBlock->textures[stage]) return FALSE;
837 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
838 && op != WINED3DTOP_SELECTARG2) return TRUE;
839 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
840 && op != WINED3DTOP_SELECTARG1) return TRUE;
841 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
842 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
844 return FALSE;
847 void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx) {
848 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface;
849 tex_op_args tex_op_args = {{0}, {0}, {0}};
850 GLenum portion = is_alpha ? GL_ALPHA : GL_RGB;
851 GLenum target = GL_COMBINER0_NV + stage;
853 TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
854 stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx);
856 /* If a texture stage references an invalid texture unit the stage just
857 * passes through the result from the previous stage */
858 if (is_invalid_op(This, stage, op, arg1, arg2, arg3)) {
859 arg1 = WINED3DTA_CURRENT;
860 op = WINED3DTOP_SELECTARG1;
863 get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0],
864 &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx);
865 get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1],
866 &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx);
867 get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2],
868 &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx);
871 /* This is called by a state handler which has the gl lock held and a context for the thread */
872 switch(op)
874 case WINED3DTOP_DISABLE:
875 /* Only for alpha */
876 if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n");
877 /* Input, prev_alpha*1 */
878 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
879 GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
880 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
881 GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
883 /* Output */
884 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
885 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
886 break;
888 case WINED3DTOP_SELECTARG1:
889 case WINED3DTOP_SELECTARG2:
890 /* Input, arg*1 */
891 if (op == WINED3DTOP_SELECTARG1) {
892 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
893 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
894 } else {
895 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
896 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
898 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
899 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
901 /* Output */
902 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
903 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
904 break;
906 case WINED3DTOP_MODULATE:
907 case WINED3DTOP_MODULATE2X:
908 case WINED3DTOP_MODULATE4X:
909 /* Input, arg1*arg2 */
910 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
911 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
912 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
913 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
915 /* Output */
916 if (op == WINED3DTOP_MODULATE) {
917 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
918 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
919 } else if (op == WINED3DTOP_MODULATE2X) {
920 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
921 GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
922 } else if (op == WINED3DTOP_MODULATE4X) {
923 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
924 GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
926 break;
928 case WINED3DTOP_ADD:
929 case WINED3DTOP_ADDSIGNED:
930 case WINED3DTOP_ADDSIGNED2X:
931 /* Input, arg1*1+arg2*1 */
932 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
933 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
934 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
935 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
936 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
937 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
938 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
939 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
941 /* Output */
942 if (op == WINED3DTOP_ADD) {
943 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
944 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
945 } else if (op == WINED3DTOP_ADDSIGNED) {
946 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
947 GL_SPARE0_NV, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
948 } else if (op == WINED3DTOP_ADDSIGNED2X) {
949 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
950 GL_SPARE0_NV, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
952 break;
954 case WINED3DTOP_SUBTRACT:
955 /* Input, arg1*1+-arg2*1 */
956 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
957 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
958 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
959 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
960 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
961 tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1]));
962 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
963 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
965 /* Output */
966 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
967 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
968 break;
970 case WINED3DTOP_ADDSMOOTH:
971 /* Input, arg1*1+(1-arg1)*arg2 */
972 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
973 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
974 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
975 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
976 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
977 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
978 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
979 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
981 /* Output */
982 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
983 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
984 break;
986 case WINED3DTOP_BLENDDIFFUSEALPHA:
987 case WINED3DTOP_BLENDTEXTUREALPHA:
988 case WINED3DTOP_BLENDFACTORALPHA:
989 case WINED3DTOP_BLENDTEXTUREALPHAPM:
990 case WINED3DTOP_BLENDCURRENTALPHA:
992 GLenum alpha_src = GL_PRIMARY_COLOR_NV;
993 if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx);
994 else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
995 else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx);
996 else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
997 else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx);
998 else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op));
1000 /* Input, arg1*alpha_src+arg2*(1-alpha_src) */
1001 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1002 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1003 if (op == WINED3DTOP_BLENDTEXTUREALPHAPM)
1005 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1006 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1007 } else {
1008 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1009 alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
1011 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1012 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1013 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1014 alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
1016 /* Output */
1017 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1018 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1019 break;
1022 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1023 /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */
1024 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n");
1025 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1026 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1027 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1028 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1029 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1030 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1031 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1032 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1034 /* Output */
1035 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1036 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1037 break;
1039 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1040 /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */
1041 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n");
1042 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1043 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1044 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1045 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1046 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1047 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1048 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1049 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1051 /* Output */
1052 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1053 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1054 break;
1056 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1057 /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */
1058 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n");
1059 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1060 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA));
1061 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1062 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1063 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1064 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1065 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1066 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1068 /* Output */
1069 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1070 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1071 break;
1073 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1074 /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */
1075 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n");
1076 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1077 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1078 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1079 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1080 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1081 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1082 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1083 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1085 /* Output */
1086 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1087 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1088 break;
1090 case WINED3DTOP_DOTPRODUCT3:
1091 /* Input, arg1 . arg2 */
1092 /* FIXME: DX7 uses a different calculation? */
1093 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1094 tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0]));
1095 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1096 tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1]));
1098 /* Output */
1099 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1100 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE));
1101 break;
1103 case WINED3DTOP_MULTIPLYADD:
1104 /* Input, arg1*1+arg2*arg3 */
1105 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1106 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1107 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1108 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1109 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1110 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1111 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1112 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1114 /* Output */
1115 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1116 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1117 break;
1119 case WINED3DTOP_LERP:
1120 /* Input, arg1*arg2+(1-arg1)*arg3 */
1121 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1122 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1123 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1124 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1125 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1126 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1127 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1128 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1130 /* Output */
1131 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1132 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1133 break;
1135 case WINED3DTOP_BUMPENVMAPLUMINANCE:
1136 case WINED3DTOP_BUMPENVMAP:
1137 if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
1138 /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to
1139 * perform bump mapping and source from the current stage. Pretty much a SELECTARG2.
1140 * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1
1141 * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the next stage
1143 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1144 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1145 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1146 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1147 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1148 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1149 break;
1152 default:
1153 FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1154 stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
1157 checkGLcall("set_tex_op_nvrc()\n");
1161 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
1162 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
1163 * input should be used for all input components. The WINED3DTA_COMPLEMENT
1164 * flag specifies the complement of the input should be used. */
1165 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
1166 BOOL complement = arg & WINED3DTA_COMPLEMENT;
1168 /* Calculate the operand */
1169 if (complement) {
1170 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
1171 else *operand = GL_ONE_MINUS_SRC_COLOR;
1172 } else {
1173 if (from_alpha) *operand = GL_SRC_ALPHA;
1174 else *operand = GL_SRC_COLOR;
1177 /* Calculate the source */
1178 switch (arg & WINED3DTA_SELECTMASK) {
1179 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
1180 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
1181 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
1182 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
1183 case WINED3DTA_SPECULAR:
1185 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
1186 * 'Secondary color' and isn't supported until base GL supports it
1187 * There is no concept of temp registers as far as I can tell
1189 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
1190 *source = GL_TEXTURE;
1191 break;
1192 default:
1193 FIXME("Unrecognized texture arg %#x\n", arg);
1194 *source = GL_TEXTURE;
1195 break;
1199 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
1200 #if defined (GL_VERSION_1_3)
1201 # define useext(A) A
1202 # define combine_ext 1
1203 #elif defined (GL_EXT_texture_env_combine)
1204 # define useext(A) A##_EXT
1205 # define combine_ext 1
1206 #elif defined (GL_ARB_texture_env_combine)
1207 # define useext(A) A##_ARB
1208 # define combine_ext 1
1209 #else
1210 # undef combine_ext
1211 #endif
1213 #if !defined(combine_ext)
1214 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1216 FIXME("Requires opengl combine extensions to work\n");
1217 return;
1219 #else
1220 /* Setup the texture operations texture stage states */
1221 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1223 GLenum src1, src2, src3;
1224 GLenum opr1, opr2, opr3;
1225 GLenum comb_target;
1226 GLenum src0_target, src1_target, src2_target;
1227 GLenum opr0_target, opr1_target, opr2_target;
1228 GLenum scal_target;
1229 GLenum opr=0, invopr, src3_target, opr3_target;
1230 BOOL Handled = FALSE;
1231 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
1233 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
1235 /* This is called by a state handler which has the gl lock held and a context for the thread */
1237 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
1238 the form (a1 <operation> a2). However, some of the more complex operations
1239 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
1240 in a third parameter called a0. Therefore these are operations of the form
1241 a0 <operation> a1 <operation> a2, ie the new parameter goes to the front.
1243 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
1244 functions below, expect their syntax to differ slightly to those listed in the
1245 manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
1246 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
1248 if (isAlpha) {
1249 comb_target = useext(GL_COMBINE_ALPHA);
1250 src0_target = useext(GL_SOURCE0_ALPHA);
1251 src1_target = useext(GL_SOURCE1_ALPHA);
1252 src2_target = useext(GL_SOURCE2_ALPHA);
1253 opr0_target = useext(GL_OPERAND0_ALPHA);
1254 opr1_target = useext(GL_OPERAND1_ALPHA);
1255 opr2_target = useext(GL_OPERAND2_ALPHA);
1256 scal_target = GL_ALPHA_SCALE;
1258 else {
1259 comb_target = useext(GL_COMBINE_RGB);
1260 src0_target = useext(GL_SOURCE0_RGB);
1261 src1_target = useext(GL_SOURCE1_RGB);
1262 src2_target = useext(GL_SOURCE2_RGB);
1263 opr0_target = useext(GL_OPERAND0_RGB);
1264 opr1_target = useext(GL_OPERAND1_RGB);
1265 opr2_target = useext(GL_OPERAND2_RGB);
1266 scal_target = useext(GL_RGB_SCALE);
1269 /* If a texture stage references an invalid texture unit the stage just
1270 * passes through the result from the previous stage */
1271 if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) {
1272 arg1 = WINED3DTA_CURRENT;
1273 op = WINED3DTOP_SELECTARG1;
1276 /* From MSDN (WINED3DTSS_ALPHAARG1) :
1277 The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage,
1278 then the default argument is WINED3DTA_DIFFUSE.
1279 FIXME? If texture added/removed, may need to reset back as well? */
1280 if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
1281 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
1282 } else {
1283 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
1285 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
1286 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
1288 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
1290 Handled = TRUE; /* Assume will be handled */
1292 /* Other texture operations require special extensions: */
1293 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1294 if (isAlpha) {
1295 opr = GL_SRC_ALPHA;
1296 invopr = GL_ONE_MINUS_SRC_ALPHA;
1297 src3_target = GL_SOURCE3_ALPHA_NV;
1298 opr3_target = GL_OPERAND3_ALPHA_NV;
1299 } else {
1300 opr = GL_SRC_COLOR;
1301 invopr = GL_ONE_MINUS_SRC_COLOR;
1302 src3_target = GL_SOURCE3_RGB_NV;
1303 opr3_target = GL_OPERAND3_RGB_NV;
1305 switch (op) {
1306 case WINED3DTOP_DISABLE: /* Only for alpha */
1307 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1308 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1309 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1310 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1311 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1312 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1313 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1314 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1315 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1316 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1317 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1318 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1319 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1320 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1321 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1322 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1323 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1324 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1325 break;
1326 case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */
1327 case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
1328 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1329 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1330 if (op == WINED3DTOP_SELECTARG1) {
1331 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1332 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1333 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1334 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1335 } else {
1336 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1337 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1338 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1339 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1341 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1342 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1343 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1344 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1345 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1346 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1347 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1348 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1349 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1350 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1351 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1352 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1353 break;
1355 case WINED3DTOP_MODULATE:
1356 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1357 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1358 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1359 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1360 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1361 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1362 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1363 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1364 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1365 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1366 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1367 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1368 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1369 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1370 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1371 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1372 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1373 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1374 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1375 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1376 break;
1377 case WINED3DTOP_MODULATE2X:
1378 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1379 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1380 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1381 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1382 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1383 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1384 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1385 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1386 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1387 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1388 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1389 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1390 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1391 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1392 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1393 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1394 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1395 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1396 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1397 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1398 break;
1399 case WINED3DTOP_MODULATE4X:
1400 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1401 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1402 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1403 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1404 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1405 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1406 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1407 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1408 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1409 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1410 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1411 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1412 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1413 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1414 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1415 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1416 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1417 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1418 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
1419 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
1420 break;
1422 case WINED3DTOP_ADD:
1423 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1424 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1425 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1426 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1427 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1428 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1429 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1430 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1431 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1432 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1433 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1434 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1435 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1436 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1437 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1438 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1439 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1440 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1441 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1442 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1443 break;
1445 case WINED3DTOP_ADDSIGNED:
1446 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1447 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1448 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1449 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1450 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1451 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1452 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1453 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1454 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1455 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1456 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1457 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1458 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1459 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1460 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1461 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1462 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1463 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1464 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1465 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1466 break;
1468 case WINED3DTOP_ADDSIGNED2X:
1469 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1470 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1471 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1472 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1473 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1474 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1475 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1476 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1477 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1478 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1479 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1480 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1481 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1482 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1483 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1484 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1485 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1486 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1487 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1488 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1489 break;
1491 case WINED3DTOP_ADDSMOOTH:
1492 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1493 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1494 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1495 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1496 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1497 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1498 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1499 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1500 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1501 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1502 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1503 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1504 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1505 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1506 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1507 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1508 switch (opr1) {
1509 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1510 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1511 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1512 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1514 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1515 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1516 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1517 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1518 break;
1520 case WINED3DTOP_BLENDDIFFUSEALPHA:
1521 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1522 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1523 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1524 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1525 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1526 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1527 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
1528 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
1529 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1530 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1531 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1532 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1533 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1534 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1535 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
1536 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
1537 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1538 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1539 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1540 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1541 break;
1542 case WINED3DTOP_BLENDTEXTUREALPHA:
1543 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1544 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1545 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1546 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1547 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1548 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1549 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
1550 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
1551 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1552 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1553 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1554 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1555 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1556 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1557 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1558 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1559 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1560 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1561 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1562 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1563 break;
1564 case WINED3DTOP_BLENDFACTORALPHA:
1565 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1566 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1567 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1568 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1569 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1570 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1571 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
1572 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
1573 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1574 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1575 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1576 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1577 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1578 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1579 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
1580 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
1581 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1582 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1583 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1584 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1585 break;
1586 case WINED3DTOP_BLENDTEXTUREALPHAPM:
1587 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1588 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1589 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1590 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1591 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1592 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1593 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1594 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1595 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1596 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1597 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1598 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1599 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1600 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1601 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1602 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1603 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1604 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1605 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1606 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1607 break;
1608 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1609 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1610 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1611 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
1612 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1613 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1614 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
1615 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1616 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1617 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1618 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1619 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
1620 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1621 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1622 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
1623 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1624 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1625 switch (opr) {
1626 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1627 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1629 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1630 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1631 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1632 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1633 break;
1634 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1635 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1636 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1637 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1638 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1639 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1640 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1641 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1642 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1643 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1644 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1645 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1646 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1647 switch (opr1) {
1648 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1649 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1651 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1652 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1653 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1654 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1655 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1656 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1657 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1658 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1659 break;
1660 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1661 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1662 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1663 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1664 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1665 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1666 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1667 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1668 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1669 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1670 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1671 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1672 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1673 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1674 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1675 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1676 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1677 switch (opr1) {
1678 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1679 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1680 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1681 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1683 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1684 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1685 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1686 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1687 break;
1688 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1689 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1690 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1691 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1692 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1693 switch (opr1) {
1694 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1695 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1696 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1697 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1699 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
1700 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
1701 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1702 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1703 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1704 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1705 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1706 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1707 switch (opr1) {
1708 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1709 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1711 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1712 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1713 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1714 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1715 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1716 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1717 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1718 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1719 break;
1720 case WINED3DTOP_MULTIPLYADD:
1721 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1722 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1723 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
1724 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1725 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
1726 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1727 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1728 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1729 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1730 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1731 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1732 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1733 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1734 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1735 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
1736 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
1737 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
1738 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
1739 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1740 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1741 break;
1743 case WINED3DTOP_BUMPENVMAP:
1747 case WINED3DTOP_BUMPENVMAPLUMINANCE:
1748 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
1750 default:
1751 Handled = FALSE;
1753 if (Handled) {
1754 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
1755 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
1757 return;
1759 } /* GL_NV_texture_env_combine4 */
1761 Handled = TRUE; /* Again, assume handled */
1762 switch (op) {
1763 case WINED3DTOP_DISABLE: /* Only for alpha */
1764 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1765 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1766 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1767 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
1768 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1769 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
1770 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1771 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1772 break;
1773 case WINED3DTOP_SELECTARG1:
1774 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1775 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1776 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1777 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1778 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1779 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1780 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1781 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1782 break;
1783 case WINED3DTOP_SELECTARG2:
1784 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1785 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1786 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1787 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1788 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1789 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1790 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1791 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1792 break;
1793 case WINED3DTOP_MODULATE:
1794 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1795 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1796 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1797 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1798 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1799 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1800 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1801 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1802 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1803 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1804 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1805 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1806 break;
1807 case WINED3DTOP_MODULATE2X:
1808 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1809 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1810 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1811 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1812 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1813 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1814 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1815 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1816 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1817 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1818 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1819 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1820 break;
1821 case WINED3DTOP_MODULATE4X:
1822 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1823 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1824 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1825 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1826 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1827 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1828 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1829 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1830 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1831 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1832 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
1833 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
1834 break;
1835 case WINED3DTOP_ADD:
1836 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1837 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1838 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1839 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1840 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1841 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1842 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1843 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1844 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1845 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1846 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1847 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1848 break;
1849 case WINED3DTOP_ADDSIGNED:
1850 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1851 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
1852 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1853 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1854 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1855 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1856 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1857 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1858 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1859 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1860 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1861 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1862 break;
1863 case WINED3DTOP_ADDSIGNED2X:
1864 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1865 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1866 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1867 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1868 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1869 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1870 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1871 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1872 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1873 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1874 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1875 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1876 break;
1877 case WINED3DTOP_SUBTRACT:
1878 if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
1879 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
1880 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
1881 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1882 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1883 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1884 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1885 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1886 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1887 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1888 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1889 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1890 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1891 } else {
1892 FIXME("This version of opengl does not support GL_SUBTRACT\n");
1894 break;
1896 case WINED3DTOP_BLENDDIFFUSEALPHA:
1897 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1898 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1899 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1900 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1901 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1902 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1903 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1904 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1905 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1906 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1907 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
1908 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
1909 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1910 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1911 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1912 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1913 break;
1914 case WINED3DTOP_BLENDTEXTUREALPHA:
1915 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1916 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1917 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1918 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1919 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1920 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1921 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1922 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1923 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1924 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1925 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
1926 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
1927 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1928 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1929 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1930 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1931 break;
1932 case WINED3DTOP_BLENDFACTORALPHA:
1933 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1934 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1935 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1936 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1937 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1938 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1939 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1940 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1941 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1942 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1943 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
1944 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
1945 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1946 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1947 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1948 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1949 break;
1950 case WINED3DTOP_BLENDCURRENTALPHA:
1951 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1952 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1953 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1954 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1955 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1956 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1957 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1958 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1959 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1960 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1961 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
1962 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
1963 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1964 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1965 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1966 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1967 break;
1968 case WINED3DTOP_DOTPRODUCT3:
1969 if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
1970 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
1971 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
1972 } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
1973 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
1974 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
1975 } else {
1976 FIXME("This version of opengl does not support GL_DOT3\n");
1978 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1979 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1980 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1981 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1982 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1983 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1984 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1985 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1986 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1987 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1988 break;
1989 case WINED3DTOP_LERP:
1990 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1991 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1992 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1993 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1994 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1995 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1996 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1997 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1998 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1999 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2000 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2001 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2002 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2003 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2004 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2005 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2006 break;
2007 case WINED3DTOP_ADDSMOOTH:
2008 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2009 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2010 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2011 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2012 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2013 switch (opr1) {
2014 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2015 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2016 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2017 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2019 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2020 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2021 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2022 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2023 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2024 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2025 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2026 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2027 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2028 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2029 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2030 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2031 } else
2032 Handled = FALSE;
2033 break;
2034 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2035 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2036 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2037 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2038 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2039 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2040 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2041 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2042 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2043 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2044 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2045 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2046 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2047 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2048 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2049 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2050 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2051 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2052 } else
2053 Handled = FALSE;
2054 break;
2055 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2056 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2057 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2058 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2059 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2060 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2061 switch (opr1) {
2062 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2063 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2064 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2065 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2067 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2068 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2069 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2070 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2071 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2072 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2073 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2074 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2075 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2076 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2077 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2078 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2079 } else
2080 Handled = FALSE;
2081 break;
2082 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2083 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2084 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2085 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2086 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2087 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2088 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2089 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2090 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2091 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2092 switch (opr1) {
2093 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2094 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2095 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2096 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2098 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2099 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2100 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2101 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2102 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2103 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2104 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2105 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2106 } else
2107 Handled = FALSE;
2108 break;
2109 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2110 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2111 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2112 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2113 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2114 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2115 switch (opr1) {
2116 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2117 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2118 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2119 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2121 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2122 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2123 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2124 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2125 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2126 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2127 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2128 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2129 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2130 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2131 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2132 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2133 } else
2134 Handled = FALSE;
2135 break;
2136 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2137 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2138 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2139 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2140 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2141 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2142 switch (opr1) {
2143 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2144 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2145 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2146 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2148 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2149 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2150 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2151 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2152 switch (opr1) {
2153 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2154 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2155 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2156 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2158 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2159 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2160 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2161 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2162 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2163 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2164 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2165 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2166 } else
2167 Handled = FALSE;
2168 break;
2169 case WINED3DTOP_MULTIPLYADD:
2170 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2171 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2172 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2173 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2174 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2175 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2176 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2177 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2178 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2179 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2180 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2181 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2182 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2183 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2184 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2185 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2186 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2187 } else
2188 Handled = FALSE;
2189 break;
2190 case WINED3DTOP_BUMPENVMAPLUMINANCE:
2191 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2192 /* Some apps use BUMPENVMAPLUMINANCE instead of D3DTOP_BUMPENVMAP, although
2193 * they check for the non-luminance cap flag. Well, give them what they asked
2194 * for :-)
2196 WARN("Application uses WINED3DTOP_BUMPENVMAPLUMINANCE\n");
2197 } else {
2198 Handled = FALSE;
2199 break;
2201 /* Fall through */
2202 case WINED3DTOP_BUMPENVMAP:
2203 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2204 TRACE("Using ati bumpmap on stage %d, target %d\n", Stage, Stage + 1);
2205 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI);
2206 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI)");
2207 glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1);
2208 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1)");
2209 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2210 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2211 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2212 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2213 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2214 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2215 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2216 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2217 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2218 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2219 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2220 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2222 Handled = TRUE;
2223 break;
2224 } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2225 /* Technically texture shader support without register combiners is possible, but not expected to occur
2226 * on real world cards, so for now a fixme should be enough
2228 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
2230 default:
2231 Handled = FALSE;
2234 if (Handled) {
2235 BOOL combineOK = TRUE;
2236 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2237 DWORD op2;
2239 if (isAlpha) {
2240 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP];
2241 } else {
2242 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP];
2245 /* Note: If COMBINE4 in effect can't go back to combine! */
2246 switch (op2) {
2247 case WINED3DTOP_ADDSMOOTH:
2248 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2249 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2250 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2251 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2252 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2253 case WINED3DTOP_MULTIPLYADD:
2254 /* Ignore those implemented in both cases */
2255 switch (op) {
2256 case WINED3DTOP_SELECTARG1:
2257 case WINED3DTOP_SELECTARG2:
2258 combineOK = FALSE;
2259 Handled = FALSE;
2260 break;
2261 default:
2262 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
2263 return;
2268 if (combineOK) {
2269 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
2270 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
2272 return;
2276 /* After all the extensions, if still unhandled, report fixme */
2277 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
2278 #undef GLINFO_LOCATION
2280 #endif
2282 /* Setup this textures matrix according to the texture flags*/
2283 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords)
2285 float mat[16];
2287 glMatrixMode(GL_TEXTURE);
2288 checkGLcall("glMatrixMode(GL_TEXTURE)");
2290 if (flags == WINED3DTTFF_DISABLE) {
2291 glLoadIdentity();
2292 checkGLcall("glLoadIdentity()");
2293 return;
2296 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2297 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2298 return;
2301 memcpy(mat, smat, 16 * sizeof(float));
2303 switch (flags & ~WINED3DTTFF_PROJECTED) {
2304 case WINED3DTTFF_COUNT1: mat[1] = mat[5] = mat[13] = 0;
2305 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2306 default: mat[3] = mat[7] = mat[11] = 0, mat[15] = 1;
2309 if (flags & WINED3DTTFF_PROJECTED) {
2310 switch (flags & ~WINED3DTTFF_PROJECTED) {
2311 case WINED3DTTFF_COUNT2:
2312 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2313 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2314 break;
2315 case WINED3DTTFF_COUNT3:
2316 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2317 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2318 break;
2320 } else if(!calculatedCoords) { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2321 mat[12] = mat[8];
2322 mat[13] = mat[9];
2325 glLoadMatrixf(mat);
2326 checkGLcall("glLoadMatrixf(mat)");
2329 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
2331 /* Convertes a D3D format into a OpenGL configuration format */
2332 int D3DFmtMakeGlCfg(WINED3DFORMAT BackBufferFormat, WINED3DFORMAT StencilBufferFormat, int *attribs, int* nAttribs, BOOL alternate){
2333 #define PUSH1(att) attribs[(*nAttribs)++] = (att);
2334 #define PUSH2(att,value) attribs[(*nAttribs)++] = (att); attribs[(*nAttribs)++] = (value);
2335 /*We need to do some Card specific stuff in here at some point,
2336 D3D now supports floating point format buffers, and there are a number of different OpelGl ways of managing these e.g.
2337 GLX_ATI_pixel_format_float
2339 switch (BackBufferFormat) {
2340 /* color buffer */
2341 case WINED3DFMT_P8:
2342 PUSH2(GLX_RENDER_TYPE, GLX_COLOR_INDEX_BIT);
2343 PUSH2(GLX_BUFFER_SIZE, 8);
2344 PUSH2(GLX_DOUBLEBUFFER, TRUE);
2345 break;
2347 case WINED3DFMT_R3G3B2:
2348 PUSH2(GLX_RENDER_TYPE, GLX_RGBA_BIT);
2349 PUSH2(GLX_RED_SIZE, 3);
2350 PUSH2(GLX_GREEN_SIZE, 3);
2351 PUSH2(GLX_BLUE_SIZE, 2);
2352 break;
2354 case WINED3DFMT_A1R5G5B5:
2355 PUSH2(GLX_ALPHA_SIZE, 1);
2356 case WINED3DFMT_X1R5G5B5:
2357 PUSH2(GLX_RED_SIZE, 5);
2358 PUSH2(GLX_GREEN_SIZE, 5);
2359 PUSH2(GLX_BLUE_SIZE, 5);
2360 break;
2362 case WINED3DFMT_R5G6B5:
2363 PUSH2(GLX_RED_SIZE, 5);
2364 PUSH2(GLX_GREEN_SIZE, 6);
2365 PUSH2(GLX_BLUE_SIZE, 5);
2366 break;
2368 case WINED3DFMT_A4R4G4B4:
2369 PUSH2(GLX_ALPHA_SIZE, 4);
2370 case WINED3DFMT_X4R4G4B4:
2371 PUSH2(GLX_RED_SIZE, 4);
2372 PUSH2(GLX_GREEN_SIZE, 4);
2373 PUSH2(GLX_BLUE_SIZE, 4);
2374 break;
2376 case WINED3DFMT_A8R8G8B8:
2377 PUSH2(GLX_ALPHA_SIZE, 8);
2378 case WINED3DFMT_R8G8B8:
2379 case WINED3DFMT_X8R8G8B8:
2380 PUSH2(GLX_RED_SIZE, 8);
2381 PUSH2(GLX_GREEN_SIZE, 8);
2382 PUSH2(GLX_BLUE_SIZE, 8);
2383 break;
2385 case WINED3DFMT_A2R10G10B10:
2386 PUSH2(GLX_ALPHA_SIZE, 2);
2387 PUSH2(GLX_RED_SIZE, 10);
2388 PUSH2(GLX_GREEN_SIZE, 10);
2389 PUSH2(GLX_BLUE_SIZE, 10);
2390 break;
2392 case WINED3DFMT_A16B16G16R16:
2393 PUSH2(GLX_ALPHA_SIZE, 16);
2394 PUSH2(GLX_RED_SIZE, 16);
2395 PUSH2(GLX_GREEN_SIZE, 16);
2396 PUSH2(GLX_BLUE_SIZE, 16);
2397 break;
2399 default:
2400 FIXME("Unsupported color format: %s\n", debug_d3dformat(BackBufferFormat));
2401 break;
2403 if(!alternate){
2404 switch (StencilBufferFormat) {
2405 case 0:
2406 break;
2408 case WINED3DFMT_D16_LOCKABLE:
2409 case WINED3DFMT_D16:
2410 PUSH2(GLX_DEPTH_SIZE, 16);
2411 break;
2413 case WINED3DFMT_D15S1:
2414 PUSH2(GLX_DEPTH_SIZE, 15);
2415 PUSH2(GLX_STENCIL_SIZE, 1);
2416 /*Does openGl support a 1bit stencil?, I've seen it used elsewhere
2417 e.g. http://www.ks.uiuc.edu/Research/vmd/doxygen/OpenGLDisplayDevice_8C-source.html*/
2418 break;
2420 case WINED3DFMT_D24X8:
2421 PUSH2(GLX_DEPTH_SIZE, 24);
2422 break;
2424 case WINED3DFMT_D24X4S4:
2425 PUSH2(GLX_DEPTH_SIZE, 24);
2426 PUSH2(GLX_STENCIL_SIZE, 4);
2427 break;
2429 case WINED3DFMT_D24S8:
2430 PUSH2(GLX_DEPTH_SIZE, 24);
2431 PUSH2(GLX_STENCIL_SIZE, 8);
2432 break;
2434 case WINED3DFMT_D24FS8:
2435 PUSH2(GLX_DEPTH_SIZE, 24);
2436 PUSH2(GLX_STENCIL_SIZE, 8);
2437 break;
2439 case WINED3DFMT_D32:
2440 PUSH2(GLX_DEPTH_SIZE, 32);
2441 break;
2443 default:
2444 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(StencilBufferFormat));
2445 break;
2448 } else { /* it the device doesn't support the 'exact' format, try to find something close */
2449 switch (StencilBufferFormat) {
2450 case 0:
2451 break;
2453 case WINED3DFMT_D16_LOCKABLE:
2454 case WINED3DFMT_D16:
2455 PUSH2(GLX_DEPTH_SIZE, 1);
2456 break;
2458 case WINED3DFMT_D15S1:
2459 PUSH2(GLX_DEPTH_SIZE, 1);
2460 PUSH2(GLX_STENCIL_SIZE, 1);
2461 /*Does openGl support a 1bit stencil?, I've seen it used elsewhere
2462 e.g. http://www.ks.uiuc.edu/Research/vmd/doxygen/OpenGLDisplayDevice_8C-source.html*/
2463 break;
2465 case WINED3DFMT_D24X8:
2466 PUSH2(GLX_DEPTH_SIZE, 1);
2467 break;
2469 case WINED3DFMT_D24X4S4:
2470 PUSH2(GLX_DEPTH_SIZE, 1);
2471 PUSH2(GLX_STENCIL_SIZE, 1);
2472 break;
2474 case WINED3DFMT_D24S8:
2475 PUSH2(GLX_DEPTH_SIZE, 1);
2476 PUSH2(GLX_STENCIL_SIZE, 1);
2477 break;
2479 case WINED3DFMT_D24FS8:
2480 PUSH2(GLX_DEPTH_SIZE, 1);
2481 PUSH2(GLX_STENCIL_SIZE, 1);
2482 break;
2484 case WINED3DFMT_D32:
2485 PUSH2(GLX_DEPTH_SIZE, 1);
2486 break;
2488 default:
2489 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(StencilBufferFormat));
2490 break;
2494 return *nAttribs;
2497 #undef GLINFO_LOCATION
2499 /* DirectDraw stuff */
2500 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2501 switch(depth) {
2502 case 8: return WINED3DFMT_P8; break;
2503 case 15: return WINED3DFMT_X1R5G5B5; break;
2504 case 16: return WINED3DFMT_R5G6B5; break;
2505 case 24: return WINED3DFMT_R8G8B8; break;
2506 case 32: return WINED3DFMT_X8R8G8B8; break;
2507 default: return WINED3DFMT_UNKNOWN;
2511 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2512 WINED3DMATRIX temp;
2514 /* Now do the multiplication 'by hand'.
2515 I know that all this could be optimised, but this will be done later :-) */
2516 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);
2517 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);
2518 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);
2519 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);
2521 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);
2522 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);
2523 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);
2524 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);
2526 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);
2527 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);
2528 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);
2529 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);
2531 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);
2532 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);
2533 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);
2534 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);
2536 /* And copy the new matrix in the good storage.. */
2537 memcpy(dest, &temp, 16 * sizeof(float));
2540 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2541 DWORD size = 0;
2542 int i;
2543 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2545 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2546 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2547 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2548 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2549 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2550 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2551 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2552 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2553 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2554 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2555 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2556 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2557 default: ERR("Unexpected position mask\n");
2559 for (i = 0; i < numTextures; i++) {
2560 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2563 return size;
2566 /***********************************************************************
2567 * CalculateTexRect
2569 * Calculates the dimensions of the opengl texture used for blits.
2570 * Handled oversized opengl textures and updates the source rectangle
2571 * accordingly
2573 * Params:
2574 * This: Surface to operate on
2575 * Rect: Requested rectangle
2577 * Returns:
2578 * TRUE if the texture part can be loaded,
2579 * FALSE otherwise
2581 *********************************************************************/
2582 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
2584 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
2585 int x1 = Rect->left, x2 = Rect->right;
2586 int y1 = Rect->top, y2 = Rect->bottom;
2587 GLint maxSize = GL_LIMITS(texture_size);
2589 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2590 Rect->left, Rect->top, Rect->right, Rect->bottom);
2592 /* The sizes might be reversed */
2593 if(Rect->left > Rect->right) {
2594 x1 = Rect->right;
2595 x2 = Rect->left;
2597 if(Rect->top > Rect->bottom) {
2598 y1 = Rect->bottom;
2599 y2 = Rect->top;
2602 /* No oversized texture? This is easy */
2603 if(!(This->Flags & SFLAG_OVERSIZE)) {
2604 /* Which rect from the texture do I need? */
2605 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2606 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2607 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2608 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2610 return TRUE;
2611 } else {
2612 /* Check if we can succeed at all */
2613 if( (x2 - x1) > maxSize ||
2614 (y2 - y1) > maxSize ) {
2615 TRACE("Requested rectangle is too large for gl\n");
2616 return FALSE;
2619 /* A part of the texture has to be picked. First, check if
2620 * some texture part is loaded already, if yes try to re-use it.
2621 * If the texture is dirty, or the part can't be used,
2622 * re-position the part to load
2624 if(This->Flags & SFLAG_INTEXTURE) {
2625 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2626 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2627 /* Ok, the rectangle is ok, re-use it */
2628 TRACE("Using existing gl Texture\n");
2629 } else {
2630 /* Rectangle is not ok, dirtify the texture to reload it */
2631 TRACE("Dirtifying texture to force reload\n");
2632 This->Flags &= ~SFLAG_INTEXTURE;
2636 /* Now if we are dirty(no else if!) */
2637 if(!(This->Flags & SFLAG_INTEXTURE)) {
2638 /* Set the new rectangle. Use the following strategy:
2639 * 1) Use as big textures as possible.
2640 * 2) Place the texture part in the way that the requested
2641 * part is in the middle of the texture(well, almost)
2642 * 3) If the texture is moved over the edges of the
2643 * surface, replace it nicely
2644 * 4) If the coord is not limiting the texture size,
2645 * use the whole size
2647 if((This->pow2Width) > maxSize) {
2648 This->glRect.left = x1 - maxSize / 2;
2649 if(This->glRect.left < 0) {
2650 This->glRect.left = 0;
2652 This->glRect.right = This->glRect.left + maxSize;
2653 if(This->glRect.right > This->currentDesc.Width) {
2654 This->glRect.right = This->currentDesc.Width;
2655 This->glRect.left = This->glRect.right - maxSize;
2657 } else {
2658 This->glRect.left = 0;
2659 This->glRect.right = This->pow2Width;
2662 if(This->pow2Height > maxSize) {
2663 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2664 if(This->glRect.top < 0) This->glRect.top = 0;
2665 This->glRect.bottom = This->glRect.left + maxSize;
2666 if(This->glRect.bottom > This->currentDesc.Height) {
2667 This->glRect.bottom = This->currentDesc.Height;
2668 This->glRect.top = This->glRect.bottom - maxSize;
2670 } else {
2671 This->glRect.top = 0;
2672 This->glRect.bottom = This->pow2Height;
2674 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2675 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2678 /* Re-calculate the rect to draw */
2679 Rect->left -= This->glRect.left;
2680 Rect->right -= This->glRect.left;
2681 Rect->top -= This->glRect.top;
2682 Rect->bottom -= This->glRect.top;
2684 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2685 * or the pow2Width / pow2Height of the surface
2687 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2688 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2689 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2690 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2692 return TRUE;
2694 #undef GLINFO_LOCATION
2696 /* Hash table functions */
2698 hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
2700 hash_table_t *table;
2701 unsigned int initial_size = 8;
2703 table = HeapAlloc(GetProcessHeap(), 0, sizeof(hash_table_t) + (initial_size * sizeof(struct list)));
2704 if (!table)
2706 ERR("Failed to allocate table, returning NULL.\n");
2707 return NULL;
2710 table->hash_function = hash_function;
2711 table->compare_function = compare_function;
2713 table->grow_size = initial_size - (initial_size >> 2);
2714 table->shrink_size = 0;
2716 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
2717 if (!table->buckets)
2719 ERR("Failed to allocate table buckets, returning NULL.\n");
2720 HeapFree(GetProcessHeap(), 0, table);
2721 return NULL;
2723 table->bucket_count = initial_size;
2725 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(hash_table_entry_t));
2726 if (!table->entries)
2728 ERR("Failed to allocate table entries, returning NULL.\n");
2729 HeapFree(GetProcessHeap(), 0, table->buckets);
2730 HeapFree(GetProcessHeap(), 0, table);
2731 return NULL;
2733 table->entry_count = 0;
2735 list_init(&table->free_entries);
2736 table->count = 0;
2738 return table;
2741 void hash_table_destroy(hash_table_t *table)
2743 unsigned int i = 0;
2745 for (i = 0; i < table->entry_count; ++i)
2747 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
2750 HeapFree(GetProcessHeap(), 0, table->entries);
2751 HeapFree(GetProcessHeap(), 0, table->buckets);
2752 HeapFree(GetProcessHeap(), 0, table);
2755 static inline hash_table_entry_t *hash_table_get_by_idx(hash_table_t *table, void *key, unsigned int idx)
2757 hash_table_entry_t *entry;
2759 if (table->buckets[idx].next)
2760 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), hash_table_entry_t, entry)
2761 if (table->compare_function(entry->key, key)) return entry;
2763 return NULL;
2766 static BOOL hash_table_resize(hash_table_t *table, unsigned int new_bucket_count)
2768 unsigned int new_entry_count = 0;
2769 hash_table_entry_t *new_entries;
2770 struct list *new_buckets;
2771 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
2772 unsigned int i;
2774 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
2775 if (!new_buckets)
2777 ERR("Failed to allocate new buckets, returning FALSE.\n");
2778 return FALSE;
2781 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(hash_table_entry_t));
2782 if (!new_entries)
2784 ERR("Failed to allocate new entries, returning FALSE.\n");
2785 HeapFree(GetProcessHeap(), 0, new_buckets);
2786 return FALSE;
2789 for (i = 0; i < table->bucket_count; ++i)
2791 if (table->buckets[i].next)
2793 hash_table_entry_t *entry, *entry2;
2795 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], hash_table_entry_t, entry)
2797 int j;
2798 hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
2799 *new_entry = *entry;
2801 j = new_entry->hash & (new_bucket_count - 1);
2803 if (!new_buckets[j].next) list_init(&new_buckets[j]);
2804 list_add_head(&new_buckets[j], &new_entry->entry);
2809 HeapFree(GetProcessHeap(), 0, table->buckets);
2810 table->buckets = new_buckets;
2812 HeapFree(GetProcessHeap(), 0, table->entries);
2813 table->entries = new_entries;
2815 table->entry_count = new_entry_count;
2816 list_init(&table->free_entries);
2818 table->bucket_count = new_bucket_count;
2819 table->grow_size = grow_size;
2820 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
2822 return TRUE;
2825 void hash_table_put(hash_table_t *table, void *key, void *value)
2827 unsigned int idx;
2828 unsigned int hash;
2829 hash_table_entry_t *entry;
2831 hash = table->hash_function(key);
2832 idx = hash & (table->bucket_count - 1);
2833 entry = hash_table_get_by_idx(table, key, idx);
2835 if (entry)
2837 HeapFree(GetProcessHeap(), 0, key);
2838 entry->value = value;
2840 if (!value)
2842 HeapFree(GetProcessHeap(), 0, entry->key);
2843 entry->key = NULL;
2845 /* Remove the entry */
2846 list_remove(&entry->entry);
2847 list_add_head(&table->free_entries, &entry->entry);
2849 --table->count;
2851 /* Shrink if necessary */
2852 if (table->count < table->shrink_size) {
2853 if (!hash_table_resize(table, table->bucket_count >> 1))
2855 ERR("Failed to shrink the table...\n");
2860 return;
2863 if (!value) return;
2865 /* Grow if necessary */
2866 if (table->count >= table->grow_size)
2868 if (!hash_table_resize(table, table->bucket_count << 1))
2870 ERR("Failed to grow the table, returning.\n");
2871 return;
2874 idx = hash & (table->bucket_count - 1);
2877 /* Find an entry to insert */
2878 if (!list_empty(&table->free_entries))
2880 struct list *elem = list_head(&table->free_entries);
2882 list_remove(elem);
2883 entry = LIST_ENTRY(elem, hash_table_entry_t, entry);
2884 } else {
2885 entry = table->entries + (table->entry_count++);
2888 /* Insert the entry */
2889 entry->key = key;
2890 entry->value = value;
2891 entry->hash = hash;
2892 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
2893 list_add_head(&table->buckets[idx], &entry->entry);
2895 ++table->count;
2898 void hash_table_remove(hash_table_t *table, void *key)
2900 hash_table_put(table, key, NULL);
2903 void *hash_table_get(hash_table_t *table, void *key)
2905 unsigned int idx;
2906 hash_table_entry_t *entry;
2908 idx = table->hash_function(key) & (table->bucket_count - 1);
2909 entry = hash_table_get_by_idx(table, key, idx);
2911 return entry ? entry->value : NULL;