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