wined3d: Remove resourceStoreCriticalSection.
[wine/hacks.git] / dlls / wined3d / utils.c
blob849eb387156fe3c5987f069d4bce382af1f725cc
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 ((IWineD3DImpl *)(This->wineD3D))->gl_info
32 /*****************************************************************************
33 * Pixel format array
35 static const PixelFormatDesc formats[] = {
36 /*{WINED3DFORMAT ,alphamask ,redmask ,greenmask ,bluemask ,bpp ,isFourcc ,internal ,format ,type }*/
37 {WINED3DFMT_UNKNOWN ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,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 },
40 {WINED3DFMT_YUY2 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 },
41 {WINED3DFMT_DXT1 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,GL_RGBA ,GL_UNSIGNED_BYTE },
42 {WINED3DFMT_DXT2 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,GL_RGBA ,GL_UNSIGNED_BYTE },
43 {WINED3DFMT_DXT3 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,GL_RGBA ,GL_UNSIGNED_BYTE },
44 {WINED3DFMT_DXT4 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,GL_RGBA ,GL_UNSIGNED_BYTE },
45 {WINED3DFMT_DXT5 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,GL_RGBA ,GL_UNSIGNED_BYTE },
46 {WINED3DFMT_MULTI2_ARGB8,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 },
47 {WINED3DFMT_G8R8_G8B8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 },
48 {WINED3DFMT_R8G8_B8G8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 },
49 /* IEEE formats */
50 {WINED3DFMT_R32F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_RGB32F_ARB ,GL_RED ,GL_FLOAT },
51 {WINED3DFMT_G32R32F ,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,0 ,0 ,0 },
52 {WINED3DFMT_A32B32G32R32F,0x0 ,0x0 ,0x0 ,0x0 ,16 ,FALSE ,GL_RGBA32F_ARB ,GL_RGBA ,GL_FLOAT },
53 /* Hmm? */
54 {WINED3DFMT_CxV8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,0 ,0 ,0 },
55 /* Float */
56 {WINED3DFMT_R16F ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_RGB16F_ARB ,GL_RED ,GL_HALF_FLOAT_ARB },
57 {WINED3DFMT_G16R16F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 },
58 {WINED3DFMT_A16B16G16R16F,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,GL_RGBA16F_ARB ,GL_RGBA ,GL_HALF_FLOAT_ARB },
59 /* Palettized formats */
60 {WINED3DFMT_A8P8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,0 ,0 ,0 },
61 {WINED3DFMT_P8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,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_BGR ,GL_UNSIGNED_BYTE },
64 {WINED3DFMT_A8R8G8B8 ,0xff000000 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,FALSE ,GL_RGBA8 ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
65 {WINED3DFMT_X8R8G8B8 ,0x0 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,FALSE ,GL_RGB8 ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
66 {WINED3DFMT_R5G6B5 ,0x0 ,0x0000F800 ,0x000007e0 ,0x0000001f ,2 ,FALSE ,GL_RGB5 ,GL_RGB ,GL_UNSIGNED_SHORT_5_6_5 },
67 {WINED3DFMT_X1R5G5B5 ,0x0 ,0x00007c00 ,0x000003e0 ,0x0000001f ,2 ,FALSE ,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_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV },
69 {WINED3DFMT_A4R4G4B4 ,0x0000f000 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,FALSE ,GL_RGBA4 ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
70 {WINED3DFMT_R3G3B2 ,0x0 ,0x000000e0 ,0x0000001c ,0x00000003 ,1 ,FALSE ,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_ALPHA ,GL_ALPHA },
72 {WINED3DFMT_A8R3G3B2 ,0x0000ff00 ,0x000000e0 ,0x0000001c ,0x00000003 ,2 ,FALSE ,0 ,0 ,0 },
73 {WINED3DFMT_X4R4G4B4 ,0x0 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,FALSE ,GL_RGB4 ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
74 {WINED3DFMT_A2B10G10R10 ,0xb0000000 ,0x000003ff ,0x000ffc00 ,0x3ff00000 ,4 ,FALSE ,GL_RGB ,GL_RGBA ,GL_UNSIGNED_INT_2_10_10_10_REV },
75 {WINED3DFMT_A8B8G8R8 ,0xff000000 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,FALSE ,GL_RGBA8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
76 {WINED3DFMT_X8B8G8R8 ,0x0 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,FALSE ,GL_RGB8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
77 {WINED3DFMT_G16R16 ,0x0 ,0x0000ffff ,0xffff0000 ,0x0 ,4 ,FALSE ,0 ,0 ,0 },
78 {WINED3DFMT_A2R10G10B10 ,0xb0000000 ,0x3ff00000 ,0x000ffc00 ,0x000003ff ,4 ,FALSE ,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_RGBA ,GL_UNSIGNED_SHORT },
80 /* Luminance */
81 {WINED3DFMT_L8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,GL_LUMINANCE8 ,GL_LUMINANCE ,GL_UNSIGNED_BYTE },
82 {WINED3DFMT_A8L8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_LUMINANCE8_ALPHA8 ,GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE },
83 {WINED3DFMT_A4L4 ,0x000000f0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,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_DSDT_NV ,GL_BYTE },
86 {WINED3DFMT_L6V5U5 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,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_DSDT_MAG_INTENSITY_NV,GL_BYTE },
88 {WINED3DFMT_Q8W8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_SIGNED_RGBA8_NV ,GL_RGBA ,GL_BYTE },
89 {WINED3DFMT_V16U16 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_SIGNED_HILO16_NV ,GL_HILO_NV ,GL_SHORT },
90 {WINED3DFMT_W11V11U10 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 },
91 {WINED3DFMT_A2W10V10U10 ,0xb0000000 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 },
92 /* Depth stencil formats */
93 {WINED3DFMT_D16_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,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_COMPONENT,GL_UNSIGNED_INT },
95 {WINED3DFMT_D15S1 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,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_COMPONENT,GL_UNSIGNED_INT },
97 {WINED3DFMT_D24X8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,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_COMPONENT,GL_UNSIGNED_INT },
99 {WINED3DFMT_D16 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT24_ARB,GL_DEPTH_COMPONENT,GL_UNSIGNED_SHORT },
100 {WINED3DFMT_L16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_LUMINANCE16_EXT ,GL_LUMINANCE ,GL_UNSIGNED_SHORT },
101 {WINED3DFMT_D32F_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT32_ARB,GL_DEPTH_COMPONENT,GL_FLOAT },
102 {WINED3DFMT_D24FS8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,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 },
105 {WINED3DFMT_INDEX16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,0 ,0 ,0 },
106 {WINED3DFMT_INDEX32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 },
107 {WINED3DFMT_Q16W16V16U16,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,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 /*****************************************************************************
700 * Useful functions mapping GL <-> D3D values
702 GLenum StencilOp(DWORD op) {
703 switch(op) {
704 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
705 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
706 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
707 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
708 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
709 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
710 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
711 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
712 default:
713 FIXME("Unrecognized stencil op %d\n", op);
714 return GL_KEEP;
718 GLenum CompareFunc(DWORD func) {
719 switch ((WINED3DCMPFUNC)func) {
720 case WINED3DCMP_NEVER : return GL_NEVER;
721 case WINED3DCMP_LESS : return GL_LESS;
722 case WINED3DCMP_EQUAL : return GL_EQUAL;
723 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
724 case WINED3DCMP_GREATER : return GL_GREATER;
725 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
726 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
727 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
728 default:
729 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
730 return 0;
734 static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) {
735 switch (d3dta) {
736 case WINED3DTA_DIFFUSE:
737 return GL_PRIMARY_COLOR_NV;
739 case WINED3DTA_CURRENT:
740 if (stage) return GL_SPARE0_NV;
741 else return GL_PRIMARY_COLOR_NV;
743 case WINED3DTA_TEXTURE:
744 if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx;
745 else return GL_PRIMARY_COLOR_NV;
747 case WINED3DTA_TFACTOR:
748 return GL_CONSTANT_COLOR0_NV;
750 case WINED3DTA_SPECULAR:
751 return GL_SECONDARY_COLOR_NV;
753 case WINED3DTA_TEMP:
754 /* TODO: Support WINED3DTSS_RESULTARG */
755 FIXME("WINED3DTA_TEMP, not properly supported.\n");
756 return GL_SPARE1_NV;
758 case WINED3DTA_CONSTANT:
759 /* TODO: Support per stage constants (WINED3DTSS_CONSTANT, NV_register_combiners2) */
760 FIXME("WINED3DTA_CONSTANT, not properly supported.\n");
761 return GL_CONSTANT_COLOR1_NV;
763 default:
764 FIXME("Unrecognized texture arg %#x\n", d3dta);
765 return GL_TEXTURE;
769 static GLenum invert_mapping(GLenum mapping) {
770 if (mapping == GL_UNSIGNED_INVERT_NV) return GL_SIGNED_IDENTITY_NV;
771 else if (mapping == GL_SIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV;
773 FIXME("Unhandled mapping %#x\n", mapping);
774 return mapping;
777 static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) {
778 /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should
779 * be used. */
780 if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV;
781 else *mapping = GL_SIGNED_IDENTITY_NV;
783 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input
784 * should be used for all input components. */
785 if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA;
786 else *component_usage = GL_RGB;
788 *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx);
791 typedef struct {
792 GLenum input[3];
793 GLenum mapping[3];
794 GLenum component_usage[3];
795 } tex_op_args;
797 static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
798 if (op == WINED3DTOP_DISABLE) return FALSE;
799 if (This->stateBlock->textures[stage]) return FALSE;
801 if (arg1 == WINED3DTA_TEXTURE && op != WINED3DTOP_SELECTARG2) return TRUE;
802 if (arg2 == WINED3DTA_TEXTURE && op != WINED3DTOP_SELECTARG1) return TRUE;
803 if (arg3 == WINED3DTA_TEXTURE && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
805 return FALSE;
808 void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx) {
809 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface;
810 tex_op_args tex_op_args = {{0}, {0}, {0}};
811 GLenum portion = is_alpha ? GL_ALPHA : GL_RGB;
812 GLenum target = GL_COMBINER0_NV + stage;
814 TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
815 stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx);
817 /* If a texture stage references an invalid texture unit the stage just
818 * passes through the result from the previous stage */
819 if (is_invalid_op(This, stage, op, arg1, arg2, arg3)) {
820 arg1 = WINED3DTA_CURRENT;
821 op = WINED3DTOP_SELECTARG1;
824 get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0],
825 &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx);
826 get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1],
827 &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx);
828 get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2],
829 &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx);
832 /* This is called by a state handler which has the gl lock held and a context for the thread */
834 switch(op)
836 case WINED3DTOP_DISABLE:
837 /* Only for alpha */
838 if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n");
839 /* Input, prev_alpha*1 */
840 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
841 GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
842 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
843 GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
845 /* Output */
846 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
847 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
848 break;
850 case WINED3DTOP_SELECTARG1:
851 case WINED3DTOP_SELECTARG2:
852 /* Input, arg*1 */
853 if (op == WINED3DTOP_SELECTARG1) {
854 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
855 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
856 } else {
857 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
858 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
860 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
861 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
863 /* Output */
864 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
865 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
866 break;
868 case WINED3DTOP_MODULATE:
869 case WINED3DTOP_MODULATE2X:
870 case WINED3DTOP_MODULATE4X:
871 /* Input, arg1*arg2 */
872 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
873 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
874 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
875 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
877 /* Output */
878 if (op == WINED3DTOP_MODULATE) {
879 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
880 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
881 } else if (op == WINED3DTOP_MODULATE2X) {
882 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
883 GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
884 } else if (op == WINED3DTOP_MODULATE4X) {
885 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
886 GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
888 break;
890 case WINED3DTOP_ADD:
891 case WINED3DTOP_ADDSIGNED:
892 case WINED3DTOP_ADDSIGNED2X:
893 /* Input, arg1*1+arg2*1 */
894 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
895 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
896 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
897 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
898 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
899 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
900 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
901 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
903 /* Output */
904 if (op == WINED3DTOP_ADD) {
905 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
906 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
907 } else if (op == WINED3DTOP_ADDSIGNED) {
908 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
909 GL_SPARE0_NV, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
910 } else if (op == WINED3DTOP_ADDSIGNED2X) {
911 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
912 GL_SPARE0_NV, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
914 break;
916 case WINED3DTOP_SUBTRACT:
917 /* Input, arg1*1+-arg2*1 */
918 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
919 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
920 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
921 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
922 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
923 tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1]));
924 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
925 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
927 /* Output */
928 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
929 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
930 break;
932 case WINED3DTOP_ADDSMOOTH:
933 /* Input, arg1*1+(1-arg1)*arg2 */
934 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
935 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
936 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
937 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
938 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
939 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
940 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
941 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
943 /* Output */
944 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
945 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
946 break;
948 case WINED3DTOP_BLENDDIFFUSEALPHA:
949 case WINED3DTOP_BLENDTEXTUREALPHA:
950 case WINED3DTOP_BLENDFACTORALPHA:
951 case WINED3DTOP_BLENDTEXTUREALPHAPM:
952 case WINED3DTOP_BLENDCURRENTALPHA:
954 GLenum alpha_src = GL_PRIMARY_COLOR_NV;
955 if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx);
956 else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
957 else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx);
958 else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
959 else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx);
960 else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op));
962 /* Input, arg1*alpha_src+arg2*(1-alpha_src) */
963 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
964 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
965 if (op == WINED3DTOP_BLENDTEXTUREALPHAPM)
967 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
968 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
969 } else {
970 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
971 alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
973 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
974 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
975 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
976 alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
978 /* Output */
979 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
980 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
981 break;
984 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
985 /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */
986 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n");
987 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
988 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
989 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
990 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
991 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
992 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
993 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
994 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
996 /* Output */
997 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
998 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
999 break;
1001 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1002 /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */
1003 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n");
1004 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1005 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1006 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1007 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1008 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1009 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1010 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1011 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1013 /* Output */
1014 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1015 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1016 break;
1018 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1019 /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */
1020 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n");
1021 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1022 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA));
1023 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1024 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1025 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1026 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1027 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1028 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1030 /* Output */
1031 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1032 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1033 break;
1035 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1036 /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */
1037 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n");
1038 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1039 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1040 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1041 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1042 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1043 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1044 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1045 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1047 /* Output */
1048 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1049 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1050 break;
1052 case WINED3DTOP_DOTPRODUCT3:
1053 /* Input, arg1 . arg2 */
1054 /* FIXME: DX7 uses a different calculation? */
1055 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1056 tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0]));
1057 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1058 tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1]));
1060 /* Output */
1061 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1062 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE));
1063 break;
1065 case WINED3DTOP_MULTIPLYADD:
1066 /* Input, arg1*1+arg2*arg3 */
1067 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1068 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1069 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1070 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1071 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1072 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1073 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1074 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1076 /* Output */
1077 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1078 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1079 break;
1081 case WINED3DTOP_LERP:
1082 /* Input, arg1*arg2+(1-arg1)*arg3 */
1083 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1084 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1085 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1086 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1087 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1088 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1089 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1090 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1092 /* Output */
1093 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1094 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1095 break;
1097 default:
1098 FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1099 stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
1102 checkGLcall("set_tex_op_nvrc()\n");
1106 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
1107 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
1108 * input should be used for all input components. The WINED3DTA_COMPLEMENT
1109 * flag specifies the complement of the input should be used. */
1110 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
1111 BOOL complement = arg & WINED3DTA_COMPLEMENT;
1113 /* Calculate the operand */
1114 if (complement) {
1115 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
1116 else *operand = GL_ONE_MINUS_SRC_COLOR;
1117 } else {
1118 if (from_alpha) *operand = GL_SRC_ALPHA;
1119 else *operand = GL_SRC_COLOR;
1122 /* Calculate the source */
1123 switch (arg & WINED3DTA_SELECTMASK) {
1124 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
1125 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
1126 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
1127 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
1128 case WINED3DTA_SPECULAR:
1130 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
1131 * 'Secondary color' and isn't supported until base GL supports it
1132 * There is no concept of temp registers as far as I can tell
1134 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
1135 *source = GL_TEXTURE;
1136 break;
1137 default:
1138 FIXME("Unrecognized texture arg %#x\n", arg);
1139 *source = GL_TEXTURE;
1140 break;
1144 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
1145 #if defined (GL_VERSION_1_3)
1146 # define useext(A) A
1147 # define combine_ext 1
1148 #elif defined (GL_EXT_texture_env_combine)
1149 # define useext(A) A##_EXT
1150 # define combine_ext 1
1151 #elif defined (GL_ARB_texture_env_combine)
1152 # define useext(A) A##_ARB
1153 # define combine_ext 1
1154 #else
1155 # undef combine_ext
1156 #endif
1158 #if !defined(combine_ext)
1159 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1161 FIXME("Requires opengl combine extensions to work\n");
1162 return;
1164 #else
1165 /* Setup the texture operations texture stage states */
1166 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1168 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
1169 GLenum src1, src2, src3;
1170 GLenum opr1, opr2, opr3;
1171 GLenum comb_target;
1172 GLenum src0_target, src1_target, src2_target;
1173 GLenum opr0_target, opr1_target, opr2_target;
1174 GLenum scal_target;
1175 GLenum opr=0, invopr, src3_target, opr3_target;
1176 BOOL Handled = FALSE;
1177 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
1179 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
1181 /* This is called by a state handler which has the gl lock held and a context for the thread */
1183 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
1184 the form (a1 <operation> a2). However, some of the more complex operations
1185 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
1186 in a third parameter called a0. Therefore these are operations of the form
1187 a0 <operation> a1 <operation> a2, ie the new parameter goes to the front.
1189 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
1190 functions below, expect their syntax to differ slightly to those listed in the
1191 manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
1192 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
1194 if (isAlpha) {
1195 comb_target = useext(GL_COMBINE_ALPHA);
1196 src0_target = useext(GL_SOURCE0_ALPHA);
1197 src1_target = useext(GL_SOURCE1_ALPHA);
1198 src2_target = useext(GL_SOURCE2_ALPHA);
1199 opr0_target = useext(GL_OPERAND0_ALPHA);
1200 opr1_target = useext(GL_OPERAND1_ALPHA);
1201 opr2_target = useext(GL_OPERAND2_ALPHA);
1202 scal_target = GL_ALPHA_SCALE;
1204 else {
1205 comb_target = useext(GL_COMBINE_RGB);
1206 src0_target = useext(GL_SOURCE0_RGB);
1207 src1_target = useext(GL_SOURCE1_RGB);
1208 src2_target = useext(GL_SOURCE2_RGB);
1209 opr0_target = useext(GL_OPERAND0_RGB);
1210 opr1_target = useext(GL_OPERAND1_RGB);
1211 opr2_target = useext(GL_OPERAND2_RGB);
1212 scal_target = useext(GL_RGB_SCALE);
1215 /* If a texture stage references an invalid texture unit the stage just
1216 * passes through the result from the previous stage */
1217 if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) {
1218 arg1 = WINED3DTA_CURRENT;
1219 op = WINED3DTOP_SELECTARG1;
1222 /* From MSDN (WINED3DTSS_ALPHAARG1) :
1223 The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage,
1224 then the default argument is WINED3DTA_DIFFUSE.
1225 FIXME? If texture added/removed, may need to reset back as well? */
1226 if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
1227 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
1228 } else {
1229 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
1231 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
1232 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
1234 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
1236 Handled = TRUE; /* Assume will be handled */
1238 /* Other texture operations require special extensions: */
1239 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1240 if (isAlpha) {
1241 opr = GL_SRC_ALPHA;
1242 invopr = GL_ONE_MINUS_SRC_ALPHA;
1243 src3_target = GL_SOURCE3_ALPHA_NV;
1244 opr3_target = GL_OPERAND3_ALPHA_NV;
1245 } else {
1246 opr = GL_SRC_COLOR;
1247 invopr = GL_ONE_MINUS_SRC_COLOR;
1248 src3_target = GL_SOURCE3_RGB_NV;
1249 opr3_target = GL_OPERAND3_RGB_NV;
1251 switch (op) {
1252 case WINED3DTOP_DISABLE: /* Only for alpha */
1253 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1254 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1255 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1256 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1257 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1258 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1259 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1260 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1261 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1262 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1263 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1264 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1265 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1266 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1267 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1268 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1269 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1270 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1271 break;
1272 case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */
1273 case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
1274 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1275 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1276 if (op == WINED3DTOP_SELECTARG1) {
1277 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1278 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1279 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1280 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1281 } else {
1282 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1283 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1284 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1285 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1287 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1288 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1289 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1290 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1291 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1292 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1293 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1294 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1295 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1296 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1297 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1298 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1299 break;
1301 case WINED3DTOP_MODULATE:
1302 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1303 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1304 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1305 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1306 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1307 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1308 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1309 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1310 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1311 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1312 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1313 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1314 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1315 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1316 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1317 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1318 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1319 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1320 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1321 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1322 break;
1323 case WINED3DTOP_MODULATE2X:
1324 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1325 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1326 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1327 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1328 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1329 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1330 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1331 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1332 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1333 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1334 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1335 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1336 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1337 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1338 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1339 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1340 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1341 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1342 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1343 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1344 break;
1345 case WINED3DTOP_MODULATE4X:
1346 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1347 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1348 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1349 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1350 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1351 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1352 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1353 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1354 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1355 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1356 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1357 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1358 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1359 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1360 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1361 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1362 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1363 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1364 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
1365 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
1366 break;
1368 case WINED3DTOP_ADD:
1369 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1370 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1371 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1372 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1373 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1374 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1375 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1376 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1377 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1378 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1379 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1380 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1381 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1382 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1383 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1384 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1385 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1386 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1387 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1388 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1389 break;
1391 case WINED3DTOP_ADDSIGNED:
1392 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1393 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1394 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1395 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1396 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1397 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1398 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1399 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1400 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1401 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1402 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1403 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1404 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1405 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1406 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1407 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1408 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1409 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1410 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1411 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1412 break;
1414 case WINED3DTOP_ADDSIGNED2X:
1415 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1416 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1417 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1418 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1419 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1420 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1421 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1422 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1423 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1424 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1425 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1426 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1427 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1428 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1429 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1430 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1431 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1432 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1433 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1434 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1435 break;
1437 case WINED3DTOP_ADDSMOOTH:
1438 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1439 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1440 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1441 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1442 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1443 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1444 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1445 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1446 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1447 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1448 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1449 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1450 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1451 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1452 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1453 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1454 switch (opr1) {
1455 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1456 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1457 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1458 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1460 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1461 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1462 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1463 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1464 break;
1466 case WINED3DTOP_BLENDDIFFUSEALPHA:
1467 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1468 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1469 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1470 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1471 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1472 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1473 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
1474 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
1475 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1476 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1477 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1478 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1479 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1480 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1481 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
1482 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
1483 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1484 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1485 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1486 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1487 break;
1488 case WINED3DTOP_BLENDTEXTUREALPHA:
1489 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1490 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1491 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1492 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1493 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1494 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1495 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
1496 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
1497 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1498 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1499 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1500 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1501 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1502 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1503 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1504 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1505 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1506 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1507 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1508 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1509 break;
1510 case WINED3DTOP_BLENDFACTORALPHA:
1511 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1512 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1513 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1514 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1515 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1516 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1517 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
1518 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
1519 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1520 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1521 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1522 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1523 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1524 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1525 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
1526 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
1527 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1528 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1529 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1530 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1531 break;
1532 case WINED3DTOP_BLENDTEXTUREALPHAPM:
1533 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1534 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1535 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1536 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1537 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1538 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1539 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1540 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1541 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1542 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1543 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1544 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1545 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1546 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1547 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1548 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1549 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1550 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1551 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1552 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1553 break;
1554 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1555 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1556 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1557 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
1558 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1559 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1560 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
1561 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1562 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1563 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1564 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1565 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
1566 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1567 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1568 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
1569 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1570 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1571 switch (opr) {
1572 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1573 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1575 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1576 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1577 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1578 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1579 break;
1580 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1581 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1582 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1583 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1584 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1585 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1586 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1587 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1588 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1589 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1590 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1591 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1592 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1593 switch (opr1) {
1594 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1595 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1597 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1598 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1599 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1600 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1601 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1602 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1603 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1604 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1605 break;
1606 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1607 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1608 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1609 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1610 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1611 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1612 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1613 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1614 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1615 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1616 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1617 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1618 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1619 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1620 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1621 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1622 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1623 switch (opr1) {
1624 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1625 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1626 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1627 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_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_MODULATEINVCOLOR_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 switch (opr1) {
1640 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1641 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1642 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1643 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1645 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
1646 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
1647 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1648 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1649 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1650 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1651 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1652 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1653 switch (opr1) {
1654 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1655 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1657 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1658 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1659 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1660 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1661 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1662 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1663 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1664 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1665 break;
1666 case WINED3DTOP_MULTIPLYADD:
1667 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1668 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1669 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
1670 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1671 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
1672 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1673 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1674 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1675 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1676 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1677 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1678 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1679 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1680 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1681 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
1682 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
1683 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
1684 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
1685 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1686 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1687 break;
1689 case WINED3DTOP_BUMPENVMAP:
1693 case WINED3DTOP_BUMPENVMAPLUMINANCE:
1695 default:
1696 Handled = FALSE;
1698 if (Handled) {
1699 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
1700 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
1702 return;
1704 } /* GL_NV_texture_env_combine4 */
1706 Handled = TRUE; /* Again, assume handled */
1707 switch (op) {
1708 case WINED3DTOP_DISABLE: /* Only for alpha */
1709 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1710 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1711 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1712 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
1713 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1714 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
1715 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1716 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1717 break;
1718 case WINED3DTOP_SELECTARG1:
1719 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1720 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1721 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1722 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1723 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1724 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1725 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1726 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1727 break;
1728 case WINED3DTOP_SELECTARG2:
1729 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1730 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1731 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1732 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1733 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1734 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1735 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1736 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1737 break;
1738 case WINED3DTOP_MODULATE:
1739 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1740 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1741 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1742 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1743 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1744 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1745 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1746 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1747 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1748 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1749 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1750 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1751 break;
1752 case WINED3DTOP_MODULATE2X:
1753 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1754 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1755 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1756 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1757 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1758 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1759 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1760 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1761 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1762 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1763 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1764 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1765 break;
1766 case WINED3DTOP_MODULATE4X:
1767 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1768 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1769 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1770 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1771 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1772 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1773 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1774 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1775 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1776 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1777 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
1778 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
1779 break;
1780 case WINED3DTOP_ADD:
1781 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1782 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1783 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1784 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1785 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1786 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1787 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1788 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1789 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1790 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1791 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1792 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1793 break;
1794 case WINED3DTOP_ADDSIGNED:
1795 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1796 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
1797 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1798 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1799 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1800 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1801 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1802 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1803 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1804 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1805 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1806 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1807 break;
1808 case WINED3DTOP_ADDSIGNED2X:
1809 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1810 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1811 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1812 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1813 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1814 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1815 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1816 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1817 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1818 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1819 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1820 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1821 break;
1822 case WINED3DTOP_SUBTRACT:
1823 if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
1824 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
1825 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
1826 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1827 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1828 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1829 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1830 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1831 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1832 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1833 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1834 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1835 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1836 } else {
1837 FIXME("This version of opengl does not support GL_SUBTRACT\n");
1839 break;
1841 case WINED3DTOP_BLENDDIFFUSEALPHA:
1842 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1843 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1844 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1845 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1846 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1847 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1848 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1849 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1850 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1851 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1852 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
1853 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
1854 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1855 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1856 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1857 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1858 break;
1859 case WINED3DTOP_BLENDTEXTUREALPHA:
1860 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1861 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1862 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1863 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1864 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1865 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1866 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1867 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1868 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1869 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1870 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
1871 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
1872 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1873 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1874 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1875 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1876 break;
1877 case WINED3DTOP_BLENDFACTORALPHA:
1878 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1879 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1880 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1881 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1882 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1883 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1884 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1885 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1886 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1887 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1888 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
1889 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
1890 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1891 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1892 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1893 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1894 break;
1895 case WINED3DTOP_BLENDCURRENTALPHA:
1896 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1897 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1898 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1899 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1900 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1901 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1902 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1903 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1904 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1905 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1906 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
1907 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
1908 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1909 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1910 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1911 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1912 break;
1913 case WINED3DTOP_DOTPRODUCT3:
1914 if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
1915 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
1916 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
1917 } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
1918 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
1919 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
1920 } else {
1921 FIXME("This version of opengl does not support GL_DOT3\n");
1923 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1924 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1925 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1926 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1927 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1928 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1929 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1930 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1931 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1932 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1933 break;
1934 case WINED3DTOP_LERP:
1935 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1936 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1937 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1938 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1939 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1940 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1941 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1942 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1943 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1944 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1945 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
1946 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
1947 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
1948 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
1949 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1950 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1951 break;
1952 case WINED3DTOP_ADDSMOOTH:
1953 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
1954 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
1955 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
1956 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1957 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1958 switch (opr1) {
1959 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1960 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1961 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1962 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1964 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
1965 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
1966 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
1967 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
1968 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
1969 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
1970 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1971 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1972 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1973 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1974 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1975 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1976 } else
1977 Handled = FALSE;
1978 break;
1979 case WINED3DTOP_BLENDTEXTUREALPHAPM:
1980 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
1981 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
1982 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
1983 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
1984 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
1985 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
1986 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
1987 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
1988 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
1989 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
1990 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
1991 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1992 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1993 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1994 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1995 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1996 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1997 } else
1998 Handled = FALSE;
1999 break;
2000 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2001 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2002 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2003 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2004 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2005 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2006 switch (opr1) {
2007 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2008 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2009 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2010 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2012 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2013 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2014 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2015 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2016 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2017 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2018 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2019 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2020 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2021 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2022 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2023 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2024 } else
2025 Handled = FALSE;
2026 break;
2027 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2028 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2029 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2030 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2031 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2032 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2033 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2034 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2035 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2036 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2037 switch (opr1) {
2038 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2039 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2040 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2041 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2043 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2044 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2045 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2046 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2047 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2048 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2049 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2050 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2051 } else
2052 Handled = FALSE;
2053 break;
2054 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2055 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2056 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2057 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2058 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2059 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2060 switch (opr1) {
2061 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2062 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2063 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2064 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2066 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2067 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2068 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2069 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2070 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2071 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2072 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2073 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2074 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2075 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2076 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2077 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2078 } else
2079 Handled = FALSE;
2080 break;
2081 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2082 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2083 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2084 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2085 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2086 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2087 switch (opr1) {
2088 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2089 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2090 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2091 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2093 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2094 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2095 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2096 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2097 switch (opr1) {
2098 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2099 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2100 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2101 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2103 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2104 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2105 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2106 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2107 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2108 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2109 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2110 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2111 } else
2112 Handled = FALSE;
2113 break;
2114 case WINED3DTOP_MULTIPLYADD:
2115 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2116 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2117 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2118 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2119 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2120 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2121 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2122 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2123 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2124 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2125 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2126 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2127 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2128 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2129 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2130 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2131 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2132 } else
2133 Handled = FALSE;
2134 break;
2135 default:
2136 Handled = FALSE;
2139 if (Handled) {
2140 BOOL combineOK = TRUE;
2141 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2142 DWORD op2;
2144 if (isAlpha) {
2145 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP];
2146 } else {
2147 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP];
2150 /* Note: If COMBINE4 in effect can't go back to combine! */
2151 switch (op2) {
2152 case WINED3DTOP_ADDSMOOTH:
2153 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2154 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2155 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2156 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2157 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2158 case WINED3DTOP_MULTIPLYADD:
2159 /* Ignore those implemented in both cases */
2160 switch (op) {
2161 case WINED3DTOP_SELECTARG1:
2162 case WINED3DTOP_SELECTARG2:
2163 combineOK = FALSE;
2164 Handled = FALSE;
2165 break;
2166 default:
2167 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
2168 return;
2173 if (combineOK) {
2174 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
2175 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
2177 return;
2181 /* After all the extensions, if still unhandled, report fixme */
2182 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
2183 #undef GLINFO_LOCATION
2185 #endif
2187 /* Setup this textures matrix according to the texture flags*/
2188 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords)
2190 float mat[16];
2192 glMatrixMode(GL_TEXTURE);
2193 checkGLcall("glMatrixMode(GL_TEXTURE)");
2195 if (flags == WINED3DTTFF_DISABLE) {
2196 glLoadIdentity();
2197 checkGLcall("glLoadIdentity()");
2198 return;
2201 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2202 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2203 return;
2206 memcpy(mat, smat, 16 * sizeof(float));
2208 switch (flags & ~WINED3DTTFF_PROJECTED) {
2209 case WINED3DTTFF_COUNT1: mat[1] = mat[5] = mat[13] = 0;
2210 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2211 default: mat[3] = mat[7] = mat[11] = 0, mat[15] = 1;
2214 if (flags & WINED3DTTFF_PROJECTED) {
2215 switch (flags & ~WINED3DTTFF_PROJECTED) {
2216 case WINED3DTTFF_COUNT2:
2217 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2218 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2219 break;
2220 case WINED3DTTFF_COUNT3:
2221 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2222 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2223 break;
2225 } else if(!calculatedCoords) { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2226 mat[12] = mat[8];
2227 mat[13] = mat[9];
2230 glLoadMatrixf(mat);
2231 checkGLcall("glLoadMatrixf(mat)");
2234 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
2236 /* Convertes a D3D format into a OpenGL configuration format */
2237 int D3DFmtMakeGlCfg(WINED3DFORMAT BackBufferFormat, WINED3DFORMAT StencilBufferFormat, int *attribs, int* nAttribs, BOOL alternate){
2238 #define PUSH1(att) attribs[(*nAttribs)++] = (att);
2239 #define PUSH2(att,value) attribs[(*nAttribs)++] = (att); attribs[(*nAttribs)++] = (value);
2240 /*We need to do some Card specific stuff in here at some point,
2241 D3D now supports floating point format buffers, and there are a number of different OpelGl ways of managing these e.g.
2242 GLX_ATI_pixel_format_float
2244 switch (BackBufferFormat) {
2245 /* color buffer */
2246 case WINED3DFMT_P8:
2247 PUSH2(GLX_RENDER_TYPE, GLX_COLOR_INDEX_BIT);
2248 PUSH2(GLX_BUFFER_SIZE, 8);
2249 PUSH2(GLX_DOUBLEBUFFER, TRUE);
2250 break;
2252 case WINED3DFMT_R3G3B2:
2253 PUSH2(GLX_RENDER_TYPE, GLX_RGBA_BIT);
2254 PUSH2(GLX_RED_SIZE, 3);
2255 PUSH2(GLX_GREEN_SIZE, 3);
2256 PUSH2(GLX_BLUE_SIZE, 2);
2257 break;
2259 case WINED3DFMT_A1R5G5B5:
2260 PUSH2(GLX_ALPHA_SIZE, 1);
2261 case WINED3DFMT_X1R5G5B5:
2262 PUSH2(GLX_RED_SIZE, 5);
2263 PUSH2(GLX_GREEN_SIZE, 5);
2264 PUSH2(GLX_BLUE_SIZE, 5);
2265 break;
2267 case WINED3DFMT_R5G6B5:
2268 PUSH2(GLX_RED_SIZE, 5);
2269 PUSH2(GLX_GREEN_SIZE, 6);
2270 PUSH2(GLX_BLUE_SIZE, 5);
2271 break;
2273 case WINED3DFMT_A4R4G4B4:
2274 PUSH2(GLX_ALPHA_SIZE, 4);
2275 case WINED3DFMT_X4R4G4B4:
2276 PUSH2(GLX_RED_SIZE, 4);
2277 PUSH2(GLX_GREEN_SIZE, 4);
2278 PUSH2(GLX_BLUE_SIZE, 4);
2279 break;
2281 case WINED3DFMT_A8R8G8B8:
2282 PUSH2(GLX_ALPHA_SIZE, 8);
2283 case WINED3DFMT_R8G8B8:
2284 case WINED3DFMT_X8R8G8B8:
2285 PUSH2(GLX_RED_SIZE, 8);
2286 PUSH2(GLX_GREEN_SIZE, 8);
2287 PUSH2(GLX_BLUE_SIZE, 8);
2288 break;
2290 case WINED3DFMT_A2R10G10B10:
2291 PUSH2(GLX_ALPHA_SIZE, 2);
2292 PUSH2(GLX_RED_SIZE, 10);
2293 PUSH2(GLX_GREEN_SIZE, 10);
2294 PUSH2(GLX_BLUE_SIZE, 10);
2295 break;
2297 case WINED3DFMT_A16B16G16R16:
2298 PUSH2(GLX_ALPHA_SIZE, 16);
2299 PUSH2(GLX_RED_SIZE, 16);
2300 PUSH2(GLX_GREEN_SIZE, 16);
2301 PUSH2(GLX_BLUE_SIZE, 16);
2302 break;
2304 default:
2305 FIXME("Unsupported color format: %s\n", debug_d3dformat(BackBufferFormat));
2306 break;
2308 if(!alternate){
2309 switch (StencilBufferFormat) {
2310 case 0:
2311 break;
2313 case WINED3DFMT_D16_LOCKABLE:
2314 case WINED3DFMT_D16:
2315 PUSH2(GLX_DEPTH_SIZE, 16);
2316 break;
2318 case WINED3DFMT_D15S1:
2319 PUSH2(GLX_DEPTH_SIZE, 15);
2320 PUSH2(GLX_STENCIL_SIZE, 1);
2321 /*Does openGl support a 1bit stencil?, I've seen it used elsewhere
2322 e.g. http://www.ks.uiuc.edu/Research/vmd/doxygen/OpenGLDisplayDevice_8C-source.html*/
2323 break;
2325 case WINED3DFMT_D24X8:
2326 PUSH2(GLX_DEPTH_SIZE, 24);
2327 break;
2329 case WINED3DFMT_D24X4S4:
2330 PUSH2(GLX_DEPTH_SIZE, 24);
2331 PUSH2(GLX_STENCIL_SIZE, 4);
2332 break;
2334 case WINED3DFMT_D24S8:
2335 PUSH2(GLX_DEPTH_SIZE, 24);
2336 PUSH2(GLX_STENCIL_SIZE, 8);
2337 break;
2339 case WINED3DFMT_D24FS8:
2340 PUSH2(GLX_DEPTH_SIZE, 24);
2341 PUSH2(GLX_STENCIL_SIZE, 8);
2342 break;
2344 case WINED3DFMT_D32:
2345 PUSH2(GLX_DEPTH_SIZE, 32);
2346 break;
2348 default:
2349 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(StencilBufferFormat));
2350 break;
2353 } else { /* it the device doesn't support the 'exact' format, try to find something close */
2354 switch (StencilBufferFormat) {
2355 case 0:
2356 break;
2358 case WINED3DFMT_D16_LOCKABLE:
2359 case WINED3DFMT_D16:
2360 PUSH2(GLX_DEPTH_SIZE, 1);
2361 break;
2363 case WINED3DFMT_D15S1:
2364 PUSH2(GLX_DEPTH_SIZE, 1);
2365 PUSH2(GLX_STENCIL_SIZE, 1);
2366 /*Does openGl support a 1bit stencil?, I've seen it used elsewhere
2367 e.g. http://www.ks.uiuc.edu/Research/vmd/doxygen/OpenGLDisplayDevice_8C-source.html*/
2368 break;
2370 case WINED3DFMT_D24X8:
2371 PUSH2(GLX_DEPTH_SIZE, 1);
2372 break;
2374 case WINED3DFMT_D24X4S4:
2375 PUSH2(GLX_DEPTH_SIZE, 1);
2376 PUSH2(GLX_STENCIL_SIZE, 1);
2377 break;
2379 case WINED3DFMT_D24S8:
2380 PUSH2(GLX_DEPTH_SIZE, 1);
2381 PUSH2(GLX_STENCIL_SIZE, 1);
2382 break;
2384 case WINED3DFMT_D24FS8:
2385 PUSH2(GLX_DEPTH_SIZE, 1);
2386 PUSH2(GLX_STENCIL_SIZE, 1);
2387 break;
2389 case WINED3DFMT_D32:
2390 PUSH2(GLX_DEPTH_SIZE, 1);
2391 break;
2393 default:
2394 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(StencilBufferFormat));
2395 break;
2399 return *nAttribs;
2402 #undef GLINFO_LOCATION
2404 /* DirectDraw stuff */
2405 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2406 switch(depth) {
2407 case 8: return WINED3DFMT_P8; break;
2408 case 15: return WINED3DFMT_X1R5G5B5; break;
2409 case 16: return WINED3DFMT_R5G6B5; break;
2410 case 24: return WINED3DFMT_R8G8B8; break;
2411 case 32: return WINED3DFMT_X8R8G8B8; break;
2412 default: return WINED3DFMT_UNKNOWN;
2416 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2417 WINED3DMATRIX temp;
2419 /* Now do the multiplication 'by hand'.
2420 I know that all this could be optimised, but this will be done later :-) */
2421 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);
2422 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);
2423 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);
2424 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);
2426 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);
2427 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);
2428 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);
2429 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);
2431 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);
2432 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);
2433 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);
2434 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);
2436 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);
2437 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);
2438 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);
2439 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);
2441 /* And copy the new matrix in the good storage.. */
2442 memcpy(dest, &temp, 16 * sizeof(float));
2445 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2446 DWORD size = 0;
2447 int i;
2448 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2450 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2451 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2452 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2453 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2454 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2455 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2456 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2457 default: TRACE(" matrix weighting not handled yet...\n");
2459 for (i = 0; i < numTextures; i++) {
2460 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2463 return size;
2466 /***********************************************************************
2467 * CalculateTexRect
2469 * Calculates the dimensions of the opengl texture used for blits.
2470 * Handled oversized opengl textures and updates the source rectangle
2471 * accordingly
2473 * Params:
2474 * This: Surface to operate on
2475 * Rect: Requested rectangle
2477 * Returns:
2478 * TRUE if the texture part can be loaded,
2479 * FALSE otherwise
2481 *********************************************************************/
2482 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->resource.wineD3DDevice->wineD3D))->gl_info
2484 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
2485 int x1 = Rect->left, x2 = Rect->right;
2486 int y1 = Rect->top, y2 = Rect->bottom;
2487 GLint maxSize = GL_LIMITS(texture_size);
2489 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2490 Rect->left, Rect->top, Rect->right, Rect->bottom);
2492 /* The sizes might be reversed */
2493 if(Rect->left > Rect->right) {
2494 x1 = Rect->right;
2495 x2 = Rect->left;
2497 if(Rect->top > Rect->bottom) {
2498 y1 = Rect->bottom;
2499 y2 = Rect->top;
2502 /* No oversized texture? This is easy */
2503 if(!(This->Flags & SFLAG_OVERSIZE)) {
2504 /* Which rect from the texture do I need? */
2505 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2506 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2507 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2508 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2510 return TRUE;
2511 } else {
2512 /* Check if we can succeed at all */
2513 if( (x2 - x1) > maxSize ||
2514 (y2 - y1) > maxSize ) {
2515 TRACE("Requested rectangle is too large for gl\n");
2516 return FALSE;
2519 /* A part of the texture has to be picked. First, check if
2520 * some texture part is loaded already, if yes try to re-use it.
2521 * If the texture is dirty, or the part can't be used,
2522 * re-position the part to load
2524 if(This->Flags & SFLAG_INTEXTURE) {
2525 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2526 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2527 /* Ok, the rectangle is ok, re-use it */
2528 TRACE("Using existing gl Texture\n");
2529 } else {
2530 /* Rectangle is not ok, dirtify the texture to reload it */
2531 TRACE("Dirtifying texture to force reload\n");
2532 This->Flags &= ~SFLAG_INTEXTURE;
2536 /* Now if we are dirty(no else if!) */
2537 if(!(This->Flags & SFLAG_INTEXTURE)) {
2538 /* Set the new rectangle. Use the following strategy:
2539 * 1) Use as big textures as possible.
2540 * 2) Place the texture part in the way that the requested
2541 * part is in the middle of the texture(well, almost)
2542 * 3) If the texture is moved over the edges of the
2543 * surface, replace it nicely
2544 * 4) If the coord is not limiting the texture size,
2545 * use the whole size
2547 if((This->pow2Width) > maxSize) {
2548 This->glRect.left = x1 - maxSize / 2;
2549 if(This->glRect.left < 0) {
2550 This->glRect.left = 0;
2552 This->glRect.right = This->glRect.left + maxSize;
2553 if(This->glRect.right > This->currentDesc.Width) {
2554 This->glRect.right = This->currentDesc.Width;
2555 This->glRect.left = This->glRect.right - maxSize;
2557 } else {
2558 This->glRect.left = 0;
2559 This->glRect.right = This->pow2Width;
2562 if(This->pow2Height > maxSize) {
2563 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2564 if(This->glRect.top < 0) This->glRect.top = 0;
2565 This->glRect.bottom = This->glRect.left + maxSize;
2566 if(This->glRect.bottom > This->currentDesc.Height) {
2567 This->glRect.bottom = This->currentDesc.Height;
2568 This->glRect.top = This->glRect.bottom - maxSize;
2570 } else {
2571 This->glRect.top = 0;
2572 This->glRect.bottom = This->pow2Height;
2574 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2575 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2578 /* Re-calculate the rect to draw */
2579 Rect->left -= This->glRect.left;
2580 Rect->right -= This->glRect.left;
2581 Rect->top -= This->glRect.top;
2582 Rect->bottom -= This->glRect.top;
2584 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2585 * or the pow2Width / pow2Height of the surface
2587 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2588 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2589 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2590 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2592 return TRUE;
2594 #undef GLINFO_LOCATION
2596 /* Hash table functions */
2598 hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
2600 hash_table_t *table;
2601 unsigned int initial_size = 8;
2603 table = HeapAlloc(GetProcessHeap(), 0, sizeof(hash_table_t) + (initial_size * sizeof(struct list)));
2604 if (!table)
2606 ERR("Failed to allocate table, returning NULL.\n");
2607 return NULL;
2610 table->hash_function = hash_function;
2611 table->compare_function = compare_function;
2613 table->grow_size = initial_size - (initial_size >> 2);
2614 table->shrink_size = 0;
2616 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
2617 if (!table->buckets)
2619 ERR("Failed to allocate table buckets, returning NULL.\n");
2620 HeapFree(GetProcessHeap(), 0, table);
2621 return NULL;
2623 table->bucket_count = initial_size;
2625 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(hash_table_entry_t));
2626 if (!table->entries)
2628 ERR("Failed to allocate table entries, returning NULL.\n");
2629 HeapFree(GetProcessHeap(), 0, table->buckets);
2630 HeapFree(GetProcessHeap(), 0, table);
2631 return NULL;
2633 table->entry_count = 0;
2635 list_init(&table->free_entries);
2636 table->count = 0;
2638 return table;
2641 void hash_table_destroy(hash_table_t *table)
2643 unsigned int i = 0;
2645 for (i = 0; i < table->entry_count; ++i)
2647 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
2650 HeapFree(GetProcessHeap(), 0, table->entries);
2651 HeapFree(GetProcessHeap(), 0, table->buckets);
2652 HeapFree(GetProcessHeap(), 0, table);
2655 static inline hash_table_entry_t *hash_table_get_by_idx(hash_table_t *table, void *key, unsigned int idx)
2657 hash_table_entry_t *entry;
2659 if (table->buckets[idx].next)
2660 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), hash_table_entry_t, entry)
2661 if (table->compare_function(entry->key, key)) return entry;
2663 return NULL;
2666 static BOOL hash_table_resize(hash_table_t *table, unsigned int new_bucket_count)
2668 unsigned int new_entry_count = 0;
2669 hash_table_entry_t *new_entries;
2670 struct list *new_buckets;
2671 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
2672 unsigned int i;
2674 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
2675 if (!new_buckets)
2677 ERR("Failed to allocate new buckets, returning FALSE.\n");
2678 return FALSE;
2681 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(hash_table_entry_t));
2682 if (!new_entries)
2684 ERR("Failed to allocate new entries, returning FALSE.\n");
2685 HeapFree(GetProcessHeap(), 0, new_buckets);
2686 return FALSE;
2689 for (i = 0; i < table->bucket_count; ++i)
2691 if (table->buckets[i].next)
2693 hash_table_entry_t *entry, *entry2;
2695 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], hash_table_entry_t, entry)
2697 int j;
2698 hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
2699 *new_entry = *entry;
2701 j = new_entry->hash & (new_bucket_count - 1);
2703 if (!new_buckets[j].next) list_init(&new_buckets[j]);
2704 list_add_head(&new_buckets[j], &new_entry->entry);
2709 HeapFree(GetProcessHeap(), 0, table->buckets);
2710 table->buckets = new_buckets;
2712 HeapFree(GetProcessHeap(), 0, table->entries);
2713 table->entries = new_entries;
2715 table->entry_count = new_entry_count;
2716 list_init(&table->free_entries);
2718 table->bucket_count = new_bucket_count;
2719 table->grow_size = grow_size;
2720 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
2722 return TRUE;
2725 void hash_table_put(hash_table_t *table, void *key, void *value)
2727 unsigned int idx;
2728 unsigned int hash;
2729 hash_table_entry_t *entry;
2731 hash = table->hash_function(key);
2732 idx = hash & (table->bucket_count - 1);
2733 entry = hash_table_get_by_idx(table, key, idx);
2735 if (entry)
2737 HeapFree(GetProcessHeap(), 0, key);
2738 entry->value = value;
2740 if (!value)
2742 HeapFree(GetProcessHeap(), 0, entry->key);
2743 entry->key = NULL;
2745 /* Remove the entry */
2746 list_remove(&entry->entry);
2747 list_add_head(&table->free_entries, &entry->entry);
2749 --table->count;
2751 /* Shrink if necessary */
2752 if (table->count < table->shrink_size) {
2753 if (!hash_table_resize(table, table->bucket_count >> 1))
2755 ERR("Failed to shrink the table...\n");
2760 return;
2763 if (!value) return;
2765 /* Grow if necessary */
2766 if (table->count >= table->grow_size)
2768 if (!hash_table_resize(table, table->bucket_count << 1))
2770 ERR("Failed to grow the table, returning.\n");
2771 return;
2774 idx = hash & (table->bucket_count - 1);
2777 /* Find an entry to insert */
2778 if (!list_empty(&table->free_entries))
2780 struct list *elem = list_head(&table->free_entries);
2782 list_remove(elem);
2783 entry = LIST_ENTRY(elem, hash_table_entry_t, entry);
2784 } else {
2785 entry = table->entries + (table->entry_count++);
2788 /* Insert the entry */
2789 entry->key = key;
2790 entry->value = value;
2791 entry->hash = hash;
2792 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
2793 list_add_head(&table->buckets[idx], &entry->entry);
2795 ++table->count;
2798 void hash_table_remove(hash_table_t *table, void *key)
2800 hash_table_put(table, key, NULL);
2803 void *hash_table_get(hash_table_t *table, void *key)
2805 unsigned int idx;
2806 hash_table_entry_t *entry;
2808 idx = table->hash_function(key) & (table->bucket_count - 1);
2809 entry = hash_table_get_by_idx(table, key, idx);
2811 return entry ? entry->value : NULL;