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