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