user32: Further implementation of MNS_NOTIFYBYPOS.
[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_ADDSIGNED2X);
957         D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
958         D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
959         D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
960         D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
961         D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
962         D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
963         D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
964         D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
965         D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
966         D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
967         D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
968         D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
969         D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
970         D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
971         D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
972         D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
973         D3DTOP_TO_STR(WINED3DTOP_LERP);
974 #undef D3DTOP_TO_STR
975         default:
976             FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
977             return "unrecognized";
978     }
979 }
980
981 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
982     switch (tstype) {
983 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
984     TSTYPE_TO_STR(WINED3DTS_VIEW);
985     TSTYPE_TO_STR(WINED3DTS_PROJECTION);
986     TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
987     TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
988     TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
989     TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
990     TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
991     TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
992     TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
993     TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
994     TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
995 #undef TSTYPE_TO_STR
996     default:
997         if (tstype > 256 && tstype < 512) {
998             FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
999             return ("WINED3DTS_WORLDMATRIX > 0");
1000         }
1001         FIXME("Unrecognized %u WINED3DTS\n", tstype);
1002         return "unrecognized";
1003     }
1004 }
1005
1006 const char* debug_d3dpool(WINED3DPOOL Pool) {
1007   switch (Pool) {
1008 #define POOL_TO_STR(p) case p: return #p;
1009     POOL_TO_STR(WINED3DPOOL_DEFAULT);
1010     POOL_TO_STR(WINED3DPOOL_MANAGED);
1011     POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1012     POOL_TO_STR(WINED3DPOOL_SCRATCH);
1013 #undef  POOL_TO_STR
1014   default:
1015     FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1016     return "unrecognized";
1017   }
1018 }
1019
1020 const char *debug_fbostatus(GLenum status) {
1021     switch(status) {
1022 #define FBOSTATUS_TO_STR(u) case u: return #u
1023         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1024         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1025         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1026         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1027         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1028         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1029         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1030         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1031 #undef FBOSTATUS_TO_STR
1032         default:
1033             FIXME("Unrecognied FBO status 0x%08x\n", status);
1034             return "unrecognized";
1035     }
1036 }
1037
1038 const char *debug_glerror(GLenum error) {
1039     switch(error) {
1040 #define GLERROR_TO_STR(u) case u: return #u
1041         GLERROR_TO_STR(GL_NO_ERROR);
1042         GLERROR_TO_STR(GL_INVALID_ENUM);
1043         GLERROR_TO_STR(GL_INVALID_VALUE);
1044         GLERROR_TO_STR(GL_INVALID_OPERATION);
1045         GLERROR_TO_STR(GL_STACK_OVERFLOW);
1046         GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1047         GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1048         GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1049 #undef GLERROR_TO_STR
1050         default:
1051             FIXME("Unrecognied GL error 0x%08x\n", error);
1052             return "unrecognized";
1053     }
1054 }
1055
1056 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1057     switch(basis) {
1058         case WINED3DBASIS_BEZIER:       return "WINED3DBASIS_BEZIER";
1059         case WINED3DBASIS_BSPLINE:      return "WINED3DBASIS_BSPLINE";
1060         case WINED3DBASIS_INTERPOLATE:  return "WINED3DBASIS_INTERPOLATE";
1061         default:                        return "unrecognized";
1062     }
1063 }
1064
1065 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1066     switch(degree) {
1067         case WINED3DDEGREE_LINEAR:      return "WINED3DDEGREE_LINEAR";
1068         case WINED3DDEGREE_QUADRATIC:   return "WINED3DDEGREE_QUADRATIC";
1069         case WINED3DDEGREE_CUBIC:       return "WINED3DDEGREE_CUBIC";
1070         case WINED3DDEGREE_QUINTIC:     return "WINED3DDEGREE_QUINTIC";
1071         default:                        return "unrecognized";
1072     }
1073 }
1074
1075 /*****************************************************************************
1076  * Useful functions mapping GL <-> D3D values
1077  */
1078 GLenum StencilOp(DWORD op) {
1079     switch(op) {
1080     case WINED3DSTENCILOP_KEEP    : return GL_KEEP;
1081     case WINED3DSTENCILOP_ZERO    : return GL_ZERO;
1082     case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1083     case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1084     case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1085     case WINED3DSTENCILOP_INVERT  : return GL_INVERT;
1086     case WINED3DSTENCILOP_INCR    : return GL_INCR_WRAP_EXT;
1087     case WINED3DSTENCILOP_DECR    : return GL_DECR_WRAP_EXT;
1088     default:
1089         FIXME("Unrecognized stencil op %d\n", op);
1090         return GL_KEEP;
1091     }
1092 }
1093
1094 GLenum CompareFunc(DWORD func) {
1095     switch ((WINED3DCMPFUNC)func) {
1096     case WINED3DCMP_NEVER        : return GL_NEVER;
1097     case WINED3DCMP_LESS         : return GL_LESS;
1098     case WINED3DCMP_EQUAL        : return GL_EQUAL;
1099     case WINED3DCMP_LESSEQUAL    : return GL_LEQUAL;
1100     case WINED3DCMP_GREATER      : return GL_GREATER;
1101     case WINED3DCMP_NOTEQUAL     : return GL_NOTEQUAL;
1102     case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1103     case WINED3DCMP_ALWAYS       : return GL_ALWAYS;
1104     default:
1105         FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1106         return 0;
1107     }
1108 }
1109
1110 static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) {
1111     switch (d3dta) {
1112         case WINED3DTA_DIFFUSE:
1113             return GL_PRIMARY_COLOR_NV;
1114
1115         case WINED3DTA_CURRENT:
1116             if (stage) return GL_SPARE0_NV;
1117             else return GL_PRIMARY_COLOR_NV;
1118
1119         case WINED3DTA_TEXTURE:
1120             if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx;
1121             else return GL_PRIMARY_COLOR_NV;
1122
1123         case WINED3DTA_TFACTOR:
1124             return GL_CONSTANT_COLOR0_NV;
1125
1126         case WINED3DTA_SPECULAR:
1127             return GL_SECONDARY_COLOR_NV;
1128
1129         case WINED3DTA_TEMP:
1130             return GL_SPARE1_NV;
1131
1132         case WINED3DTA_CONSTANT:
1133             /* TODO: Support per stage constants (WINED3DTSS_CONSTANT, NV_register_combiners2) */
1134             FIXME("WINED3DTA_CONSTANT, not properly supported.\n");
1135             return GL_CONSTANT_COLOR1_NV;
1136
1137         default:
1138             FIXME("Unrecognized texture arg %#x\n", d3dta);
1139             return GL_TEXTURE;
1140     }
1141 }
1142
1143 static GLenum invert_mapping(GLenum mapping) {
1144     if (mapping == GL_UNSIGNED_INVERT_NV) return GL_SIGNED_IDENTITY_NV;
1145     else if (mapping == GL_SIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV;
1146
1147     FIXME("Unhandled mapping %#x\n", mapping);
1148     return mapping;
1149 }
1150
1151 static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) {
1152     /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should
1153      * be used. */
1154     if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV;
1155     else *mapping = GL_SIGNED_IDENTITY_NV;
1156
1157     /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input
1158      * should be used for all input components. */
1159     if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA;
1160     else *component_usage = GL_RGB;
1161
1162     *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx);
1163 }
1164
1165 typedef struct {
1166     GLenum input[3];
1167     GLenum mapping[3];
1168     GLenum component_usage[3];
1169 } tex_op_args;
1170
1171 static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1172     if (op == WINED3DTOP_DISABLE) return FALSE;
1173     if (This->stateBlock->textures[stage]) return FALSE;
1174
1175     if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1176             && op != WINED3DTOP_SELECTARG2) return TRUE;
1177     if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1178             && op != WINED3DTOP_SELECTARG1) return TRUE;
1179     if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1180             && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1181
1182     return FALSE;
1183 }
1184
1185 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) {
1186     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface;
1187     tex_op_args tex_op_args = {{0}, {0}, {0}};
1188     GLenum portion = is_alpha ? GL_ALPHA : GL_RGB;
1189     GLenum target = GL_COMBINER0_NV + stage;
1190     GLenum output;
1191
1192     TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1193             stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx);
1194
1195     /* If a texture stage references an invalid texture unit the stage just
1196      * passes through the result from the previous stage */
1197     if (is_invalid_op(This, stage, op, arg1, arg2, arg3)) {
1198         arg1 = WINED3DTA_CURRENT;
1199         op = WINED3DTOP_SELECTARG1;
1200     }
1201
1202     get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0],
1203             &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx);
1204     get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1],
1205             &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx);
1206     get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2],
1207             &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx);
1208
1209
1210     if(dst == WINED3DTA_TEMP) {
1211         output = GL_SPARE1_NV;
1212     } else {
1213         output = GL_SPARE0_NV;
1214     }
1215
1216     /* This is called by a state handler which has the gl lock held and a context for the thread */
1217     switch(op)
1218     {
1219         case WINED3DTOP_DISABLE:
1220             /* Only for alpha */
1221             if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n");
1222             /* Input, prev_alpha*1 */
1223             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1224                     GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
1225             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1226                     GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
1227
1228             /* Output */
1229             GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1230                     GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1231             break;
1232
1233         case WINED3DTOP_SELECTARG1:
1234         case WINED3DTOP_SELECTARG2:
1235             /* Input, arg*1 */
1236             if (op == WINED3DTOP_SELECTARG1) {
1237                 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1238                         tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1239             } else {
1240                 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1241                         tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1242             }
1243             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1244                     GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1245
1246             /* Output */
1247             GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
1248                     GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1249             break;
1250
1251         case WINED3DTOP_MODULATE:
1252         case WINED3DTOP_MODULATE2X:
1253         case WINED3DTOP_MODULATE4X:
1254             /* Input, arg1*arg2 */
1255             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1256                     tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1257             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1258                     tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1259
1260             /* Output */
1261             if (op == WINED3DTOP_MODULATE) {
1262                 GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
1263                         GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1264             } else if (op == WINED3DTOP_MODULATE2X) {
1265                 GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
1266                         GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1267             } else if (op == WINED3DTOP_MODULATE4X) {
1268                 GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
1269                         GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1270             }
1271             break;
1272
1273         case WINED3DTOP_ADD:
1274         case WINED3DTOP_ADDSIGNED:
1275         case WINED3DTOP_ADDSIGNED2X:
1276             /* Input, arg1*1+arg2*1 */
1277             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1278                     tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1279             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1280                     GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1281             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1282                     tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1283             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1284                     GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1285
1286             /* Output */
1287             if (op == WINED3DTOP_ADD) {
1288                 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1289                            output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1290             } else if (op == WINED3DTOP_ADDSIGNED) {
1291                 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1292                            output, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
1293             } else if (op == WINED3DTOP_ADDSIGNED2X) {
1294                 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1295                            output, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
1296             }
1297             break;
1298
1299         case WINED3DTOP_SUBTRACT:
1300             /* Input, arg1*1+-arg2*1 */
1301             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1302                     tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1303             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1304                     GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1305             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1306                     tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1]));
1307             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1308                     GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1309
1310             /* Output */
1311             GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1312                        output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1313             break;
1314
1315         case WINED3DTOP_ADDSMOOTH:
1316             /* Input, arg1*1+(1-arg1)*arg2 */
1317             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1318                     tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1319             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1320                     GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1321             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1322                     tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1323             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1324                     tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1325
1326             /* Output */
1327             GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1328                        output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1329             break;
1330
1331         case WINED3DTOP_BLENDDIFFUSEALPHA:
1332         case WINED3DTOP_BLENDTEXTUREALPHA:
1333         case WINED3DTOP_BLENDFACTORALPHA:
1334         case WINED3DTOP_BLENDTEXTUREALPHAPM:
1335         case WINED3DTOP_BLENDCURRENTALPHA:
1336         {
1337             GLenum alpha_src = GL_PRIMARY_COLOR_NV;
1338             if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx);
1339             else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
1340             else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx);
1341             else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
1342             else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx);
1343             else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op));
1344
1345             /* Input, arg1*alpha_src+arg2*(1-alpha_src) */
1346             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1347                     tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1348             if (op == WINED3DTOP_BLENDTEXTUREALPHAPM)
1349             {
1350                 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1351                         GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1352             } else {
1353                 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1354                         alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
1355             }
1356             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1357                     tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1358             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1359                     alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
1360
1361             /* Output */
1362             GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1363                        output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1364             break;
1365         }
1366
1367         case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1368             /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */
1369             if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n");
1370             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1371                     tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1372             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1373                     tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1374             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1375                     tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1376             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1377                     GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1378
1379             /* Output */
1380             GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1381                        output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1382             break;
1383
1384         case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1385             /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */
1386             if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n");
1387             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1388                     tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1389             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1390                     tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1391             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1392                     tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1393             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1394                     GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1395
1396             /* Output */
1397             GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1398                        output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1399             break;
1400
1401         case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1402             /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */
1403             if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n");
1404             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1405                     tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA));
1406             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1407                     tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1408             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1409                     tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1410             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1411                     GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1412
1413             /* Output */
1414             GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1415                        output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1416             break;
1417
1418         case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1419             /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */
1420             if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n");
1421             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1422                     tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1423             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1424                     tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1425             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1426                     tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1427             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1428                     GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1429
1430             /* Output */
1431             GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1432                        output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1433             break;
1434
1435         case WINED3DTOP_DOTPRODUCT3:
1436             /* Input, arg1 . arg2 */
1437             /* FIXME: DX7 uses a different calculation? */
1438             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1439                     tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0]));
1440             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1441                     tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1]));
1442
1443             /* Output */
1444             GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
1445                     GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE));
1446             break;
1447
1448         case WINED3DTOP_MULTIPLYADD:
1449             /* Input, arg3*1+arg1*arg2 */
1450             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1451                     tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1452             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1453                     GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1454             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1455                     tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1456             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1457                     tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1458
1459             /* Output */
1460             GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1461                        output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1462             break;
1463
1464         case WINED3DTOP_LERP:
1465             /* Input, arg3*arg1+(1-arg3)*arg2 */
1466             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1467                     tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1468             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1469                     tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1470             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1471                     tex_op_args.input[2], invert_mapping(tex_op_args.mapping[2]), tex_op_args.component_usage[2]));
1472             GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1473                     tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1474
1475             /* Output */
1476             GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1477                        output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1478             break;
1479
1480         case WINED3DTOP_BUMPENVMAPLUMINANCE:
1481         case WINED3DTOP_BUMPENVMAP:
1482             if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
1483                 /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to
1484                  * perform bump mapping and source from the current stage. Pretty much a SELECTARG2.
1485                  * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1
1486                  * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the next stage
1487                  */
1488                 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1489                         tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1490                 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1491                         GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1492                 /* Always pass through to CURRENT, ignore temp arg */
1493                 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1494                         GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1495                 break;
1496             }
1497
1498         default:
1499             FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1500                     stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
1501     }
1502
1503     checkGLcall("set_tex_op_nvrc()\n");
1504
1505 }
1506
1507 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
1508     /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
1509      * input should be used for all input components. The WINED3DTA_COMPLEMENT
1510      * flag specifies the complement of the input should be used. */
1511     BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
1512     BOOL complement = arg & WINED3DTA_COMPLEMENT;
1513
1514     /* Calculate the operand */
1515     if (complement) {
1516         if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
1517         else *operand = GL_ONE_MINUS_SRC_COLOR;
1518     } else {
1519         if (from_alpha) *operand = GL_SRC_ALPHA;
1520         else *operand = GL_SRC_COLOR;
1521     }
1522
1523     /* Calculate the source */
1524     switch (arg & WINED3DTA_SELECTMASK) {
1525         case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
1526         case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
1527         case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
1528         case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
1529         case WINED3DTA_SPECULAR:
1530             /*
1531              * According to the GL_ARB_texture_env_combine specs, SPECULAR is
1532              * 'Secondary color' and isn't supported until base GL supports it
1533              * There is no concept of temp registers as far as I can tell
1534              */
1535             FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
1536             *source = GL_TEXTURE;
1537             break;
1538         default:
1539             FIXME("Unrecognized texture arg %#x\n", arg);
1540             *source = GL_TEXTURE;
1541             break;
1542     }
1543 }
1544
1545 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
1546 #if defined (GL_VERSION_1_3)
1547 # define useext(A) A
1548 # define combine_ext 1
1549 #elif defined (GL_EXT_texture_env_combine)
1550 # define useext(A) A##_EXT
1551 # define combine_ext 1
1552 #elif defined (GL_ARB_texture_env_combine)
1553 # define useext(A) A##_ARB
1554 # define combine_ext 1
1555 #else
1556 # undef combine_ext
1557 #endif
1558
1559 #if !defined(combine_ext)
1560 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1561 {
1562         FIXME("Requires opengl combine extensions to work\n");
1563         return;
1564 }
1565 #else
1566 /* Setup the texture operations texture stage states */
1567 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1568 {
1569         GLenum src1, src2, src3;
1570         GLenum opr1, opr2, opr3;
1571         GLenum comb_target;
1572         GLenum src0_target, src1_target, src2_target;
1573         GLenum opr0_target, opr1_target, opr2_target;
1574         GLenum scal_target;
1575         GLenum opr=0, invopr, src3_target, opr3_target;
1576         BOOL Handled = FALSE;
1577         IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
1578
1579         TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
1580
1581         /* This is called by a state handler which has the gl lock held and a context for the thread */
1582
1583         /* Note: Operations usually involve two ars, src0 and src1 and are operations of
1584            the form (a1 <operation> a2). However, some of the more complex operations
1585            take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
1586            in a third parameter called a0. Therefore these are operations of the form
1587            a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
1588
1589            However, below we treat the new (a0) parameter as src2/opr2, so in the actual
1590            functions below, expect their syntax to differ slightly to those listed in the
1591            manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
1592            This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP                     */
1593
1594         if (isAlpha) {
1595                 comb_target = useext(GL_COMBINE_ALPHA);
1596                 src0_target = useext(GL_SOURCE0_ALPHA);
1597                 src1_target = useext(GL_SOURCE1_ALPHA);
1598                 src2_target = useext(GL_SOURCE2_ALPHA);
1599                 opr0_target = useext(GL_OPERAND0_ALPHA);
1600                 opr1_target = useext(GL_OPERAND1_ALPHA);
1601                 opr2_target = useext(GL_OPERAND2_ALPHA);
1602                 scal_target = GL_ALPHA_SCALE;
1603         }
1604         else {
1605                 comb_target = useext(GL_COMBINE_RGB);
1606                 src0_target = useext(GL_SOURCE0_RGB);
1607                 src1_target = useext(GL_SOURCE1_RGB);
1608                 src2_target = useext(GL_SOURCE2_RGB);
1609                 opr0_target = useext(GL_OPERAND0_RGB);
1610                 opr1_target = useext(GL_OPERAND1_RGB);
1611                 opr2_target = useext(GL_OPERAND2_RGB);
1612                 scal_target = useext(GL_RGB_SCALE);
1613         }
1614
1615         /* If a texture stage references an invalid texture unit the stage just
1616          * passes through the result from the previous stage */
1617         if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) {
1618             arg1 = WINED3DTA_CURRENT;
1619             op = WINED3DTOP_SELECTARG1;
1620         }
1621
1622         /* From MSDN (WINED3DTSS_ALPHAARG1) :
1623            The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage,
1624                    then the default argument is WINED3DTA_DIFFUSE.
1625                    FIXME? If texture added/removed, may need to reset back as well?    */
1626         if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
1627             get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
1628         } else {
1629             get_src_and_opr(arg1, isAlpha, &src1, &opr1);
1630         }
1631         get_src_and_opr(arg2, isAlpha, &src2, &opr2);
1632         get_src_and_opr(arg3, isAlpha, &src3, &opr3);
1633
1634         TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
1635
1636         Handled = TRUE; /* Assume will be handled */
1637
1638         /* Other texture operations require special extensions: */
1639         if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1640           if (isAlpha) {
1641             opr = GL_SRC_ALPHA;
1642             invopr = GL_ONE_MINUS_SRC_ALPHA;
1643             src3_target = GL_SOURCE3_ALPHA_NV;
1644             opr3_target = GL_OPERAND3_ALPHA_NV;
1645           } else {
1646             opr = GL_SRC_COLOR;
1647             invopr = GL_ONE_MINUS_SRC_COLOR;
1648             src3_target = GL_SOURCE3_RGB_NV;
1649             opr3_target = GL_OPERAND3_RGB_NV;
1650           }
1651           switch (op) {
1652           case WINED3DTOP_DISABLE: /* Only for alpha */
1653             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1654             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1655             glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1656             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1657             glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1658             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1659             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1660             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1661             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1662             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1663             glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1664             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1665             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1666             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1667             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1668             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1669             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1670             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1671             break;
1672           case WINED3DTOP_SELECTARG1:                                          /* = a1 * 1 + 0 * 0 */
1673           case WINED3DTOP_SELECTARG2:                                          /* = a2 * 1 + 0 * 0 */
1674             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1675             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1676             if (op == WINED3DTOP_SELECTARG1) {
1677               glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1678               checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1679               glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1680               checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1681             } else {
1682               glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1683               checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1684               glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1685               checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1686             }
1687             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1688             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1689             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1690             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1691             glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1692             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1693             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1694             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1695             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1696             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1697             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1698             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1699             break;
1700
1701           case WINED3DTOP_MODULATE:
1702             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1703             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1704             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1705             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1706             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1707             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1708             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1709             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1710             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1711             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1712             glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1713             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1714             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1715             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1716             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1717             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1718             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1719             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1720             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1721             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1722             break;
1723           case WINED3DTOP_MODULATE2X:
1724             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1725             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1726             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1727             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1728             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1729             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1730             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1731             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1732             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1733             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1734             glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1735             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1736             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1737             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1738             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1739             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1740             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1741             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1742             glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1743             checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1744             break;
1745           case WINED3DTOP_MODULATE4X:
1746             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1747             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1748             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1749             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1750             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1751             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1752             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1753             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1754             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1755             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1756             glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1757             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1758             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1759             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1760             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1761             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1762             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1763             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1764             glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
1765             checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
1766             break;
1767
1768           case WINED3DTOP_ADD:
1769             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1770             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1771             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1772             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1773             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1774             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1775             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1776             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1777             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1778             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1779             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1780             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1781             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1782             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1783             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1784             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1785             glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1786             checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1787             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1788             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1789             break;
1790
1791           case WINED3DTOP_ADDSIGNED:
1792             glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1793             checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1794             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1795             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1796             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1797             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1798             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1799             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1800             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1801             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1802             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1803             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1804             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1805             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1806             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1807             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1808             glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1809             checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1810             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1811             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1812             break;
1813
1814           case WINED3DTOP_ADDSIGNED2X:
1815             glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1816             checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1817             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1818             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1819             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1820             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1821             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1822             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1823             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1824             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1825             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1826             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1827             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1828             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1829             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1830             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1831             glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1832             checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1833             glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1834             checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1835             break;
1836
1837           case WINED3DTOP_ADDSMOOTH:
1838             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1839             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1840             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1841             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1842             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1843             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1844             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1845             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1846             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1847             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1848             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1849             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1850             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1851             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1852             glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1853             checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1854             switch (opr1) {
1855             case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1856             case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1857             case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1858             case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1859             }
1860             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1861             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1862             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1863             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1864             break;
1865
1866           case WINED3DTOP_BLENDDIFFUSEALPHA:
1867             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1868             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1869             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1870             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1871             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1872             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1873             glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
1874             checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
1875             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1876             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1877             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1878             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1879             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1880             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1881             glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
1882             checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
1883             glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1884             checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1885             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1886             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1887             break;
1888           case WINED3DTOP_BLENDTEXTUREALPHA:
1889             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1890             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1891             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1892             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1893             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1894             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1895             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
1896             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
1897             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1898             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1899             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1900             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1901             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1902             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1903             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1904             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1905             glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1906             checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1907             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1908             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1909             break;
1910           case WINED3DTOP_BLENDFACTORALPHA:
1911             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1912             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1913             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1914             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1915             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1916             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1917             glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
1918             checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
1919             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1920             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1921             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1922             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1923             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1924             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1925             glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
1926             checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
1927             glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1928             checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1929             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1930             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1931             break;
1932           case WINED3DTOP_BLENDTEXTUREALPHAPM:
1933             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1934             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1935             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1936             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1937             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1938             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1939             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1940             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1941             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1942             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1943             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1944             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1945             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1946             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1947             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1948             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1949             glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1950             checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1951             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1952             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1953             break;
1954           case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1955             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1956             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");  /* Add = a0*a1 + a2*a3 */
1957             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);        /*   a0 = src1/opr1    */
1958             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1959             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1960             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");    /*   a1 = 1 (see docs) */
1961             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1962             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1963             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1964             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1965             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);        /*   a2 = arg2         */
1966             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1967             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1968             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");     /*  a3 = src1 alpha   */
1969             glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1970             checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1971             switch (opr) {
1972             case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1973             case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1974             }
1975             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1976             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1977             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1978             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1979             break;
1980           case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1981             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1982             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1983             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1984             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1985             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1986             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1987             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1988             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1989             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1990             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1991             glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1992             checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1993             switch (opr1) {
1994             case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1995             case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1996             }
1997             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1998             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1999             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2000             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2001             glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2002             checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2003             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2004             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2005             break;
2006           case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2007             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2008             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2009             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2010             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2011             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2012             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2013             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2014             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2015             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2016             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2017             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2018             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2019             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2020             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2021             glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2022             checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2023             switch (opr1) {
2024             case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2025             case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2026             case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2027             case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2028             }
2029             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2030             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2031             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2032             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2033             break;
2034           case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2035             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2036             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2037             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2038             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2039             switch (opr1) {
2040             case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2041             case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2042             case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2043             case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2044             }
2045             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2046             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2047             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2048             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2049             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2050             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2051             glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2052             checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2053             switch (opr1) {
2054             case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2055             case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2056             }
2057             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2058             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2059             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2060             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2061             glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2062             checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2063             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2064             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2065             break;
2066           case WINED3DTOP_MULTIPLYADD:
2067             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2068             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2069             glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2070             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2071             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2072             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2073             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2074             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2075             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2076             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2077             glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2078             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2079             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2080             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2081             glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2082             checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2083             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2084             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2085             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2086             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2087             break;
2088
2089           case WINED3DTOP_BUMPENVMAP:
2090             {
2091             }
2092
2093           case WINED3DTOP_BUMPENVMAPLUMINANCE:
2094                 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2095
2096           default:
2097             Handled = FALSE;
2098           }
2099           if (Handled) {
2100             glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2101             checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2102
2103             return;
2104           }
2105         } /* GL_NV_texture_env_combine4 */
2106
2107         Handled = TRUE; /* Again, assume handled */
2108         switch (op) {
2109         case WINED3DTOP_DISABLE: /* Only for alpha */
2110                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2111                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2112                 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2113                 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2114                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2115                 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2116                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2117                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2118                 break;
2119         case WINED3DTOP_SELECTARG1:
2120                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2121                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2122                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2123                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2124                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2125                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2126                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2127                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2128                 break;
2129         case WINED3DTOP_SELECTARG2:
2130                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2131                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2132                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2133                 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2134                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2135                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2136                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2137                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2138                 break;
2139         case WINED3DTOP_MODULATE:
2140                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2141                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2142                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2143                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2144                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2145                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2146                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2147                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2148                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2149                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2150                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2151                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2152                 break;
2153         case WINED3DTOP_MODULATE2X:
2154                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2155                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2156                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2157                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2158                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2159                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2160                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2161                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2162                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2163                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2164                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2165                 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2166                 break;
2167         case WINED3DTOP_MODULATE4X:
2168                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2169                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2170                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2171                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2172                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2173                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2174                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2175                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2176                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2177                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2178                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2179                 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2180                 break;
2181         case WINED3DTOP_ADD:
2182                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2183                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2184                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2185                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2186                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2187                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2188                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2189                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2190                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2191                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2192                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2193                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2194                 break;
2195         case WINED3DTOP_ADDSIGNED:
2196                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2197                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
2198                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2199                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2200                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2201                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2202                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2203                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2204                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2205                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2206                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2207                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2208                 break;
2209         case WINED3DTOP_ADDSIGNED2X:
2210                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2211                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2212                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2213                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2214                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2215                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2216                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2217                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2218                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2219                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2220                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2221                 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2222                 break;
2223         case WINED3DTOP_SUBTRACT:
2224           if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
2225                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2226                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
2227                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2228                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2229                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2230                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2231                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2232                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2233                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2234                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2235                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2236                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2237           } else {
2238                 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2239           }
2240           break;
2241
2242         case WINED3DTOP_BLENDDIFFUSEALPHA:
2243                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2244                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2245                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2246                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2247                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2248                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2249                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2250                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2251                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2252                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2253                 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
2254                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2255                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2256                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2257                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2258                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2259                 break;
2260         case WINED3DTOP_BLENDTEXTUREALPHA:
2261                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2262                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2263                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2264                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2265                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2266                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2267                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2268                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2269                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2270                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2271                 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2272                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2273                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2274                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2275                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2276                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2277                 break;
2278         case WINED3DTOP_BLENDFACTORALPHA:
2279                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2280                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2281                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2282                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2283                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2284                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2285                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2286                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2287                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2288                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2289                 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
2290                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2291                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2292                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2293                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2294                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2295                 break;
2296         case WINED3DTOP_BLENDCURRENTALPHA:
2297                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2298                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2299                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2300                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2301                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2302                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2303                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2304                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2305                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2306                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2307                 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
2308                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2309                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2310                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2311                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2312                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2313                 break;
2314         case WINED3DTOP_DOTPRODUCT3:
2315                 if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
2316                   glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2317                   checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2318                 } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
2319                   glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2320                   checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2321                 } else {
2322                   FIXME("This version of opengl does not support GL_DOT3\n");
2323                 }
2324                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2325                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2326                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2327                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2328                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2329                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2330                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2331                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2332                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2333                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2334                 break;
2335         case WINED3DTOP_LERP:
2336                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2337                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2338                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2339                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2340                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2341                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2342                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2343                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2344                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2345                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2346                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2347                 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2348                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2349                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2350                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2351                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2352                 break;
2353         case WINED3DTOP_ADDSMOOTH:
2354                 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2355                   glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2356                   checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2357                   glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2358                   checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2359                   switch (opr1) {
2360                   case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2361                   case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2362                   case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2363                   case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2364                   }
2365                   glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2366                   checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2367                   glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2368                   checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2369                   glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2370                   checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2371                   glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2372                   checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2373                   glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2374                   checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2375                   glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2376                   checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2377                 } else
2378                   Handled = FALSE;
2379                 break;
2380         case WINED3DTOP_BLENDTEXTUREALPHAPM:
2381                 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2382                   glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2383                   checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2384                   glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2385                   checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2386                   glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2387                   checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2388                   glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2389                   checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2390                   glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2391                   checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2392                   glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2393                   checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2394                   glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2395                   checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2396                   glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2397                   checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2398                 } else
2399                   Handled = FALSE;
2400                 break;
2401         case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2402                 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2403                   glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2404                   checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2405                   glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2406                   checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2407                   switch (opr1) {
2408                   case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2409                   case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2410                   case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2411                   case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2412                   }
2413                   glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2414                   checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2415                   glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2416                   checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2417                   glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2418                   checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2419                   glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2420                   checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2421                   glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2422                   checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2423                   glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2424                   checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2425                 } else
2426                   Handled = FALSE;
2427                 break;
2428         case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2429                 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2430                   glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2431                   checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2432                   glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2433                   checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2434                   glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2435                   checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2436                   glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2437                   checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2438                   switch (opr1) {
2439                   case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2440                   case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2441                   case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2442                   case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2443                   }
2444                   glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2445                   checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2446                   glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2447                   checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2448                   glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2449                   checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2450                   glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2451                   checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2452                 } else
2453                   Handled = FALSE;
2454                 break;
2455         case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2456                 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2457                   glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2458                   checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2459                   glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2460                   checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2461                   switch (opr1) {
2462                   case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2463                   case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2464                   case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2465                   case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2466                   }
2467                   glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2468                   checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2469                   glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2470                   checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2471                   glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2472                   checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2473                   glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2474                   checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2475                   glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2476                   checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2477                   glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2478                   checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2479                 } else
2480                   Handled = FALSE;
2481                 break;
2482         case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2483                 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2484                   glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2485                   checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2486                   glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2487                   checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2488                   switch (opr1) {
2489                   case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2490                   case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2491                   case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2492                   case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2493                   }
2494                   glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2495                   checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2496                   glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2497                   checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2498                   switch (opr1) {
2499                   case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2500                   case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2501                   case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2502                   case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2503                   }
2504                   glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2505                   checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2506                   glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2507                   checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2508                   glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2509                   checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2510                   glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2511                   checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2512                 } else
2513                   Handled = FALSE;
2514                 break;
2515         case WINED3DTOP_MULTIPLYADD:
2516                 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2517                   glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2518                   checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2519                   glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2520                   checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2521                   glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2522                   checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2523                   glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2524                   checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2525                   glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2526                   checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2527                   glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2528                   checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2529                   glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2530                   checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2531                   glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2532                   checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2533                 } else
2534                   Handled = FALSE;
2535                 break;
2536         case WINED3DTOP_BUMPENVMAPLUMINANCE:
2537                 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2538                     /* Some apps use BUMPENVMAPLUMINANCE instead of D3DTOP_BUMPENVMAP, although
2539                      * they check for the non-luminance cap flag. Well, give them what they asked
2540                      * for :-)
2541                      */
2542                     WARN("Application uses WINED3DTOP_BUMPENVMAPLUMINANCE\n");
2543                 } else {
2544                     Handled = FALSE;
2545                     break;
2546                 }
2547                 /* Fall through */
2548         case WINED3DTOP_BUMPENVMAP:
2549                 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2550                     TRACE("Using ati bumpmap on stage %d, target %d\n", Stage, Stage + 1);
2551                     glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI);
2552                     checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI)");
2553                     glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1);
2554                     checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1)");
2555                     glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2556                     checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2557                     glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2558                     checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2559                     glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2560                     checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2561                     glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2562                     checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2563                     glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2564                     checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2565                     glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2566                     checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2567
2568                     Handled = TRUE;
2569                     break;
2570                 } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2571                     /* Technically texture shader support without register combiners is possible, but not expected to occur
2572                      * on real world cards, so for now a fixme should be enough
2573                      */
2574                     FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
2575                 }
2576         default:
2577                 Handled = FALSE;
2578         }
2579
2580         if (Handled) {
2581           BOOL  combineOK = TRUE;
2582           if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2583             DWORD op2;
2584
2585             if (isAlpha) {
2586               op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP];
2587             } else {
2588               op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP];
2589             }
2590
2591             /* Note: If COMBINE4 in effect can't go back to combine! */
2592             switch (op2) {
2593             case WINED3DTOP_ADDSMOOTH:
2594             case WINED3DTOP_BLENDTEXTUREALPHAPM:
2595             case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2596             case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2597             case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2598             case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2599             case WINED3DTOP_MULTIPLYADD:
2600               /* Ignore those implemented in both cases */
2601               switch (op) {
2602               case WINED3DTOP_SELECTARG1:
2603               case WINED3DTOP_SELECTARG2:
2604                 combineOK = FALSE;
2605                 Handled   = FALSE;
2606                 break;
2607               default:
2608                 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
2609                 return;
2610               }
2611             }
2612           }
2613
2614           if (combineOK) {
2615             glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
2616             checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
2617
2618             return;
2619           }
2620         }
2621
2622         /* After all the extensions, if still unhandled, report fixme */
2623         FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
2624 #undef GLINFO_LOCATION
2625 }
2626 #endif
2627
2628 /* Setup this textures matrix according to the texture flags*/
2629 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype)
2630 {
2631     float mat[16];
2632
2633     glMatrixMode(GL_TEXTURE);
2634     checkGLcall("glMatrixMode(GL_TEXTURE)");
2635
2636     if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2637         glLoadIdentity();
2638         checkGLcall("glLoadIdentity()");
2639         return;
2640     }
2641
2642     if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2643         ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2644         return;
2645     }
2646
2647     memcpy(mat, smat, 16 * sizeof(float));
2648
2649     if (flags & WINED3DTTFF_PROJECTED) {
2650         switch (flags & ~WINED3DTTFF_PROJECTED) {
2651         case WINED3DTTFF_COUNT2:
2652             mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2653             mat[1] = mat[5] = mat[9] = mat[13] = 0;
2654             break;
2655         case WINED3DTTFF_COUNT3:
2656             mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2657             mat[2] = mat[6] = mat[10] = mat[14] = 0;
2658             break;
2659         }
2660     } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2661         if(!calculatedCoords) {
2662             switch(coordtype) {
2663                 case WINED3DDECLTYPE_FLOAT1:
2664                     /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2665                      * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2666                      * the input value to the transformation will be 0, so the matrix value is irrelevant
2667                      */
2668                     mat[12] = mat[4];
2669                     mat[13] = mat[5];
2670                     mat[14] = mat[6];
2671                     mat[15] = mat[7];
2672                     break;
2673                 case WINED3DDECLTYPE_FLOAT2:
2674                     /* See above, just 3rd and 4th coord
2675                     */
2676                     mat[12] = mat[8];
2677                     mat[13] = mat[9];
2678                     mat[14] = mat[10];
2679                     mat[15] = mat[11];
2680                     break;
2681                 case WINED3DDECLTYPE_FLOAT3: /* Opengl defaults match dx defaults */
2682                 case WINED3DDECLTYPE_FLOAT4: /* No defaults apply, all app defined */
2683
2684                 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2685                  * into a bad place. The division elimination below will apply to make sure the
2686                  * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2687                  */
2688                 case WINED3DDECLTYPE_UNUSED: /* No texture coords, 0/0/0/1 defaults are passed */
2689                     break;
2690                 default:
2691                     FIXME("Unexpected fixed function texture coord input\n");
2692             }
2693         }
2694         switch (flags & ~WINED3DTTFF_PROJECTED) {
2695             /* case WINED3DTTFF_COUNT1: Won't ever get here */
2696             case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2697             /* OpenGL divides the first 3 vertex coord by the 4th by default,
2698              * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2699              * the 4th coord evaluates to 1.0 to eliminate that.
2700              *
2701              * If the fixed function pipeline is used, the 4th value remains unused,
2702              * so there is no danger in doing this. With vertex shaders we have a
2703              * problem. Should an app hit that problem, the code here would have to
2704              * check for pixel shaders, and the shader has to undo the default gl divide.
2705              *
2706              * A more serious problem occurs if the app passes 4 coordinates in, and the
2707              * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2708              * or a replacement shader
2709              */
2710             default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2711         }
2712     }
2713
2714     glLoadMatrixf(mat);
2715     checkGLcall("glLoadMatrixf(mat)");
2716 }
2717
2718 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
2719
2720 /* This small helper function is used to convert a bitmask into the number of masked bits */
2721 unsigned int count_bits(unsigned int mask)
2722 {
2723     unsigned int count;
2724     for (count = 0; mask; ++count)
2725     {
2726         mask &= mask - 1;
2727     }
2728     return count;
2729 }
2730
2731 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2732  * The later function requires individual color components. */
2733 BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2734 {
2735     const StaticPixelFormatDesc *desc;
2736
2737     TRACE("fmt: %s\n", debug_d3dformat(fmt));
2738     switch(fmt)
2739     {
2740         case WINED3DFMT_X8R8G8B8:
2741         case WINED3DFMT_R8G8B8:
2742         case WINED3DFMT_A8R8G8B8:
2743         case WINED3DFMT_A2R10G10B10:
2744         case WINED3DFMT_X1R5G5B5:
2745         case WINED3DFMT_A1R5G5B5:
2746         case WINED3DFMT_R5G6B5:
2747         case WINED3DFMT_X4R4G4B4:
2748         case WINED3DFMT_A4R4G4B4:
2749         case WINED3DFMT_R3G3B2:
2750         case WINED3DFMT_A8P8:
2751         case WINED3DFMT_P8:
2752             break;
2753         default:
2754             ERR("Unsupported format: %s\n", debug_d3dformat(fmt));
2755             return FALSE;
2756     }
2757
2758     desc = getFormatDescEntry(fmt, NULL, NULL);
2759     if(!desc)
2760     {
2761         ERR("Unable to look up format: 0x%x\n", fmt);
2762         return FALSE;
2763     }
2764     *redSize = count_bits(desc->redMask);
2765     *greenSize = count_bits(desc->greenMask);
2766     *blueSize = count_bits(desc->blueMask);
2767     *alphaSize = count_bits(desc->alphaMask);
2768     *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2769
2770     TRACE("Returning red:  %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n", *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(fmt));
2771     return TRUE;
2772 }
2773
2774 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2775 BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize)
2776 {
2777     const StaticPixelFormatDesc *desc;
2778
2779     TRACE("fmt: %s\n", debug_d3dformat(fmt));
2780     switch(fmt)
2781     {
2782         case WINED3DFMT_D16_LOCKABLE:
2783         case WINED3DFMT_D16:
2784         case WINED3DFMT_D15S1:
2785         case WINED3DFMT_D24X8:
2786         case WINED3DFMT_D24X4S4:
2787         case WINED3DFMT_D24S8:
2788         case WINED3DFMT_D24FS8:
2789         case WINED3DFMT_D32:
2790         case WINED3DFMT_D32F_LOCKABLE:
2791             break;
2792         default:
2793             FIXME("Unsupported stencil format: %s\n", debug_d3dformat(fmt));
2794             return FALSE;
2795     }
2796
2797     desc = getFormatDescEntry(fmt, NULL, NULL);
2798     if(!desc)
2799     {
2800         ERR("Unable to look up format: 0x%x\n", fmt);
2801         return FALSE;
2802     }
2803     *depthSize = desc->depthSize;
2804     *stencilSize = desc->stencilSize;
2805
2806     TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n", *depthSize, *stencilSize, debug_d3dformat(fmt));
2807     return TRUE;
2808 }
2809
2810 #undef GLINFO_LOCATION
2811
2812 /* DirectDraw stuff */
2813 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2814     switch(depth) {
2815         case 8:  return WINED3DFMT_P8;
2816         case 15: return WINED3DFMT_X1R5G5B5;
2817         case 16: return WINED3DFMT_R5G6B5;
2818         case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
2819         case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
2820         default: return WINED3DFMT_UNKNOWN;
2821     }
2822 }
2823
2824 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2825     WINED3DMATRIX temp;
2826
2827     /* Now do the multiplication 'by hand'.
2828        I know that all this could be optimised, but this will be done later :-) */
2829     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);
2830     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);
2831     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);
2832     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);
2833
2834     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);
2835     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);
2836     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);
2837     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);
2838
2839     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);
2840     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);
2841     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);
2842     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);
2843
2844     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);
2845     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);
2846     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);
2847     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);
2848
2849     /* And copy the new matrix in the good storage.. */
2850     memcpy(dest, &temp, 16 * sizeof(float));
2851 }
2852
2853 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2854     DWORD size = 0;
2855     int i;
2856     int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2857
2858     if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2859     if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2860     if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2861     if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2862     switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2863         case WINED3DFVF_XYZ:    size += 3 * sizeof(float); break;
2864         case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2865         case WINED3DFVF_XYZB1:  size += 4 * sizeof(float); break;
2866         case WINED3DFVF_XYZB2:  size += 5 * sizeof(float); break;
2867         case WINED3DFVF_XYZB3:  size += 6 * sizeof(float); break;
2868         case WINED3DFVF_XYZB4:  size += 7 * sizeof(float); break;
2869         case WINED3DFVF_XYZB5:  size += 8 * sizeof(float); break;
2870         default: ERR("Unexpected position mask\n");
2871     }
2872     for (i = 0; i < numTextures; i++) {
2873         size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2874     }
2875
2876     return size;
2877 }
2878
2879 /***********************************************************************
2880  * CalculateTexRect
2881  *
2882  * Calculates the dimensions of the opengl texture used for blits.
2883  * Handled oversized opengl textures and updates the source rectangle
2884  * accordingly
2885  *
2886  * Params:
2887  *  This: Surface to operate on
2888  *  Rect: Requested rectangle
2889  *
2890  * Returns:
2891  *  TRUE if the texture part can be loaded,
2892  *  FALSE otherwise
2893  *
2894  *********************************************************************/
2895 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
2896
2897 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
2898     int x1 = Rect->left, x2 = Rect->right;
2899     int y1 = Rect->top, y2 = Rect->bottom;
2900     GLint maxSize = GL_LIMITS(texture_size);
2901
2902     TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2903           Rect->left, Rect->top, Rect->right, Rect->bottom);
2904
2905     /* The sizes might be reversed */
2906     if(Rect->left > Rect->right) {
2907         x1 = Rect->right;
2908         x2 = Rect->left;
2909     }
2910     if(Rect->top > Rect->bottom) {
2911         y1 = Rect->bottom;
2912         y2 = Rect->top;
2913     }
2914
2915     /* No oversized texture? This is easy */
2916     if(!(This->Flags & SFLAG_OVERSIZE)) {
2917         /* Which rect from the texture do I need? */
2918         if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
2919             glTexCoord[0] = (float) Rect->left;
2920             glTexCoord[2] = (float) Rect->top;
2921             glTexCoord[1] = (float) Rect->right;
2922             glTexCoord[3] = (float) Rect->bottom;
2923         } else {
2924             glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2925             glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2926             glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2927             glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2928         }
2929
2930         return TRUE;
2931     } else {
2932         /* Check if we can succeed at all */
2933         if( (x2 - x1) > maxSize ||
2934             (y2 - y1) > maxSize ) {
2935             TRACE("Requested rectangle is too large for gl\n");
2936             return FALSE;
2937         }
2938
2939         /* A part of the texture has to be picked. First, check if
2940          * some texture part is loaded already, if yes try to re-use it.
2941          * If the texture is dirty, or the part can't be used,
2942          * re-position the part to load
2943          */
2944         if(This->Flags & SFLAG_INTEXTURE) {
2945             if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2946                This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2947                 /* Ok, the rectangle is ok, re-use it */
2948                 TRACE("Using existing gl Texture\n");
2949             } else {
2950                 /* Rectangle is not ok, dirtify the texture to reload it */
2951                 TRACE("Dirtifying texture to force reload\n");
2952                 This->Flags &= ~SFLAG_INTEXTURE;
2953             }
2954         }
2955
2956         /* Now if we are dirty(no else if!) */
2957         if(!(This->Flags & SFLAG_INTEXTURE)) {
2958             /* Set the new rectangle. Use the following strategy:
2959              * 1) Use as big textures as possible.
2960              * 2) Place the texture part in the way that the requested
2961              *    part is in the middle of the texture(well, almost)
2962              * 3) If the texture is moved over the edges of the
2963              *    surface, replace it nicely
2964              * 4) If the coord is not limiting the texture size,
2965              *    use the whole size
2966              */
2967             if((This->pow2Width) > maxSize) {
2968                 This->glRect.left = x1 - maxSize / 2;
2969                 if(This->glRect.left < 0) {
2970                     This->glRect.left = 0;
2971                 }
2972                 This->glRect.right = This->glRect.left + maxSize;
2973                 if(This->glRect.right > This->currentDesc.Width) {
2974                     This->glRect.right = This->currentDesc.Width;
2975                     This->glRect.left = This->glRect.right - maxSize;
2976                 }
2977             } else {
2978                 This->glRect.left = 0;
2979                 This->glRect.right = This->pow2Width;
2980             }
2981
2982             if(This->pow2Height > maxSize) {
2983                 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2984                 if(This->glRect.top < 0) This->glRect.top = 0;
2985                 This->glRect.bottom = This->glRect.left + maxSize;
2986                 if(This->glRect.bottom > This->currentDesc.Height) {
2987                     This->glRect.bottom = This->currentDesc.Height;
2988                     This->glRect.top = This->glRect.bottom - maxSize;
2989                 }
2990             } else {
2991                 This->glRect.top = 0;
2992                 This->glRect.bottom = This->pow2Height;
2993             }
2994             TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2995                    This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2996         }
2997
2998         /* Re-calculate the rect to draw */
2999         Rect->left -= This->glRect.left;
3000         Rect->right -= This->glRect.left;
3001         Rect->top -= This->glRect.top;
3002         Rect->bottom -= This->glRect.top;
3003
3004         /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
3005          * or the pow2Width / pow2Height of the surface.
3006          *
3007          * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
3008          * as regular GL_TEXTURE_2D.
3009          */
3010         glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
3011         glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
3012         glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
3013         glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
3014     }
3015     return TRUE;
3016 }
3017 #undef GLINFO_LOCATION
3018
3019 /* Hash table functions */
3020
3021 hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
3022 {
3023     hash_table_t *table;
3024     unsigned int initial_size = 8;
3025
3026     table = HeapAlloc(GetProcessHeap(), 0, sizeof(hash_table_t) + (initial_size * sizeof(struct list)));
3027     if (!table)
3028     {
3029         ERR("Failed to allocate table, returning NULL.\n");
3030         return NULL;
3031     }
3032
3033     table->hash_function = hash_function;
3034     table->compare_function = compare_function;
3035
3036     table->grow_size = initial_size - (initial_size >> 2);
3037     table->shrink_size = 0;
3038
3039     table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
3040     if (!table->buckets)
3041     {
3042         ERR("Failed to allocate table buckets, returning NULL.\n");
3043         HeapFree(GetProcessHeap(), 0, table);
3044         return NULL;
3045     }
3046     table->bucket_count = initial_size;
3047
3048     table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(hash_table_entry_t));
3049     if (!table->entries)
3050     {
3051         ERR("Failed to allocate table entries, returning NULL.\n");
3052         HeapFree(GetProcessHeap(), 0, table->buckets);
3053         HeapFree(GetProcessHeap(), 0, table);
3054         return NULL;
3055     }
3056     table->entry_count = 0;
3057
3058     list_init(&table->free_entries);
3059     table->count = 0;
3060
3061     return table;
3062 }
3063
3064 void hash_table_destroy(hash_table_t *table)
3065 {
3066     unsigned int i = 0;
3067
3068     for (i = 0; i < table->entry_count; ++i)
3069     {
3070         HeapFree(GetProcessHeap(), 0, table->entries[i].key);
3071     }
3072
3073     HeapFree(GetProcessHeap(), 0, table->entries);
3074     HeapFree(GetProcessHeap(), 0, table->buckets);
3075     HeapFree(GetProcessHeap(), 0, table);
3076 }
3077
3078 static inline hash_table_entry_t *hash_table_get_by_idx(hash_table_t *table, void *key, unsigned int idx)
3079 {
3080     hash_table_entry_t *entry;
3081
3082     if (table->buckets[idx].next)
3083         LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), hash_table_entry_t, entry)
3084             if (table->compare_function(entry->key, key)) return entry;
3085
3086     return NULL;
3087 }
3088
3089 static BOOL hash_table_resize(hash_table_t *table, unsigned int new_bucket_count)
3090 {
3091     unsigned int new_entry_count = 0;
3092     hash_table_entry_t *new_entries;
3093     struct list *new_buckets;
3094     unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
3095     unsigned int i;
3096
3097     new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
3098     if (!new_buckets)
3099     {
3100         ERR("Failed to allocate new buckets, returning FALSE.\n");
3101         return FALSE;
3102     }
3103
3104     new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(hash_table_entry_t));
3105     if (!new_entries)
3106     {
3107         ERR("Failed to allocate new entries, returning FALSE.\n");
3108         HeapFree(GetProcessHeap(), 0, new_buckets);
3109         return FALSE;
3110     }
3111
3112     for (i = 0; i < table->bucket_count; ++i)
3113     {
3114         if (table->buckets[i].next)
3115         {
3116             hash_table_entry_t *entry, *entry2;
3117
3118             LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], hash_table_entry_t, entry)
3119             {
3120                 int j;
3121                 hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
3122                 *new_entry = *entry;
3123
3124                 j = new_entry->hash & (new_bucket_count - 1);
3125
3126                 if (!new_buckets[j].next) list_init(&new_buckets[j]);
3127                 list_add_head(&new_buckets[j], &new_entry->entry);
3128             }
3129         }
3130     }
3131
3132     HeapFree(GetProcessHeap(), 0, table->buckets);
3133     table->buckets = new_buckets;
3134
3135     HeapFree(GetProcessHeap(), 0, table->entries);
3136     table->entries = new_entries;
3137
3138     table->entry_count = new_entry_count;
3139     list_init(&table->free_entries);
3140
3141     table->bucket_count = new_bucket_count;
3142     table->grow_size = grow_size;
3143     table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
3144
3145     return TRUE;
3146 }
3147
3148 void hash_table_put(hash_table_t *table, void *key, void *value)
3149 {
3150     unsigned int idx;
3151     unsigned int hash;
3152     hash_table_entry_t *entry;
3153
3154     hash = table->hash_function(key);
3155     idx = hash & (table->bucket_count - 1);
3156     entry = hash_table_get_by_idx(table, key, idx);
3157
3158     if (entry)
3159     {
3160         HeapFree(GetProcessHeap(), 0, key);
3161         entry->value = value;
3162
3163         if (!value)
3164         {
3165             HeapFree(GetProcessHeap(), 0, entry->key);
3166             entry->key = NULL;
3167
3168             /* Remove the entry */
3169             list_remove(&entry->entry);
3170             list_add_head(&table->free_entries, &entry->entry);
3171
3172             --table->count;
3173
3174             /* Shrink if necessary */
3175             if (table->count < table->shrink_size) {
3176                 if (!hash_table_resize(table, table->bucket_count >> 1))
3177                 {
3178                     ERR("Failed to shrink the table...\n");
3179                 }
3180             }
3181         }
3182
3183         return;
3184     }
3185
3186     if (!value) return;
3187
3188     /* Grow if necessary */
3189     if (table->count >= table->grow_size)
3190     {
3191         if (!hash_table_resize(table, table->bucket_count << 1))
3192         {
3193             ERR("Failed to grow the table, returning.\n");
3194             return;
3195         }
3196
3197         idx = hash & (table->bucket_count - 1);
3198     }
3199
3200     /* Find an entry to insert */
3201     if (!list_empty(&table->free_entries))
3202     {
3203         struct list *elem = list_head(&table->free_entries);
3204
3205         list_remove(elem);
3206         entry = LIST_ENTRY(elem, hash_table_entry_t, entry);
3207     } else {
3208         entry = table->entries + (table->entry_count++);
3209     }
3210
3211     /* Insert the entry */
3212     entry->key = key;
3213     entry->value = value;
3214     entry->hash = hash;
3215     if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
3216     list_add_head(&table->buckets[idx], &entry->entry);
3217
3218     ++table->count;
3219 }
3220
3221 void hash_table_remove(hash_table_t *table, void *key)
3222 {
3223     hash_table_put(table, key, NULL);
3224 }
3225
3226 void *hash_table_get(hash_table_t *table, void *key)
3227 {
3228     unsigned int idx;
3229     hash_table_entry_t *entry;
3230
3231     idx = table->hash_function(key) & (table->bucket_count - 1);
3232     entry = hash_table_get_by_idx(table, key, idx);
3233
3234     return entry ? entry->value : NULL;
3235 }
3236
3237 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
3238 void gen_ffp_op(IWineD3DStateBlockImpl *stateblock, struct texture_stage_op op[MAX_TEXTURES]) {
3239 #define ARG1 0x01
3240 #define ARG2 0x02
3241 #define ARG0 0x04
3242     static const unsigned char args[WINED3DTOP_LERP + 1] = {
3243         /* undefined                        */  0,
3244         /* D3DTOP_DISABLE                   */  0,
3245         /* D3DTOP_SELECTARG1                */  ARG1,
3246         /* D3DTOP_SELECTARG2                */  ARG2,
3247         /* D3DTOP_MODULATE                  */  ARG1 | ARG2,
3248         /* D3DTOP_MODULATE2X                */  ARG1 | ARG2,
3249         /* D3DTOP_MODULATE4X                */  ARG1 | ARG2,
3250         /* D3DTOP_ADD                       */  ARG1 | ARG2,
3251         /* D3DTOP_ADDSIGNED                 */  ARG1 | ARG2,
3252         /* D3DTOP_ADDSIGNED2X               */  ARG1 | ARG2,
3253         /* D3DTOP_SUBTRACT                  */  ARG1 | ARG2,
3254         /* D3DTOP_ADDSMOOTH                 */  ARG1 | ARG2,
3255         /* D3DTOP_BLENDDIFFUSEALPHA         */  ARG1 | ARG2,
3256         /* D3DTOP_BLENDTEXTUREALPHA         */  ARG1 | ARG2,
3257         /* D3DTOP_BLENDFACTORALPHA          */  ARG1 | ARG2,
3258         /* D3DTOP_BLENDTEXTUREALPHAPM       */  ARG1 | ARG2,
3259         /* D3DTOP_BLENDCURRENTALPHA         */  ARG1 | ARG2,
3260         /* D3DTOP_PREMODULATE               */  ARG1 | ARG2,
3261         /* D3DTOP_MODULATEALPHA_ADDCOLOR    */  ARG1 | ARG2,
3262         /* D3DTOP_MODULATECOLOR_ADDALPHA    */  ARG1 | ARG2,
3263         /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */  ARG1 | ARG2,
3264         /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */  ARG1 | ARG2,
3265         /* D3DTOP_BUMPENVMAP                */  ARG1 | ARG2,
3266         /* D3DTOP_BUMPENVMAPLUMINANCE       */  ARG1 | ARG2,
3267         /* D3DTOP_DOTPRODUCT3               */  ARG1 | ARG2,
3268         /* D3DTOP_MULTIPLYADD               */  ARG1 | ARG2 | ARG0,
3269         /* D3DTOP_LERP                      */  ARG1 | ARG2 | ARG0
3270     };
3271     unsigned int i;
3272     DWORD ttff;
3273
3274     for(i = 0; i < GL_LIMITS(texture_stages); i++) {
3275         IWineD3DBaseTextureImpl *texture;
3276         if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
3277             op[i].cop = WINED3DTOP_DISABLE;
3278             op[i].aop = WINED3DTOP_DISABLE;
3279             op[i].carg0 = op[i].carg1 = op[i].carg2 = 0xffffffff;
3280             op[i].aarg0 = op[i].aarg1 = op[i].aarg2 = 0xffffffff;
3281             op[i].color_correction = WINED3DFMT_UNKNOWN;
3282             op[i].dst = 0xffffffff;
3283             i++;
3284             break;
3285         }
3286
3287         texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
3288         op[i].color_correction = texture ? texture->baseTexture.shader_conversion_group : WINED3DFMT_UNKNOWN;
3289
3290         op[i].cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
3291         op[i].aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
3292
3293         op[i].carg1 = (args[op[i].cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : 0xffffffff;
3294         op[i].carg2 = (args[op[i].cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : 0xffffffff;
3295         op[i].carg0 = (args[op[i].cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : 0xffffffff;
3296
3297         if(is_invalid_op(stateblock->wineD3DDevice, i, op[i].cop, op[i].carg1, op[i].carg2, op[i].carg0)) {
3298             op[i].carg0 = 0xffffffff;
3299             op[i].carg2 = 0xffffffff;
3300             op[i].carg1 = WINED3DTA_CURRENT;
3301             op[i].cop = WINED3DTOP_SELECTARG1;
3302         }
3303
3304         op[i].aarg1 = (args[op[i].aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : 0xffffffff;
3305         op[i].aarg2 = (args[op[i].aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : 0xffffffff;
3306         op[i].aarg0 = (args[op[i].aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : 0xffffffff;
3307
3308         if(is_invalid_op(stateblock->wineD3DDevice, i, op[i].aop, op[i].aarg1, op[i].aarg2, op[i].aarg0)) {
3309             op[i].aarg0 = 0xffffffff;
3310             op[i].aarg2 = 0xffffffff;
3311             op[i].aarg1 = WINED3DTA_CURRENT;
3312             op[i].aop = WINED3DTOP_SELECTARG1;
3313         } else if(i == 0 && stateblock->textures[0] &&
3314                   stateblock->renderState[WINED3DRS_COLORKEYENABLE] &&
3315                  (stateblock->textureDimensions[0] == GL_TEXTURE_2D ||
3316                   stateblock->textureDimensions[0] == GL_TEXTURE_RECTANGLE_ARB)) {
3317             IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
3318
3319             if(surf->CKeyFlags & WINEDDSD_CKSRCBLT &&
3320                getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000) {
3321
3322                 if(op[0].aop == WINED3DTOP_DISABLE) {
3323                     op[0].aarg1 = WINED3DTA_TEXTURE;
3324                     op[0].aop = WINED3DTOP_SELECTARG1;
3325                 }
3326                 else if(op[0].aop == WINED3DTOP_SELECTARG1 && op[0].aarg1 != WINED3DTA_TEXTURE) {
3327                     if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
3328                         op[0].aarg2 = WINED3DTA_TEXTURE;
3329                         op[0].aop = WINED3DTOP_MODULATE;
3330                     }
3331                     else op[0].aarg1 = WINED3DTA_TEXTURE;
3332                 }
3333                 else if(op[0].aop == WINED3DTOP_SELECTARG2 && op[0].aarg2 != WINED3DTA_TEXTURE) {
3334                     if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
3335                         op[0].aarg1 = WINED3DTA_TEXTURE;
3336                         op[0].aop = WINED3DTOP_MODULATE;
3337                     }
3338                     else op[0].aarg2 = WINED3DTA_TEXTURE;
3339                 }
3340             }
3341         }
3342
3343         if(op[i].carg1 == WINED3DTA_TEXTURE || op[i].carg2 == WINED3DTA_TEXTURE || op[i].carg0 == WINED3DTA_TEXTURE ||
3344            op[i].aarg1 == WINED3DTA_TEXTURE || op[i].aarg2 == WINED3DTA_TEXTURE || op[i].aarg0 == WINED3DTA_TEXTURE) {
3345             ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
3346             if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
3347                 op[i].projected = proj_count3;
3348             } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
3349                 op[i].projected = proj_count4;
3350             } else {
3351                 op[i].projected = proj_none;
3352             }
3353         } else {
3354             op[i].projected = proj_none;
3355         }
3356
3357         op[i].dst = stateblock->textureState[i][WINED3DTSS_RESULTARG];
3358     }
3359
3360     /* Clear unsupported stages */
3361     for(; i < MAX_TEXTURES; i++) {
3362         memset(&op[i], 0xff, sizeof(op[i]));
3363     }
3364 }
3365 #undef GLINFO_LOCATION
3366
3367 struct ffp_desc *find_ffp_shader(struct list *shaders, struct texture_stage_op op[MAX_TEXTURES])
3368 {
3369     struct ffp_desc *entry;
3370
3371     /* TODO: Optimize this. Finding the shader can be optimized by e.g. sorting the list,
3372      * or maybe consider using hashtables
3373      */
3374     LIST_FOR_EACH_ENTRY(entry, shaders, struct ffp_desc, entry) {
3375         if(memcmp(op, entry->op, sizeof(struct texture_stage_op) * MAX_TEXTURES) == 0) {
3376             TRACE("Found shader entry %p\n", entry);
3377             return entry;
3378         }
3379     }
3380
3381     TRACE("Shader not found\n");
3382     return NULL;
3383 }
3384
3385 void add_ffp_shader(struct list *shaders, struct ffp_desc *desc) {
3386     list_add_head(shaders, &desc->entry);
3387 }
3388
3389 /* Activates the texture dimension according to the bound D3D texture.
3390  * Does not care for the colorop or correct gl texture unit(when using nvrc)
3391  * Requires the caller to activate the correct unit before
3392  */
3393 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
3394 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3395     BOOL bumpmap = FALSE;
3396
3397     if(stage > 0 && (stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAPLUMINANCE ||
3398                      stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAP)) {
3399         bumpmap = TRUE;
3400         context->texShaderBumpMap |= (1 << stage);
3401     } else {
3402         context->texShaderBumpMap &= ~(1 << stage);
3403     }
3404
3405     if(stateblock->textures[stage]) {
3406         switch(stateblock->textureDimensions[stage]) {
3407             case GL_TEXTURE_2D:
3408                 if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
3409                     glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_2D);
3410                     checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
3411                 } else {
3412                     glDisable(GL_TEXTURE_3D);
3413                     checkGLcall("glDisable(GL_TEXTURE_3D)");
3414                     if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
3415                         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3416                         checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3417                     }
3418                     if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
3419                         glDisable(GL_TEXTURE_RECTANGLE_ARB);
3420                         checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3421                     }
3422                     glEnable(GL_TEXTURE_2D);
3423                     checkGLcall("glEnable(GL_TEXTURE_2D)");
3424                 }
3425                 break;
3426             case GL_TEXTURE_RECTANGLE_ARB:
3427                 if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
3428                     glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_RECTANGLE_ARB);
3429                     checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
3430                 } else {
3431                     glDisable(GL_TEXTURE_2D);
3432                     checkGLcall("glDisable(GL_TEXTURE_2D)");
3433                     glDisable(GL_TEXTURE_3D);
3434                     checkGLcall("glDisable(GL_TEXTURE_3D)");
3435                     if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
3436                         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3437                         checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3438                     }
3439                     glEnable(GL_TEXTURE_RECTANGLE_ARB);
3440                     checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3441                 }
3442                 break;
3443             case GL_TEXTURE_3D:
3444                 if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
3445                     glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D);
3446                     checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D)");
3447                 } else {
3448                     if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
3449                         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3450                         checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3451                     }
3452                     if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
3453                         glDisable(GL_TEXTURE_RECTANGLE_ARB);
3454                         checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3455                     }
3456                     glDisable(GL_TEXTURE_2D);
3457                     checkGLcall("glDisable(GL_TEXTURE_2D)");
3458                     glEnable(GL_TEXTURE_3D);
3459                     checkGLcall("glEnable(GL_TEXTURE_3D)");
3460                 }
3461                 break;
3462             case GL_TEXTURE_CUBE_MAP_ARB:
3463                 if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
3464                     glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB);
3465                     checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB)");
3466                 } else {
3467                     glDisable(GL_TEXTURE_2D);
3468                     checkGLcall("glDisable(GL_TEXTURE_2D)");
3469                     glDisable(GL_TEXTURE_3D);
3470                     checkGLcall("glDisable(GL_TEXTURE_3D)");
3471                     if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
3472                         glDisable(GL_TEXTURE_RECTANGLE_ARB);
3473                         checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3474                     }
3475                     glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3476                     checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3477                 }
3478               break;
3479         }
3480     } else {
3481         if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
3482             glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
3483             checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE)");
3484         } else {
3485             glEnable(GL_TEXTURE_2D);
3486             checkGLcall("glEnable(GL_TEXTURE_2D)");
3487             glDisable(GL_TEXTURE_3D);
3488             checkGLcall("glDisable(GL_TEXTURE_3D)");
3489             if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
3490                 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3491                 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3492             }
3493             if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
3494                 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3495                 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3496             }
3497             /* Binding textures is done by samplers. A dummy texture will be bound */
3498         }
3499     }
3500 }
3501 #undef GLINFO_LOCATION