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