Started implementing support for the SubSystemTib field in the TEB of
[wine] / dlls / d3d8 / utils.c
1 /*
2  * D3D8 utils
3  *
4  * Copyright 2002-2003 Jason Edmeades
5  *                     Raphael Junqueira
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23
24 #include <math.h>
25 #include <stdarg.h>
26
27 #define NONAMELESSUNION
28 #define NONAMELESSSTRUCT
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winuser.h"
32 #include "wingdi.h"
33 #include "wine/debug.h"
34
35 #include "d3d8_private.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
38
39 const char* debug_d3ddevicetype(D3DDEVTYPE devtype) {
40   switch (devtype) {
41 #define DEVTYPE_TO_STR(dev) case dev: return #dev
42     DEVTYPE_TO_STR(D3DDEVTYPE_HAL);
43     DEVTYPE_TO_STR(D3DDEVTYPE_REF);
44     DEVTYPE_TO_STR(D3DDEVTYPE_SW);    
45 #undef DEVTYPE_TO_STR
46   default:
47     FIXME("Unrecognized %u D3DDEVTYPE!\n", devtype);
48     return "unrecognized";
49   }
50 }
51
52 const char* debug_d3dusage(DWORD usage) {
53   switch (usage) {
54 #define D3DUSAGE_TO_STR(u) case u: return #u
55     D3DUSAGE_TO_STR(D3DUSAGE_RENDERTARGET);
56     D3DUSAGE_TO_STR(D3DUSAGE_DEPTHSTENCIL);
57     D3DUSAGE_TO_STR(D3DUSAGE_WRITEONLY);
58     D3DUSAGE_TO_STR(D3DUSAGE_SOFTWAREPROCESSING);
59     D3DUSAGE_TO_STR(D3DUSAGE_DONOTCLIP);
60     D3DUSAGE_TO_STR(D3DUSAGE_POINTS);
61     D3DUSAGE_TO_STR(D3DUSAGE_RTPATCHES);
62     D3DUSAGE_TO_STR(D3DUSAGE_NPATCHES);
63     D3DUSAGE_TO_STR(D3DUSAGE_DYNAMIC);
64 #undef D3DUSAGE_TO_STR
65   case 0: return "none";
66   default:
67     FIXME("Unrecognized %lu Usage!\n", usage);
68     return "unrecognized";
69   }
70 }
71
72 const char* debug_d3dformat(D3DFORMAT fmt) {
73   switch (fmt) {
74 #define FMT_TO_STR(fmt) case fmt: return #fmt
75     FMT_TO_STR(D3DFMT_UNKNOWN);
76     FMT_TO_STR(D3DFMT_R8G8B8);
77     FMT_TO_STR(D3DFMT_A8R8G8B8);
78     FMT_TO_STR(D3DFMT_X8R8G8B8);
79     FMT_TO_STR(D3DFMT_R5G6B5);
80     FMT_TO_STR(D3DFMT_X1R5G5B5);
81     FMT_TO_STR(D3DFMT_A1R5G5B5);
82     FMT_TO_STR(D3DFMT_A4R4G4B4);
83     FMT_TO_STR(D3DFMT_R3G3B2);
84     FMT_TO_STR(D3DFMT_A8);
85     FMT_TO_STR(D3DFMT_A8R3G3B2);
86     FMT_TO_STR(D3DFMT_X4R4G4B4);
87     FMT_TO_STR(D3DFMT_A8P8);
88     FMT_TO_STR(D3DFMT_P8);
89     FMT_TO_STR(D3DFMT_L8);
90     FMT_TO_STR(D3DFMT_A8L8);
91     FMT_TO_STR(D3DFMT_A4L4);
92     FMT_TO_STR(D3DFMT_V8U8);
93     FMT_TO_STR(D3DFMT_L6V5U5);
94     FMT_TO_STR(D3DFMT_X8L8V8U8);
95     FMT_TO_STR(D3DFMT_Q8W8V8U8);
96     FMT_TO_STR(D3DFMT_V16U16);
97     FMT_TO_STR(D3DFMT_W11V11U10);
98     FMT_TO_STR(D3DFMT_UYVY);
99     FMT_TO_STR(D3DFMT_YUY2);
100     FMT_TO_STR(D3DFMT_DXT1);
101     FMT_TO_STR(D3DFMT_DXT2);
102     FMT_TO_STR(D3DFMT_DXT3);
103     FMT_TO_STR(D3DFMT_DXT4);
104     FMT_TO_STR(D3DFMT_DXT5);
105     FMT_TO_STR(D3DFMT_D16_LOCKABLE);
106     FMT_TO_STR(D3DFMT_D32);
107     FMT_TO_STR(D3DFMT_D15S1);
108     FMT_TO_STR(D3DFMT_D24S8);
109     FMT_TO_STR(D3DFMT_D16);
110     FMT_TO_STR(D3DFMT_D24X8);
111     FMT_TO_STR(D3DFMT_D24X4S4);
112     FMT_TO_STR(D3DFMT_VERTEXDATA);
113     FMT_TO_STR(D3DFMT_INDEX16);
114     FMT_TO_STR(D3DFMT_INDEX32);
115 #undef FMT_TO_STR
116   default:
117     FIXME("Unrecognized %u D3DFORMAT!\n", fmt);
118     return "unrecognized";
119   }
120 }
121
122 const char* debug_d3dressourcetype(D3DRESOURCETYPE res) {
123   switch (res) {
124 #define RES_TO_STR(res) case res: return #res;
125     RES_TO_STR(D3DRTYPE_SURFACE);
126     RES_TO_STR(D3DRTYPE_VOLUME);
127     RES_TO_STR(D3DRTYPE_TEXTURE);
128     RES_TO_STR(D3DRTYPE_VOLUMETEXTURE);
129     RES_TO_STR(D3DRTYPE_CUBETEXTURE);
130     RES_TO_STR(D3DRTYPE_VERTEXBUFFER);
131     RES_TO_STR(D3DRTYPE_INDEXBUFFER);
132 #undef  RES_TO_STR
133   default:
134     FIXME("Unrecognized %u D3DRESOURCETYPE!\n", res);
135     return "unrecognized";
136   }
137 }
138
139 const char* debug_d3dprimitivetype(D3DPRIMITIVETYPE PrimitiveType) {
140   switch (PrimitiveType) {
141 #define PRIM_TO_STR(prim) case prim: return #prim;
142     PRIM_TO_STR(D3DPT_POINTLIST);
143     PRIM_TO_STR(D3DPT_LINELIST);
144     PRIM_TO_STR(D3DPT_LINESTRIP);
145     PRIM_TO_STR(D3DPT_TRIANGLELIST);
146     PRIM_TO_STR(D3DPT_TRIANGLESTRIP);
147     PRIM_TO_STR(D3DPT_TRIANGLEFAN);
148 #undef  PRIM_TO_STR
149   default:
150     FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType);
151     return "unrecognized";
152   }
153 }
154
155 const char* debug_d3dpool(D3DPOOL Pool) {
156   switch (Pool) {
157 #define POOL_TO_STR(p) case p: return #p;
158     POOL_TO_STR(D3DPOOL_DEFAULT);
159     POOL_TO_STR(D3DPOOL_MANAGED);
160     POOL_TO_STR(D3DPOOL_SYSTEMMEM);
161     POOL_TO_STR(D3DPOOL_SCRATCH);
162 #undef  POOL_TO_STR
163   default:
164     FIXME("Unrecognized %u D3DPOOL!\n", Pool);
165     return "unrecognized";
166   }
167 }
168
169 const char* debug_d3drenderstate(DWORD state) {
170   switch (state) {
171 #define D3DSTATE_TO_STR(u) case u: return #u
172     D3DSTATE_TO_STR(D3DRS_ZENABLE                   );
173     D3DSTATE_TO_STR(D3DRS_FILLMODE                  );
174     D3DSTATE_TO_STR(D3DRS_SHADEMODE                 );
175     D3DSTATE_TO_STR(D3DRS_LINEPATTERN               );
176     D3DSTATE_TO_STR(D3DRS_ZWRITEENABLE              );
177     D3DSTATE_TO_STR(D3DRS_ALPHATESTENABLE           );
178     D3DSTATE_TO_STR(D3DRS_LASTPIXEL                 );
179     D3DSTATE_TO_STR(D3DRS_SRCBLEND                  );
180     D3DSTATE_TO_STR(D3DRS_DESTBLEND                 );
181     D3DSTATE_TO_STR(D3DRS_CULLMODE                  );
182     D3DSTATE_TO_STR(D3DRS_ZFUNC                     );
183     D3DSTATE_TO_STR(D3DRS_ALPHAREF                  );
184     D3DSTATE_TO_STR(D3DRS_ALPHAFUNC                 );
185     D3DSTATE_TO_STR(D3DRS_DITHERENABLE              );
186     D3DSTATE_TO_STR(D3DRS_ALPHABLENDENABLE          );
187     D3DSTATE_TO_STR(D3DRS_FOGENABLE                 );
188     D3DSTATE_TO_STR(D3DRS_SPECULARENABLE            );
189     D3DSTATE_TO_STR(D3DRS_ZVISIBLE                  );
190     D3DSTATE_TO_STR(D3DRS_FOGCOLOR                  );
191     D3DSTATE_TO_STR(D3DRS_FOGTABLEMODE              );
192     D3DSTATE_TO_STR(D3DRS_FOGSTART                  );
193     D3DSTATE_TO_STR(D3DRS_FOGEND                    );
194     D3DSTATE_TO_STR(D3DRS_FOGDENSITY                );
195     D3DSTATE_TO_STR(D3DRS_EDGEANTIALIAS             );
196     D3DSTATE_TO_STR(D3DRS_ZBIAS                     );
197     D3DSTATE_TO_STR(D3DRS_RANGEFOGENABLE            );
198     D3DSTATE_TO_STR(D3DRS_STENCILENABLE             );
199     D3DSTATE_TO_STR(D3DRS_STENCILFAIL               );
200     D3DSTATE_TO_STR(D3DRS_STENCILZFAIL              );
201     D3DSTATE_TO_STR(D3DRS_STENCILPASS               );
202     D3DSTATE_TO_STR(D3DRS_STENCILFUNC               );
203     D3DSTATE_TO_STR(D3DRS_STENCILREF                );
204     D3DSTATE_TO_STR(D3DRS_STENCILMASK               );
205     D3DSTATE_TO_STR(D3DRS_STENCILWRITEMASK          );
206     D3DSTATE_TO_STR(D3DRS_TEXTUREFACTOR             );
207     D3DSTATE_TO_STR(D3DRS_WRAP0                     );
208     D3DSTATE_TO_STR(D3DRS_WRAP1                     );
209     D3DSTATE_TO_STR(D3DRS_WRAP2                     );
210     D3DSTATE_TO_STR(D3DRS_WRAP3                     );
211     D3DSTATE_TO_STR(D3DRS_WRAP4                     );
212     D3DSTATE_TO_STR(D3DRS_WRAP5                     );
213     D3DSTATE_TO_STR(D3DRS_WRAP6                     );
214     D3DSTATE_TO_STR(D3DRS_WRAP7                     );
215     D3DSTATE_TO_STR(D3DRS_CLIPPING                  );
216     D3DSTATE_TO_STR(D3DRS_LIGHTING                  );
217     D3DSTATE_TO_STR(D3DRS_AMBIENT                   );
218     D3DSTATE_TO_STR(D3DRS_FOGVERTEXMODE             );
219     D3DSTATE_TO_STR(D3DRS_COLORVERTEX               );
220     D3DSTATE_TO_STR(D3DRS_LOCALVIEWER               );
221     D3DSTATE_TO_STR(D3DRS_NORMALIZENORMALS          );
222     D3DSTATE_TO_STR(D3DRS_DIFFUSEMATERIALSOURCE     );
223     D3DSTATE_TO_STR(D3DRS_SPECULARMATERIALSOURCE    );
224     D3DSTATE_TO_STR(D3DRS_AMBIENTMATERIALSOURCE     );
225     D3DSTATE_TO_STR(D3DRS_EMISSIVEMATERIALSOURCE    );
226     D3DSTATE_TO_STR(D3DRS_VERTEXBLEND               );
227     D3DSTATE_TO_STR(D3DRS_CLIPPLANEENABLE           );
228     D3DSTATE_TO_STR(D3DRS_SOFTWAREVERTEXPROCESSING  );
229     D3DSTATE_TO_STR(D3DRS_POINTSIZE                 );
230     D3DSTATE_TO_STR(D3DRS_POINTSIZE_MIN             );
231     D3DSTATE_TO_STR(D3DRS_POINTSPRITEENABLE         );
232     D3DSTATE_TO_STR(D3DRS_POINTSCALEENABLE          );
233     D3DSTATE_TO_STR(D3DRS_POINTSCALE_A              );
234     D3DSTATE_TO_STR(D3DRS_POINTSCALE_B              );
235     D3DSTATE_TO_STR(D3DRS_POINTSCALE_C              );
236     D3DSTATE_TO_STR(D3DRS_MULTISAMPLEANTIALIAS      );
237     D3DSTATE_TO_STR(D3DRS_MULTISAMPLEMASK           );
238     D3DSTATE_TO_STR(D3DRS_PATCHEDGESTYLE            );
239     D3DSTATE_TO_STR(D3DRS_PATCHSEGMENTS             );
240     D3DSTATE_TO_STR(D3DRS_DEBUGMONITORTOKEN         );
241     D3DSTATE_TO_STR(D3DRS_POINTSIZE_MAX             );
242     D3DSTATE_TO_STR(D3DRS_INDEXEDVERTEXBLENDENABLE  );
243     D3DSTATE_TO_STR(D3DRS_COLORWRITEENABLE          );
244     D3DSTATE_TO_STR(D3DRS_TWEENFACTOR               );
245     D3DSTATE_TO_STR(D3DRS_BLENDOP                   );
246     D3DSTATE_TO_STR(D3DRS_POSITIONORDER             );
247     D3DSTATE_TO_STR(D3DRS_NORMALORDER               );
248 #undef D3DSTATE_TO_STR
249   default:
250     FIXME("Unrecognized %lu render state!\n", state);
251     return "unrecognized";
252   }
253 }
254
255 const char* debug_d3dtexturestate(DWORD state) {
256   switch (state) {
257 #define D3DSTATE_TO_STR(u) case u: return #u
258     D3DSTATE_TO_STR(D3DTSS_COLOROP               );
259     D3DSTATE_TO_STR(D3DTSS_COLORARG1             );
260     D3DSTATE_TO_STR(D3DTSS_COLORARG2             );
261     D3DSTATE_TO_STR(D3DTSS_ALPHAOP               );
262     D3DSTATE_TO_STR(D3DTSS_ALPHAARG1             );
263     D3DSTATE_TO_STR(D3DTSS_ALPHAARG2             );
264     D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT00          );
265     D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT01          );
266     D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT10          );
267     D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT11          );
268     D3DSTATE_TO_STR(D3DTSS_TEXCOORDINDEX         );
269     D3DSTATE_TO_STR(D3DTSS_ADDRESSU              );
270     D3DSTATE_TO_STR(D3DTSS_ADDRESSV              );
271     D3DSTATE_TO_STR(D3DTSS_BORDERCOLOR           );
272     D3DSTATE_TO_STR(D3DTSS_MAGFILTER             );
273     D3DSTATE_TO_STR(D3DTSS_MINFILTER             );
274     D3DSTATE_TO_STR(D3DTSS_MIPFILTER             );
275     D3DSTATE_TO_STR(D3DTSS_MIPMAPLODBIAS         );
276     D3DSTATE_TO_STR(D3DTSS_MAXMIPLEVEL           );
277     D3DSTATE_TO_STR(D3DTSS_MAXANISOTROPY         );
278     D3DSTATE_TO_STR(D3DTSS_BUMPENVLSCALE         );
279     D3DSTATE_TO_STR(D3DTSS_BUMPENVLOFFSET        );
280     D3DSTATE_TO_STR(D3DTSS_TEXTURETRANSFORMFLAGS );
281     D3DSTATE_TO_STR(D3DTSS_ADDRESSW              );
282     D3DSTATE_TO_STR(D3DTSS_COLORARG0             );
283     D3DSTATE_TO_STR(D3DTSS_ALPHAARG0             );
284     D3DSTATE_TO_STR(D3DTSS_RESULTARG             );
285 #undef D3DSTATE_TO_STR
286   case 12:
287     /* Note D3DTSS are not consecutive, so skip these */
288     return "unused";
289     break;
290   default:
291     FIXME("Unrecognized %lu texture state!\n", state);
292     return "unrecognized";
293   }
294 }
295
296 /*
297  * Simple utility routines used for dx -> gl mapping of byte formats
298  */
299 int D3DPrimitiveListGetVertexSize(D3DPRIMITIVETYPE PrimitiveType, int iNumPrim) {
300   switch (PrimitiveType) {
301   case D3DPT_POINTLIST:     return iNumPrim;
302   case D3DPT_LINELIST:      return iNumPrim * 2;
303   case D3DPT_LINESTRIP:     return iNumPrim + 1;
304   case D3DPT_TRIANGLELIST:  return iNumPrim * 3;
305   case D3DPT_TRIANGLESTRIP: return iNumPrim + 2;
306   case D3DPT_TRIANGLEFAN:   return iNumPrim + 2;
307   default:
308     FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType);
309     return 0;
310   }
311 }
312
313 int D3DPrimitive2GLenum(D3DPRIMITIVETYPE PrimitiveType) {
314   switch (PrimitiveType) {
315   case D3DPT_POINTLIST:     return GL_POINTS;
316   case D3DPT_LINELIST:      return GL_LINES;
317   case D3DPT_LINESTRIP:     return GL_LINE_STRIP;
318   case D3DPT_TRIANGLELIST:  return GL_TRIANGLES;
319   case D3DPT_TRIANGLESTRIP: return GL_TRIANGLE_STRIP;
320   case D3DPT_TRIANGLEFAN:   return GL_TRIANGLE_FAN;
321   default:
322     FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType);
323     return GL_POLYGON;
324   }
325 }
326
327 int D3DFVFGetSize(D3DFORMAT fvf) {
328   int ret = 0;
329   if      (fvf & D3DFVF_XYZ)    ret += 3 * sizeof(float);
330   else if (fvf & D3DFVF_XYZRHW) ret += 4 * sizeof(float);
331   if (fvf & D3DFVF_NORMAL)      ret += 3 * sizeof(float);
332   if (fvf & D3DFVF_PSIZE)       ret += sizeof(float);
333   if (fvf & D3DFVF_DIFFUSE)     ret += sizeof(DWORD);
334   if (fvf & D3DFVF_SPECULAR)    ret += sizeof(DWORD);
335   /*if (fvf & D3DFVF_TEX1)        ret += 1;*/
336   return ret;
337 }
338
339 GLenum D3DFmt2GLDepthFmt(D3DFORMAT fmt) {
340   switch (fmt) {
341   /* depth/stencil buffer */
342   case D3DFMT_D16_LOCKABLE:
343   case D3DFMT_D16:
344   case D3DFMT_D15S1:
345   case D3DFMT_D24X4S4:
346   case D3DFMT_D24S8:
347   case D3DFMT_D24X8:
348   case D3DFMT_D32:
349     return GL_DEPTH_COMPONENT;
350   default:
351     FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
352   }
353   return 0;
354 }
355
356 GLenum D3DFmt2GLDepthType(D3DFORMAT fmt) {
357   switch (fmt) {
358   /* depth/stencil buffer */
359   case D3DFMT_D15S1:
360   case D3DFMT_D16_LOCKABLE:     
361   case D3DFMT_D16:              
362     return GL_UNSIGNED_SHORT;
363   case D3DFMT_D24X4S4:          
364   case D3DFMT_D24S8:            
365   case D3DFMT_D24X8:            
366   case D3DFMT_D32:              
367     return GL_UNSIGNED_INT;
368   default:
369     FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
370   }
371   return 0;
372 }
373
374 SHORT D3DFmtGetBpp(IDirect3DDevice8Impl* This, D3DFORMAT fmt) {
375     SHORT retVal;
376
377     switch (fmt) {
378     /* color buffer */
379     case D3DFMT_P8:               retVal = 1; break;
380     case D3DFMT_R3G3B2:           retVal = 1; break;
381     case D3DFMT_R5G6B5:           retVal = 2; break;
382     case D3DFMT_X1R5G5B5:         retVal = 2; break;
383     case D3DFMT_A4R4G4B4:         retVal = 2; break;
384     case D3DFMT_X4R4G4B4:         retVal = 2; break;
385     case D3DFMT_A1R5G5B5:         retVal = 2; break;
386     case D3DFMT_R8G8B8:           retVal = 3; break;
387     case D3DFMT_X8R8G8B8:         retVal = 4; break;
388     case D3DFMT_A8R8G8B8:         retVal = 4; break;
389     /* depth/stencil buffer */
390     case D3DFMT_D16_LOCKABLE:     retVal = 2; break;
391     case D3DFMT_D16:              retVal = 2; break;
392     case D3DFMT_D15S1:            retVal = 2; break;
393     case D3DFMT_D24X4S4:          retVal = 4; break;
394     case D3DFMT_D24S8:            retVal = 4; break;
395     case D3DFMT_D24X8:            retVal = 4; break;
396     case D3DFMT_D32:              retVal = 4; break;
397     /* Compressed */                              
398     case D3DFMT_DXT1:             retVal = 1; break; /* Actually  8 bytes per 16 pixels - Special cased later */
399     case D3DFMT_DXT3:             retVal = 1; break; /* Actually 16 bytes per 16 pixels */
400     case D3DFMT_DXT5:             retVal = 1; break; /* Actually 16 bytes per 16 pixels */
401
402     /* unknown */                                 
403     case D3DFMT_UNKNOWN:
404       /* Guess at the highest value of the above */
405       TRACE("D3DFMT_UNKNOWN - Guessing at 4 bytes/pixel %u\n", fmt);
406       retVal = 4;
407       break;
408
409     default:
410       FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
411       retVal = 4;
412     }
413     TRACE("bytes/Pxl for fmt(%u,%s) = %d\n", fmt, debug_d3dformat(fmt), retVal);
414     return retVal;
415 }
416
417 GLint D3DFmt2GLIntFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt) {
418     GLint retVal = 0;
419
420 #if defined(GL_EXT_texture_compression_s3tc)
421     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
422       switch (fmt) {
423       case D3DFMT_DXT1:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
424       case D3DFMT_DXT3:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
425       case D3DFMT_DXT5:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
426       default:
427         /* stupid compiler */
428         break;
429       }
430     }
431 #endif
432
433     if (retVal == 0) {
434         switch (fmt) {
435         case D3DFMT_P8:               retVal = GL_COLOR_INDEX8_EXT; break;
436         case D3DFMT_A8P8:             retVal = GL_COLOR_INDEX8_EXT; break;
437
438         case D3DFMT_A4R4G4B4:         retVal = GL_RGBA4; break;
439         case D3DFMT_A8R8G8B8:         retVal = GL_RGBA8; break;
440         case D3DFMT_X8R8G8B8:         retVal = GL_RGB8; break;
441         case D3DFMT_R8G8B8:           retVal = GL_RGB8; break;
442         case D3DFMT_R5G6B5:           retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
443         case D3DFMT_A1R5G5B5:         retVal = GL_RGB5_A1; break;
444         default:
445             FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
446             retVal = GL_RGB8;
447         }
448     }
449     TRACE("fmt2glintFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
450     return retVal;
451 }
452
453 GLenum D3DFmt2GLFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt) {
454     GLenum retVal = 0;
455
456 #if defined(GL_EXT_texture_compression_s3tc)
457     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
458       switch (fmt) {
459       case D3DFMT_DXT1:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
460       case D3DFMT_DXT3:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
461       case D3DFMT_DXT5:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
462       default:
463         /* stupid compiler */
464         break;
465       }
466     }
467 #endif
468
469     if (retVal == 0) {
470         switch (fmt) {
471         case D3DFMT_P8:               retVal = GL_COLOR_INDEX; break;
472         case D3DFMT_A8P8:             retVal = GL_COLOR_INDEX; break;
473
474         case D3DFMT_A4R4G4B4:         retVal = GL_BGRA; break;
475         case D3DFMT_A8R8G8B8:         retVal = GL_BGRA; break;
476         case D3DFMT_X8R8G8B8:         retVal = GL_BGRA; break;
477         case D3DFMT_R8G8B8:           retVal = GL_BGR; break;
478         case D3DFMT_R5G6B5:           retVal = GL_RGB; break;
479         case D3DFMT_A1R5G5B5:         retVal = GL_BGRA; break;
480         default:
481             FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
482             retVal = GL_BGR;
483         }
484     }
485
486     TRACE("fmt2glFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
487     return retVal;
488 }
489
490 GLenum D3DFmt2GLType(IDirect3DDevice8Impl* This, D3DFORMAT fmt) {
491     GLenum retVal = 0;
492
493 #if defined(GL_EXT_texture_compression_s3tc)
494     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
495       switch (fmt) {
496       case D3DFMT_DXT1:             retVal = 0; break;
497       case D3DFMT_DXT3:             retVal = 0; break;
498       case D3DFMT_DXT5:             retVal = 0; break;
499       default:
500         /* stupid compiler */
501         break;
502       }
503     }
504 #endif
505
506     if (retVal == 0) {
507         switch (fmt) {
508         case D3DFMT_P8:               retVal = GL_UNSIGNED_BYTE; break;
509         case D3DFMT_A8P8:             retVal = GL_UNSIGNED_BYTE; break;
510
511         case D3DFMT_A4R4G4B4:         retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
512         case D3DFMT_A8R8G8B8:         retVal = GL_UNSIGNED_BYTE; break;
513         case D3DFMT_X8R8G8B8:         retVal = GL_UNSIGNED_BYTE; break;
514         case D3DFMT_R5G6B5:           retVal = GL_UNSIGNED_SHORT_5_6_5; break;
515         case D3DFMT_R8G8B8:           retVal = GL_UNSIGNED_BYTE; break;
516         case D3DFMT_A1R5G5B5:         retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
517         default:
518             FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
519             retVal = GL_UNSIGNED_BYTE;
520         }
521     }
522
523     TRACE("fmt2glType for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
524     return retVal;
525 }
526
527 int SOURCEx_RGB_EXT(DWORD arg) {
528     switch(arg) {
529     case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
530     case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
531     case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
532     case D3DTSS_ALPHAARG0:
533     case D3DTSS_ALPHAARG1:
534     case D3DTSS_ALPHAARG2:
535     default:
536         FIXME("Invalid arg %ld\n", arg);
537         return GL_SOURCE0_RGB_EXT;
538     }
539 }
540
541 int OPERANDx_RGB_EXT(DWORD arg) {
542     switch(arg) {
543     case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
544     case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
545     case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
546     case D3DTSS_ALPHAARG0:
547     case D3DTSS_ALPHAARG1:
548     case D3DTSS_ALPHAARG2:
549     default:
550         FIXME("Invalid arg %ld\n", arg);
551         return GL_OPERAND0_RGB_EXT;
552     }
553 }
554
555 int SOURCEx_ALPHA_EXT(DWORD arg) {
556     switch(arg) {
557     case D3DTSS_ALPHAARG0:  return GL_SOURCE2_ALPHA_EXT;
558     case D3DTSS_ALPHAARG1:  return GL_SOURCE0_ALPHA_EXT;
559     case D3DTSS_ALPHAARG2:  return GL_SOURCE1_ALPHA_EXT;
560     case D3DTSS_COLORARG0:
561     case D3DTSS_COLORARG1:
562     case D3DTSS_COLORARG2:
563     default:
564         FIXME("Invalid arg %ld\n", arg);
565         return GL_SOURCE0_ALPHA_EXT;
566     }
567 }
568
569 int OPERANDx_ALPHA_EXT(DWORD arg) {
570     switch(arg) {
571     case D3DTSS_ALPHAARG0:  return GL_OPERAND2_ALPHA_EXT;
572     case D3DTSS_ALPHAARG1:  return GL_OPERAND0_ALPHA_EXT;
573     case D3DTSS_ALPHAARG2:  return GL_OPERAND1_ALPHA_EXT;
574     case D3DTSS_COLORARG0:
575     case D3DTSS_COLORARG1:
576     case D3DTSS_COLORARG2:
577     default:
578         FIXME("Invalid arg %ld\n", arg);
579         return GL_OPERAND0_ALPHA_EXT;
580     }
581 }
582
583 GLenum StencilOp(DWORD op) {
584     switch(op) {                
585     case D3DSTENCILOP_KEEP    : return GL_KEEP;
586     case D3DSTENCILOP_ZERO    : return GL_ZERO;
587     case D3DSTENCILOP_REPLACE : return GL_REPLACE;
588     case D3DSTENCILOP_INCRSAT : return GL_INCR;
589     case D3DSTENCILOP_DECRSAT : return GL_DECR;
590     case D3DSTENCILOP_INVERT  : return GL_INVERT; 
591 #if defined(GL_VERSION_1_4)
592     case D3DSTENCILOP_INCR    : return GL_INCR_WRAP;
593     case D3DSTENCILOP_DECR    : return GL_DECR_WRAP;
594 #elif defined(GL_EXT_stencil_wrap)
595     case D3DSTENCILOP_INCR    : return GL_INCR_WRAP_EXT;
596     case D3DSTENCILOP_DECR    : return GL_DECR_WRAP_EXT;
597 #else
598     case D3DSTENCILOP_INCR    : FIXME("Unsupported stencil op D3DSTENCILOP_INCR\n");
599                                 return GL_INCR; /* Fixme - needs to support wrap */
600     case D3DSTENCILOP_DECR    : FIXME("Unsupported stencil op D3DSTENCILOP_DECR\n");
601                                 return GL_DECR; /* Fixme - needs to support wrap */
602 #endif
603     default:
604         FIXME("Invalid stencil op %ld\n", op);
605         return GL_ALWAYS;
606     }
607 }
608
609 /**
610  * @nodoc: todo
611  */
612 void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand) 
613 {
614   BOOL isAlphaReplicate = FALSE;
615   BOOL isComplement     = FALSE;
616   
617   *operand = GL_SRC_COLOR;
618   *source = GL_TEXTURE;
619   
620   /* Catch alpha replicate */
621   if (iValue & D3DTA_ALPHAREPLICATE) {
622     iValue = iValue & ~D3DTA_ALPHAREPLICATE;
623     isAlphaReplicate = TRUE;
624   }
625   
626   /* Catch Complement */
627   if (iValue & D3DTA_COMPLEMENT) {
628     iValue = iValue & ~D3DTA_COMPLEMENT;
629     isComplement = TRUE;
630   }
631   
632   /* Calculate the operand */
633   if (isAlphaReplicate && !isComplement) {
634     *operand = GL_SRC_ALPHA;
635   } else if (isAlphaReplicate && isComplement) {
636     *operand = GL_ONE_MINUS_SRC_ALPHA;
637   } else if (isComplement) {
638     if (isAlphaArg) {
639       *operand = GL_ONE_MINUS_SRC_ALPHA;
640     } else {
641       *operand = GL_ONE_MINUS_SRC_COLOR;
642     }
643   } else {
644     if (isAlphaArg) {
645       *operand = GL_SRC_ALPHA;
646     } else {
647       *operand = GL_SRC_COLOR;
648     }
649   }
650   
651   /* Calculate the source */
652   switch (iValue & D3DTA_SELECTMASK) {
653   case D3DTA_CURRENT:   *source  = GL_PREVIOUS_EXT;
654     break;
655   case D3DTA_DIFFUSE:   *source  = GL_PRIMARY_COLOR_EXT;
656     break;
657   case D3DTA_TEXTURE:   *source  = GL_TEXTURE;
658     break;
659   case D3DTA_TFACTOR:   *source  = GL_CONSTANT_EXT;
660     break;
661   case D3DTA_SPECULAR:
662     /**
663      * According to the GL_ARB_texture_env_combine specs, SPECULAR is
664      * 'Secondary color' and isn't supported until base GL supports it
665      * There is no concept of temp registers as far as I can tell
666      */
667
668   default:
669     FIXME("Unrecognized or unhandled texture arg %ld\n", iValue);
670     *source = GL_TEXTURE;
671   }
672 }
673
674
675 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
676 #if defined (GL_VERSION_1_3)
677 # define useext(A) A
678 # define combine_ext 1
679 #elif defined (GL_EXT_texture_env_combine)
680 # define useext(A) A##_EXT
681 # define combine_ext 1
682 #elif defined (GL_ARB_texture_env_combine)
683 # define useext(A) A##_ARB
684 # define combine_ext 1
685 #else
686 # undef combine_ext
687 #endif
688
689 #if !defined(combine_ext)
690 void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
691
692         FIXME("Requires opengl combine extensions to work\n");
693         return;
694 }
695 #else
696 /* Setup the texture operations texture stage states */
697 void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
698 {
699         GLenum src1, src2, src3;
700         GLenum opr1, opr2, opr3;
701         GLenum comb_target;
702         GLenum src0_target, src1_target, src2_target;
703         GLenum opr0_target, opr1_target, opr2_target;
704         GLenum scal_target;
705         GLenum opr=0, invopr, src3_target, opr3_target;
706         BOOL Handled = FALSE;
707         ICOM_THIS(IDirect3DDevice8Impl,iface);
708
709         TRACE("Alpha?(%d), Stage:%d Op(%d), a1(%ld), a2(%ld), a3(%ld)\n", isAlpha, Stage, op, arg1, arg2, arg3);
710
711         ENTER_GL();
712
713         /* Note: Operations usually involve two ars, src0 and src1 and are operations of
714            the form (a1 <operation> a2). However, some of the more complex operations
715            take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added  
716            in a third parameter called a0. Therefore these are operations of the form
717            a0 <operation> a1 <operation> a2, ie the new parameter goes to the front.
718            
719            However, below we treat the new (a0) parameter as src2/opr2, so in the actual
720            functions below, expect their syntax to differ slightly to those listed in the
721            manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
722            This affects D3DTOP_MULTIPLYADD and D3DTOP_LERP                               */
723            
724         if (isAlpha) {
725                 comb_target = useext(GL_COMBINE_ALPHA);
726                 src0_target = useext(GL_SOURCE0_ALPHA);
727                 src1_target = useext(GL_SOURCE1_ALPHA);
728                 src2_target = useext(GL_SOURCE2_ALPHA);
729                 opr0_target = useext(GL_OPERAND0_ALPHA);
730                 opr1_target = useext(GL_OPERAND1_ALPHA);
731                 opr2_target = useext(GL_OPERAND2_ALPHA);
732                 scal_target = GL_ALPHA_SCALE;
733         }
734         else {
735                 comb_target = useext(GL_COMBINE_RGB);
736                 src0_target = useext(GL_SOURCE0_RGB);
737                 src1_target = useext(GL_SOURCE1_RGB);
738                 src2_target = useext(GL_SOURCE2_RGB);
739                 opr0_target = useext(GL_OPERAND0_RGB);
740                 opr1_target = useext(GL_OPERAND1_RGB);
741                 opr2_target = useext(GL_OPERAND2_RGB);
742                 scal_target = useext(GL_RGB_SCALE);
743         }
744
745         /* From MSDN (D3DTSS_ALPHAARG1) : 
746            The default argument is D3DTA_TEXTURE. If no texture is set for this stage, 
747                    then the default argument is D3DTA_DIFFUSE.
748                    FIXME? If texture added/removed, may need to reset back as well?    */
749         if (isAlpha && This->StateBlock->textures[Stage] == NULL && arg1 == D3DTA_TEXTURE) {
750             GetSrcAndOpFromValue(D3DTA_DIFFUSE, isAlpha, &src1, &opr1);  
751         } else {
752             GetSrcAndOpFromValue(arg1, isAlpha, &src1, &opr1);
753         }
754         GetSrcAndOpFromValue(arg2, isAlpha, &src2, &opr2);
755         GetSrcAndOpFromValue(arg3, isAlpha, &src3, &opr3);
756         
757         TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
758
759         Handled = TRUE; /* Assume will be handled */
760         switch (op) {
761         case D3DTOP_DISABLE: /* Only for alpha */
762                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
763                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
764                 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
765                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
766                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
767                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
768                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
769                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
770                 break;
771         case D3DTOP_SELECTARG1:
772                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
773                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
774                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
775                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
776                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
777                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
778                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
779                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
780                 break;
781         case D3DTOP_SELECTARG2:
782                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
783                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
784                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
785                 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
786                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
787                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
788                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
789                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
790                 break;
791         case D3DTOP_MODULATE:
792                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
793                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
794                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
795                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
796                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
797                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
798                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
799                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
800                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
801                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
802                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
803                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
804                 break;
805         case D3DTOP_MODULATE2X:
806                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
807                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
808                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
809                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
810                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
811                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
812                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
813                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
814                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
815                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
816                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
817                 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
818                 break;
819         case D3DTOP_MODULATE4X:
820                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
821                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
822                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
823                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
824                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
825                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
826                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
827                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
828                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
829                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
830                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
831                 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
832                 break;
833         case D3DTOP_ADD:
834                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
835                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
836                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
837                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
838                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
839                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
840                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
841                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
842                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
843                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
844                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
845                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
846                 break;
847         case D3DTOP_ADDSIGNED:
848                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
849                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
850                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
851                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
852                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
853                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
854                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
855                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
856                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
857                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
858                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
859                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
860                 break;
861         case D3DTOP_ADDSIGNED2X:
862                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
863                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
864                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
865                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
866                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
867                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
868                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
869                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
870                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
871                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
872                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
873                 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
874                 break;
875         case D3DTOP_SUBTRACT:
876           if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
877                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
878                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
879                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
880                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
881                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
882                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
883                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
884                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
885                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
886                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
887                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
888                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
889           } else {
890                 FIXME("This version of opengl does not support GL_SUBTRACT\n");
891           }
892           break;
893
894         case D3DTOP_BLENDDIFFUSEALPHA:
895                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
896                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
897                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
898                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
899                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
900                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
901                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
902                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
903                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
904                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
905                 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
906                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
907                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
908                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
909                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
910                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
911                 break;
912         case D3DTOP_BLENDTEXTUREALPHA:
913                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
914                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
915                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
916                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
917                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
918                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
919                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
920                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
921                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
922                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
923                 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
924                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
925                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
926                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
927                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
928                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
929                 break;
930         case D3DTOP_BLENDFACTORALPHA:
931                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
932                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
933                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
934                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
935                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
936                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
937                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
938                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
939                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
940                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
941                 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
942                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
943                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
944                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
945                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
946                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
947                 break;
948         case D3DTOP_BLENDCURRENTALPHA:
949                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
950                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
951                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
952                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
953                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
954                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
955                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
956                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
957                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
958                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
959                 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
960                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
961                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
962                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
963                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
964                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
965                 break;
966         case D3DTOP_DOTPRODUCT3: 
967                if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
968                   glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
969                   checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
970                } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
971                   glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
972                   checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
973                 } else {
974                   FIXME("This version of opengl does not support GL_DOT3\n");
975                 }
976                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
977                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
978                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
979                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
980                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
981                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
982                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
983                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
984                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
985                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
986                 break;
987         case D3DTOP_LERP:
988                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
989                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
990                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
991                 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
992                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
993                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
994                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
995                 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
996                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
997                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
998                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
999                 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1000                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, src3);
1001                 checkGLcall("GL_TEXTURE_ENV, opr2_target, src1");
1002                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1003                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1004                 break;
1005         default:
1006                 Handled = FALSE;
1007         }
1008
1009         if (Handled) {
1010           BOOL  combineOK = TRUE;
1011           if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1012             DWORD op2;
1013             
1014             if (isAlpha) {
1015               op2 = This->UpdateStateBlock->texture_state[Stage][D3DTSS_COLOROP];
1016             } else {
1017               op2 = This->UpdateStateBlock->texture_state[Stage][D3DTSS_ALPHAOP];
1018             }
1019             
1020             /* Note: If COMBINE4 in effect can't go back to combine! */
1021             switch (op2) {
1022             case D3DTOP_ADDSMOOTH:
1023             case D3DTOP_BLENDTEXTUREALPHAPM:
1024             case D3DTOP_MODULATEALPHA_ADDCOLOR:
1025             case D3DTOP_MODULATECOLOR_ADDALPHA:
1026             case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
1027             case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
1028             case D3DTOP_MULTIPLYADD:
1029               /* Ignore those implemented in both cases */
1030               switch (op) {
1031               case D3DTOP_SELECTARG1:
1032               case D3DTOP_SELECTARG2:
1033                 combineOK = FALSE;
1034                 Handled   = FALSE;
1035                 break;
1036               default:
1037                 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%d, otherop=%ld, isAlpha(%d)\n", op, op2, isAlpha);
1038                 LEAVE_GL();
1039                 return;
1040               }
1041             }
1042           }
1043           
1044           if (combineOK == TRUE) {
1045             glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
1046             checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
1047             
1048             LEAVE_GL();
1049             return;
1050           }
1051         }
1052
1053         /* Other texture operations require special extensions: */
1054         if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1055           if (isAlpha) {
1056             opr = GL_SRC_ALPHA;
1057             invopr = GL_ONE_MINUS_SRC_ALPHA;
1058             src3_target = GL_SOURCE3_ALPHA_NV;
1059             opr3_target = GL_OPERAND3_ALPHA_NV;
1060           } else {
1061             opr = GL_SRC_COLOR;
1062             invopr = GL_ONE_MINUS_SRC_COLOR;
1063             src3_target = GL_SOURCE3_RGB_NV;
1064             opr3_target = GL_OPERAND3_RGB_NV;
1065           }
1066           Handled = TRUE; /* Again, assume handled */
1067           switch (op) {
1068           case D3DTOP_SELECTARG1:                                          /* = a1 * 1 + 0 * 0 */
1069           case D3DTOP_SELECTARG2:                                          /* = a2 * 1 + 0 * 0 */
1070             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1071             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1072             if (op == D3DTOP_SELECTARG1) {
1073               glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);                
1074               checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1075               glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);        
1076               checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");  
1077             } else {
1078               glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);                
1079               checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1080               glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);        
1081               checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");  
1082             }
1083             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);             
1084             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1085             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);              
1086             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");  
1087             glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);             
1088             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1089             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1090             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");  
1091             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);             
1092             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1093             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1094             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");  
1095             break;
1096             
1097           case D3DTOP_ADDSMOOTH:
1098             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1099             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1100             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1101             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1102             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1103             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1104             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1105             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1106             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1107             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1108             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1109             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1110             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1111             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1112             glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1113             checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1114             switch (opr1) {
1115             case GL_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_COLOR; break;
1116             case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_SRC_COLOR; break;
1117             case GL_SRC_ALPHA: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
1118             case GL_ONE_MINUS_SRC_ALPHA: opr1 = GL_SRC_ALPHA; break;
1119             }
1120             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr1);
1121             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1122             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1123             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1124             break;
1125           case D3DTOP_BLENDTEXTUREALPHAPM:
1126             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1127             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1128             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1129             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1130             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1131             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1132             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1133             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1134             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1135             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1136             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1137             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1138             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1139             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1140             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1141             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1142             glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1143             checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1144             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1145             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1146             break;
1147           case D3DTOP_MODULATEALPHA_ADDCOLOR:
1148             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1149             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");  /* Add = a0*a1 + a2*a3 */
1150             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);        /*   a0 = src1/opr1    */
1151             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1152             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1153             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");    /*   a1 = 1 (see docs) */
1154             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1155             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1156             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);      
1157             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");  
1158             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);        /*   a2 = arg2         */
1159             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1160             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1161             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");     /*  a3 = src1 alpha   */
1162             glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1163             checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1164             switch (opr1) {
1165             case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
1166             case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
1167             }
1168             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr1);
1169             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1170             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1171             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1172             break;
1173           case D3DTOP_MODULATECOLOR_ADDALPHA:
1174             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1175             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1176             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1177             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1178             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1179             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1180             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1181             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1182             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1183             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1184             glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1185             checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1186             switch (opr1) {
1187             case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
1188             case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
1189             }
1190             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1191             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr1");
1192             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1193             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1194             glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1195             checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1196             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1197             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1198             break;
1199           case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
1200             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1201             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1202             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1203             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1204             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1205             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1206             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1207             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1208             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1209             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1210             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1211             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1212             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1213             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1214             glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1215             checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1216             switch (opr1) {
1217             case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1218             case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1219             case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1220             case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1221             }
1222             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1223             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1224             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1225             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1226             break;
1227           case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
1228             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1229             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1230             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1231             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1232             switch (opr1) {
1233             case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1234             case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1235             case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1236             case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1237             }
1238             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
1239             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
1240             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1241             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1242             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1243             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1244             glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1245             checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1246             switch (opr1) {
1247             case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
1248             case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
1249             }
1250             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1251             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr1");
1252             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1253             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1254             glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1255             checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1256             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1257             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1258             break;
1259           case D3DTOP_MULTIPLYADD:
1260             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1261             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1262             glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
1263             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1264             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
1265             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1266             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1267             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1268             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1269             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1270             glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1271             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1272             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1273             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1274             glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
1275             checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
1276             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
1277             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
1278             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1279             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1280             break;
1281
1282           default:
1283             Handled = FALSE;
1284           }
1285           if (Handled) {
1286             glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
1287             checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
1288             
1289             LEAVE_GL();
1290             return;
1291           }
1292         } /* GL_NV_texture_env_combine4 */
1293         
1294         LEAVE_GL();
1295         
1296         /* After all the extensions, if still unhandled, report fixme */
1297         FIXME("Unhandled texture operation %d\n", op);
1298 }
1299 #endif