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