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