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