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