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