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