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