AddRef texture only if there is one for the requested stage.
[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 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
675 #if defined (GL_VERSION_1_3)
676 # define useext(A) A
677 # define combine_ext 1
678 #elif defined (GL_EXT_texture_env_combine)
679 # define useext(A) A##_EXT
680 # define combine_ext 1
681 #elif defined (GL_ARB_texture_env_combine)
682 # define useext(A) A##_ARB
683 # define combine_ext 1
684 #else
685 # undef combine_ext
686 #endif
687
688 #if !defined(combine_ext)
689 void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
690
691         FIXME("Requires opengl combine extensions to work\n");
692         return;
693 }
694 #else
695 /* Setup the texture operations texture stage states */
696 void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
697 {
698         GLenum src1, src2, src3;
699         GLenum opr1, opr2, opr3;
700         GLenum comb_target;
701         GLenum src0_target, src1_target, src2_target;
702         GLenum opr0_target, opr1_target, opr2_target;
703         GLenum scal_target;
704         GLenum opr=0, invopr, src3_target, opr3_target;
705         BOOL Handled = FALSE;
706         ICOM_THIS(IDirect3DDevice8Impl,iface);
707
708         TRACE("Alpha?(%d), Stage:%d Op(%d), a1(%ld), a2(%ld), a3(%ld)\n", isAlpha, Stage, op, arg1, arg2, arg3);
709
710         ENTER_GL();
711
712         /* Note: Operations usually involve two ars, src0 and src1 and are operations of
713            the form (a1 <operation> a2). However, some of the more complex operations
714            take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added  
715            in a third parameter called a0. Therefore these are operations of the form
716            a0 <operation> a1 <operation> a2, ie the new parameter goes to the front.
717            
718            However, below we treat the new (a0) parameter as src2/opr2, so in the actual
719            functions below, expect their syntax to differ slightly to those listed in the
720            manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
721            This affects D3DTOP_MULTIPLYADD and D3DTOP_LERP                               */
722            
723         if (isAlpha) {
724                 comb_target = useext(GL_COMBINE_ALPHA);
725                 src0_target = useext(GL_SOURCE0_ALPHA);
726                 src1_target = useext(GL_SOURCE1_ALPHA);
727                 src2_target = useext(GL_SOURCE2_ALPHA);
728                 opr0_target = useext(GL_OPERAND0_ALPHA);
729                 opr1_target = useext(GL_OPERAND1_ALPHA);
730                 opr2_target = useext(GL_OPERAND2_ALPHA);
731                 scal_target = GL_ALPHA_SCALE;
732         }
733         else {
734                 comb_target = useext(GL_COMBINE_RGB);
735                 src0_target = useext(GL_SOURCE0_RGB);
736                 src1_target = useext(GL_SOURCE1_RGB);
737                 src2_target = useext(GL_SOURCE2_RGB);
738                 opr0_target = useext(GL_OPERAND0_RGB);
739                 opr1_target = useext(GL_OPERAND1_RGB);
740                 opr2_target = useext(GL_OPERAND2_RGB);
741                 scal_target = useext(GL_RGB_SCALE);
742         }
743
744         /* From MSDN (D3DTSS_ALPHAARG1) : 
745            The default argument is D3DTA_TEXTURE. If no texture is set for this stage, 
746                    then the default argument is D3DTA_DIFFUSE.
747                    FIXME? If texture added/removed, may need to reset back as well?    */
748         if (isAlpha && This->StateBlock->textures[Stage] == NULL && arg1 == D3DTA_TEXTURE) {
749             GetSrcAndOpFromValue(D3DTA_DIFFUSE, isAlpha, &src1, &opr1);  
750         } else {
751             GetSrcAndOpFromValue(arg1, isAlpha, &src1, &opr1);
752         }
753         GetSrcAndOpFromValue(arg2, isAlpha, &src2, &opr2);
754         GetSrcAndOpFromValue(arg3, isAlpha, &src3, &opr3);
755         
756         TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
757
758         Handled = TRUE; /* Assume will be handled */
759         switch (op) {
760         case D3DTOP_DISABLE: /* Only for alpha */
761                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
762                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
763                 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
764                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
765                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
766                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
767                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
768                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
769                 break;
770         case D3DTOP_SELECTARG1:
771                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
772                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
773                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
774                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
775                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
776                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
777                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
778                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
779                 break;
780         case D3DTOP_SELECTARG2:
781                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
782                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
783                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
784                 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
785                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
786                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
787                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
788                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
789                 break;
790         case D3DTOP_MODULATE:
791                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
792                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
793                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
794                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
795                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
796                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
797                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
798                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
799                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
800                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
801                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
802                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
803                 break;
804         case D3DTOP_MODULATE2X:
805                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
806                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
807                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
808                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
809                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
810                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
811                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
812                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
813                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
814                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
815                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
816                 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
817                 break;
818         case D3DTOP_MODULATE4X:
819                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
820                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
821                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
822                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
823                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
824                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
825                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
826                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
827                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
828                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
829                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
830                 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
831                 break;
832         case D3DTOP_ADD:
833                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
834                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
835                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
836                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
837                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
838                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
839                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
840                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
841                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
842                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
843                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
844                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
845                 break;
846         case D3DTOP_ADDSIGNED:
847                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
848                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
849                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
850                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
851                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
852                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
853                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
854                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
855                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
856                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
857                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
858                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
859                 break;
860         case D3DTOP_ADDSIGNED2X:
861                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
862                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
863                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
864                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
865                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
866                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
867                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
868                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
869                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
870                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
871                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
872                 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
873                 break;
874         case D3DTOP_SUBTRACT:
875           if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
876                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
877                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
878                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
879                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
880                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
881                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
882                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
883                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
884                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
885                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
886                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
887                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
888           } else {
889                 FIXME("This version of opengl does not support GL_SUBTRACT\n");
890           }
891           break;
892
893         case D3DTOP_BLENDDIFFUSEALPHA:
894                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
895                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
896                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
897                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
898                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
899                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
900                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
901                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
902                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
903                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
904                 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
905                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
906                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
907                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
908                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
909                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
910                 break;
911         case D3DTOP_BLENDTEXTUREALPHA:
912                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
913                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
914                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
915                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
916                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
917                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
918                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
919                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
920                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
921                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
922                 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
923                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
924                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
925                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
926                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
927                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
928                 break;
929         case D3DTOP_BLENDFACTORALPHA:
930                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
931                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
932                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
933                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
934                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
935                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
936                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
937                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
938                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
939                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
940                 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
941                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
942                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
943                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
944                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
945                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
946                 break;
947         case D3DTOP_BLENDCURRENTALPHA:
948                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
949                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
950                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
951                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
952                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
953                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
954                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
955                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
956                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
957                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
958                 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
959                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
960                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
961                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
962                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
963                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
964                 break;
965         case D3DTOP_DOTPRODUCT3: 
966                if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
967                   glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);
968                   checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA");
969                 } else {
970                   FIXME("This version of opengl does not support GL_DOT3\n");
971                 }
972                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
973                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
974                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
975                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
976                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
977                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
978                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
979                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
980                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
981                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
982                 break;
983         case D3DTOP_LERP:
984                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
985                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
986                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
987                 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
988                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
989                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
990                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
991                 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
992                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
993                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
994                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
995                 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
996                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, src3);
997                 checkGLcall("GL_TEXTURE_ENV, opr2_target, src1");
998                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
999                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1000                 break;
1001         default:
1002                 Handled = FALSE;
1003         }
1004
1005         if (Handled) {
1006             BOOL  combineOK = TRUE;
1007 #if defined(GL_NV_texture_env_combine4)
1008             DWORD op2;
1009
1010             if (isAlpha) {
1011                 op2 = This->UpdateStateBlock->texture_state[Stage][D3DTSS_COLOROP];
1012             } else {
1013                 op2 = This->UpdateStateBlock->texture_state[Stage][D3DTSS_ALPHAOP];
1014             }
1015
1016            /* Note: If COMBINE4 in effect cant go back to combine! */
1017            switch (op2)
1018            {
1019            case D3DTOP_ADDSMOOTH:
1020            case D3DTOP_BLENDTEXTUREALPHAPM:
1021            case D3DTOP_MODULATEALPHA_ADDCOLOR:
1022            case D3DTOP_MODULATECOLOR_ADDALPHA:
1023            case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
1024            case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
1025            case D3DTOP_MULTIPLYADD:
1026                /* Ignore those implemented in both cases */
1027                switch (op) {
1028                case D3DTOP_SELECTARG1:
1029                case D3DTOP_SELECTARG2:
1030                    combineOK = FALSE;
1031                    Handled   = FALSE;
1032                    break;
1033                default:
1034                    FIXME("Cant have COMBINE4 and COMBINE in efferct together, thisop=%d, otherop=%ld, isAlpha(%d)\n", 
1035                               op, op2, isAlpha);
1036
1037                    LEAVE_GL();
1038                    return;
1039                }
1040            }
1041 #endif
1042
1043            if (combineOK == TRUE) {
1044                glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
1045                checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
1046
1047                LEAVE_GL();
1048                return;
1049            }
1050         }
1051
1052         /* Other texture operations require special extensions: */
1053 #if defined(GL_NV_texture_env_combine4)
1054         if (isAlpha) {
1055                 opr = GL_SRC_ALPHA;
1056                 invopr = GL_ONE_MINUS_SRC_ALPHA;
1057                 src3_target = GL_SOURCE3_ALPHA_NV;
1058                 opr3_target = GL_OPERAND3_ALPHA_NV;
1059         }
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 #endif /* 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