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