wined3d: Remove a useless FIXME.
[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-2008 Henri Verbeet
9  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25
26 #include "config.h"
27 #include "wined3d_private.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
30
31 /*****************************************************************************
32  * Pixel format array
33  *
34  * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
35  * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
36  * high masks do not fit into the 32 bit values needed for ddraw. It is only
37  * used for ddraw mostly, and to figure out if the format has alpha at all, so
38  * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
39  * formats are not usable in 2D rendering because ddraw doesn't support them.
40  */
41 static const StaticPixelFormatDesc formats[] = {
42   /*{WINED3DFORMAT          ,alphamask  ,redmask    ,greenmask  ,bluemask   ,bpp    ,depth  ,stencil,    isFourcc*/
43     {WINED3DFMT_UNKNOWN     ,0x0        ,0x0        ,0x0        ,0x0        ,1      ,0      ,0          ,FALSE },
44     /* FourCC formats, kept here to have WINED3DFMT_R8G8B8(=20) at position 20 */
45     {WINED3DFMT_UYVY        ,0x0        ,0x0        ,0x0        ,0x0        ,2      ,0      ,0          ,TRUE  },
46     {WINED3DFMT_YUY2        ,0x0        ,0x0        ,0x0        ,0x0        ,2      ,0      ,0          ,TRUE  },
47     {WINED3DFMT_YV12        ,0x0        ,0x0        ,0x0        ,0x0        ,1      ,0      ,0          ,TRUE  },
48     {WINED3DFMT_DXT1        ,0x0        ,0x0        ,0x0        ,0x0        ,1      ,0      ,0          ,TRUE  },
49     {WINED3DFMT_DXT2        ,0x0        ,0x0        ,0x0        ,0x0        ,1      ,0      ,0          ,TRUE  },
50     {WINED3DFMT_DXT3        ,0x0        ,0x0        ,0x0        ,0x0        ,1      ,0      ,0          ,TRUE  },
51     {WINED3DFMT_DXT4        ,0x0        ,0x0        ,0x0        ,0x0        ,1      ,0      ,0          ,TRUE  },
52     {WINED3DFMT_DXT5        ,0x0        ,0x0        ,0x0        ,0x0        ,1      ,0      ,0          ,TRUE  },
53     {WINED3DFMT_MULTI2_ARGB8,0x0        ,0x0        ,0x0        ,0x0        ,1/*?*/ ,0      ,0          ,TRUE  },
54     {WINED3DFMT_G8R8_G8B8   ,0x0        ,0x0        ,0x0        ,0x0        ,1/*?*/ ,0      ,0          ,TRUE  },
55     {WINED3DFMT_R8G8_B8G8   ,0x0        ,0x0        ,0x0        ,0x0        ,1/*?*/ ,0      ,0          ,TRUE  },
56     /* IEEE formats */
57     {WINED3DFMT_R32F        ,0x0        ,0x0        ,0x0        ,0x0        ,4      ,0      ,0          ,FALSE },
58     {WINED3DFMT_G32R32F     ,0x0        ,0x0        ,0x0        ,0x0        ,8      ,0      ,0          ,FALSE },
59     {WINED3DFMT_A32B32G32R32F,0x1       ,0x0        ,0x0        ,0x0        ,16     ,0      ,0          ,FALSE },
60     /* Hmm? */
61     {WINED3DFMT_CxV8U8      ,0x0        ,0x0        ,0x0        ,0x0        ,2      ,0      ,0          ,FALSE },
62     /* Float */
63     {WINED3DFMT_R16F        ,0x0        ,0x0        ,0x0        ,0x0        ,2      ,0      ,0          ,FALSE },
64     {WINED3DFMT_G16R16F     ,0x0        ,0x0        ,0x0        ,0x0        ,4      ,0      ,0          ,FALSE },
65     {WINED3DFMT_A16B16G16R16F,0x1       ,0x0        ,0x0        ,0x0        ,8      ,0      ,0          ,FALSE },
66     /* Palettized formats */
67     {WINED3DFMT_A8P8        ,0x0000ff00 ,0x0        ,0x0        ,0x0        ,2      ,0      ,0          ,FALSE },
68     {WINED3DFMT_P8          ,0x0        ,0x0        ,0x0        ,0x0        ,1      ,0      ,0          ,FALSE },
69     /* Standard ARGB formats. Keep WINED3DFMT_R8G8B8(=20) at position 20 */
70     {WINED3DFMT_R8G8B8      ,0x0        ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,3      ,0      ,0          ,FALSE },
71     {WINED3DFMT_A8R8G8B8    ,0xff000000 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4      ,0      ,0          ,FALSE },
72     {WINED3DFMT_X8R8G8B8    ,0x0        ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4      ,0      ,0          ,FALSE },
73     {WINED3DFMT_R5G6B5      ,0x0        ,0x0000F800 ,0x000007e0 ,0x0000001f ,2      ,0      ,0          ,FALSE },
74     {WINED3DFMT_X1R5G5B5    ,0x0        ,0x00007c00 ,0x000003e0 ,0x0000001f ,2      ,0      ,0          ,FALSE },
75     {WINED3DFMT_A1R5G5B5    ,0x00008000 ,0x00007c00 ,0x000003e0 ,0x0000001f ,2      ,0      ,0          ,FALSE },
76     {WINED3DFMT_A4R4G4B4    ,0x0000f000 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2      ,0      ,0          ,FALSE },
77     {WINED3DFMT_R3G3B2      ,0x0        ,0x000000e0 ,0x0000001c ,0x00000003 ,1      ,0      ,0          ,FALSE },
78     {WINED3DFMT_A8          ,0x000000ff ,0x0        ,0x0        ,0x0        ,1      ,0      ,0          ,FALSE },
79     {WINED3DFMT_A8R3G3B2    ,0x0000ff00 ,0x000000e0 ,0x0000001c ,0x00000003 ,2      ,0      ,0          ,FALSE },
80     {WINED3DFMT_X4R4G4B4    ,0x0        ,0x00000f00 ,0x000000f0 ,0x0000000f ,2      ,0      ,0          ,FALSE },
81     {WINED3DFMT_A2B10G10R10 ,0xb0000000 ,0x000003ff ,0x000ffc00 ,0x3ff00000 ,4      ,0      ,0          ,FALSE },
82     {WINED3DFMT_A8B8G8R8    ,0xff000000 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4      ,0      ,0          ,FALSE },
83     {WINED3DFMT_X8B8G8R8    ,0x0        ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4      ,0      ,0          ,FALSE },
84     {WINED3DFMT_G16R16      ,0x0        ,0x0000ffff ,0xffff0000 ,0x0        ,4      ,0      ,0          ,FALSE },
85     {WINED3DFMT_A2R10G10B10 ,0xb0000000 ,0x3ff00000 ,0x000ffc00 ,0x000003ff ,4      ,0      ,0          ,FALSE },
86     {WINED3DFMT_A16B16G16R16,0x1        ,0x0000ffff ,0xffff0000 ,0x0        ,8      ,0      ,0          ,FALSE },
87     /* Luminance */
88     {WINED3DFMT_L8          ,0x0        ,0x0        ,0x0        ,0x0        ,1      ,0      ,0          ,FALSE },
89     {WINED3DFMT_A8L8        ,0x0000ff00 ,0x0        ,0x0        ,0x0        ,2      ,0      ,0          ,FALSE },
90     {WINED3DFMT_A4L4        ,0x000000f0 ,0x0        ,0x0        ,0x0        ,1      ,0      ,0          ,FALSE },
91     /* Bump mapping stuff */
92     {WINED3DFMT_V8U8        ,0x0        ,0x0        ,0x0        ,0x0        ,2      ,0      ,0          ,FALSE },
93     {WINED3DFMT_L6V5U5      ,0x0        ,0x0        ,0x0        ,0x0        ,2      ,0      ,0          ,FALSE },
94     {WINED3DFMT_X8L8V8U8    ,0x0        ,0x0        ,0x0        ,0x0        ,4      ,0      ,0          ,FALSE },
95     {WINED3DFMT_Q8W8V8U8    ,0x0        ,0x0        ,0x0        ,0x0        ,4      ,0      ,0          ,FALSE },
96     {WINED3DFMT_V16U16      ,0x0        ,0x0        ,0x0        ,0x0        ,4      ,0      ,0          ,FALSE },
97     {WINED3DFMT_W11V11U10   ,0x0        ,0x0        ,0x0        ,0x0        ,4      ,0      ,0          ,FALSE },
98     {WINED3DFMT_A2W10V10U10 ,0xb0000000 ,0x0        ,0x0        ,0x0        ,4      ,0      ,0          ,FALSE },
99     /* Depth stencil formats */
100     {WINED3DFMT_D16_LOCKABLE,0x0        ,0x0        ,0x0        ,0x0        ,2      ,16     ,0          ,FALSE },
101     {WINED3DFMT_D32         ,0x0        ,0x0        ,0x0        ,0x0        ,4      ,32     ,0          ,FALSE },
102     {WINED3DFMT_D15S1       ,0x0        ,0x0        ,0x0        ,0x0        ,2      ,15     ,1          ,FALSE },
103     {WINED3DFMT_D24S8       ,0x0        ,0x0        ,0x0        ,0x0        ,4      ,24     ,8          ,FALSE },
104     {WINED3DFMT_D24X8       ,0x0        ,0x0        ,0x0        ,0x0        ,4      ,24     ,0          ,FALSE },
105     {WINED3DFMT_D24X4S4     ,0x0        ,0x0        ,0x0        ,0x0        ,4      ,24     ,4          ,FALSE },
106     {WINED3DFMT_D16         ,0x0        ,0x0        ,0x0        ,0x0        ,2      ,16     ,0          ,FALSE },
107     {WINED3DFMT_L16         ,0x0        ,0x0        ,0x0        ,0x0        ,2      ,16      ,0          ,FALSE },
108     {WINED3DFMT_D32F_LOCKABLE,0x0       ,0x0        ,0x0        ,0x0        ,4      ,32     ,0          ,FALSE },
109     {WINED3DFMT_D24FS8      ,0x0        ,0x0        ,0x0        ,0x0        ,4      ,24     ,8          ,FALSE },
110     /* Is this a vertex buffer? */
111     {WINED3DFMT_VERTEXDATA  ,0x0        ,0x0        ,0x0        ,0x0        ,0      ,0      ,0          ,FALSE },
112     {WINED3DFMT_INDEX16     ,0x0        ,0x0        ,0x0        ,0x0        ,2      ,0      ,0          ,FALSE },
113     {WINED3DFMT_INDEX32     ,0x0        ,0x0        ,0x0        ,0x0        ,4      ,0      ,0          ,FALSE },
114     {WINED3DFMT_Q16W16V16U16,0x0        ,0x0        ,0x0        ,0x0        ,8      ,0      ,0          ,FALSE },
115     /* Vendor-specific formats */
116     {WINED3DFMT_ATI2N       ,0x0        ,0x0        ,0x0        ,0x0        ,1      ,0      ,0          ,TRUE  },
117     {WINED3DFMT_NVHU        ,0x0        ,0x0        ,0x0        ,0x0        ,2      ,0      ,0          ,TRUE  },
118     {WINED3DFMT_NVHS        ,0x0        ,0x0        ,0x0        ,0x0        ,2      ,0      ,0          ,TRUE  },
119 };
120
121 typedef struct {
122     WINED3DFORMAT           fmt;
123     GLint                   glInternal, glGammaInternal, rtInternal, glFormat, glType;
124     unsigned int            Flags;
125 } GlPixelFormatDescTemplate;
126
127 /*****************************************************************************
128  * OpenGL format template. Contains unexciting formats which do not need
129  * extension checks. The order in this table is independent of the order in
130  * the table StaticPixelFormatDesc above. Not all formats have to be in this
131  * table.
132  */
133 static const GlPixelFormatDescTemplate gl_formats_template[] = {
134   /*{                           internal                         ,srgbInternal                           , rtInternal,  format                    ,type \
135         ,Flags }*/
136     {WINED3DFMT_UNKNOWN        ,0                                ,0                                      , 0,           0                         ,0
137         ,0 },
138     /* FourCC formats */
139     /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
140      * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
141      * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
142      * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
143      * endian machine
144      */
145     {WINED3DFMT_UYVY           ,GL_RGB                           ,GL_RGB                                 , 0,           GL_YCBCR_422_APPLE        ,UNSIGNED_SHORT_8_8_APPLE
146         ,WINED3DFMT_FLAG_FILTERING },
147     {WINED3DFMT_YUY2           ,GL_RGB                           ,GL_RGB                                 , 0,           GL_YCBCR_422_APPLE        ,UNSIGNED_SHORT_8_8_REV_APPLE
148         ,WINED3DFMT_FLAG_FILTERING },
149     {WINED3DFMT_YV12           ,GL_ALPHA                         ,GL_ALPHA                               , 0,           GL_ALPHA                  ,GL_UNSIGNED_BYTE
150         ,WINED3DFMT_FLAG_FILTERING },
151     {WINED3DFMT_DXT1           ,GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT , 0,           GL_RGBA                   ,GL_UNSIGNED_BYTE
152         ,WINED3DFMT_FLAG_FILTERING },
153     {WINED3DFMT_DXT2           ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT , 0,           GL_RGBA                   ,GL_UNSIGNED_BYTE
154         ,WINED3DFMT_FLAG_FILTERING },
155     {WINED3DFMT_DXT3           ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT , 0,           GL_RGBA                   ,GL_UNSIGNED_BYTE
156         ,WINED3DFMT_FLAG_FILTERING },
157     {WINED3DFMT_DXT4           ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT , 0,           GL_RGBA                   ,GL_UNSIGNED_BYTE
158         ,WINED3DFMT_FLAG_FILTERING },
159     {WINED3DFMT_DXT5           ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT , 0,           GL_RGBA                   ,GL_UNSIGNED_BYTE
160         ,WINED3DFMT_FLAG_FILTERING },
161     {WINED3DFMT_MULTI2_ARGB8   ,0                                ,0                                      , 0,           0                         ,0
162         ,0 },
163     {WINED3DFMT_G8R8_G8B8      ,0                                ,0                                      , 0,           0                         ,0
164         ,0 },
165     {WINED3DFMT_R8G8_B8G8      ,0                                ,0                                      , 0,           0                         ,0
166         ,0 },
167     /* IEEE formats */
168     {WINED3DFMT_R32F           ,GL_RGB32F_ARB                    ,GL_RGB32F_ARB                          , 0,           GL_RED                    ,GL_FLOAT
169         ,WINED3DFMT_FLAG_RENDERTARGET },
170     {WINED3DFMT_G32R32F        ,GL_RG32F                         ,GL_RG32F                               , 0,           GL_RG                     ,GL_FLOAT
171         ,WINED3DFMT_FLAG_RENDERTARGET },
172     {WINED3DFMT_A32B32G32R32F  ,GL_RGBA32F_ARB                   ,GL_RGBA32F_ARB                         , 0,           GL_RGBA                   ,GL_FLOAT
173         ,WINED3DFMT_FLAG_RENDERTARGET },
174     /* Hmm? */
175     {WINED3DFMT_CxV8U8         ,0                                ,0                                      , 0,           0                         ,0
176         ,0 },
177     /* Float */
178     {WINED3DFMT_R16F           ,GL_RGB16F_ARB                    ,GL_RGB16F_ARB                          , 0,           GL_RED                    ,GL_HALF_FLOAT_ARB
179         ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
180     {WINED3DFMT_G16R16F        ,GL_RG16F                         ,GL_RG16F                               , 0,           GL_RG                     ,GL_HALF_FLOAT_ARB
181         ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
182     {WINED3DFMT_A16B16G16R16F  ,GL_RGBA16F_ARB                   ,GL_RGBA16F_ARB                         , 0,           GL_RGBA                   ,GL_HALF_FLOAT_ARB
183         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
184     /* Palettized formats */
185     {WINED3DFMT_A8P8,           0                                ,0                                      , 0,           0                         ,0
186         ,0 },
187     {WINED3DFMT_P8,             GL_COLOR_INDEX8_EXT              ,GL_COLOR_INDEX8_EXT                    , 0,           GL_COLOR_INDEX            ,GL_UNSIGNED_BYTE
188         ,0 },
189     /* Standard ARGB formats */
190     {WINED3DFMT_R8G8B8         ,GL_RGB8                          ,GL_RGB8                                , 0,           GL_BGR                    ,GL_UNSIGNED_BYTE
191         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
192     {WINED3DFMT_A8R8G8B8       ,GL_RGBA8                         ,GL_SRGB8_ALPHA8_EXT                    , 0,           GL_BGRA                   ,GL_UNSIGNED_INT_8_8_8_8_REV
193         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
194     {WINED3DFMT_X8R8G8B8       ,GL_RGB8                          ,GL_SRGB8_EXT                           , 0,           GL_BGRA                   ,GL_UNSIGNED_INT_8_8_8_8_REV
195         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
196     {WINED3DFMT_R5G6B5         ,GL_RGB5                          ,GL_RGB5                                , GL_RGB8,     GL_RGB                    ,GL_UNSIGNED_SHORT_5_6_5
197         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
198     {WINED3DFMT_X1R5G5B5       ,GL_RGB5                          ,GL_RGB5_A1                             , 0,           GL_BGRA                   ,GL_UNSIGNED_SHORT_1_5_5_5_REV
199         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING },
200     {WINED3DFMT_A1R5G5B5       ,GL_RGB5_A1                       ,GL_RGB5_A1                             , 0,           GL_BGRA                   ,GL_UNSIGNED_SHORT_1_5_5_5_REV
201         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING },
202     {WINED3DFMT_A4R4G4B4       ,GL_RGBA4                         ,GL_SRGB8_ALPHA8_EXT                    , 0,           GL_BGRA                   ,GL_UNSIGNED_SHORT_4_4_4_4_REV
203         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING },
204     {WINED3DFMT_R3G3B2         ,GL_R3_G3_B2                      ,GL_R3_G3_B2                            , 0,           GL_RGB                    ,GL_UNSIGNED_BYTE_3_3_2
205         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING },
206     {WINED3DFMT_A8             ,GL_ALPHA8                        ,GL_ALPHA8                              , 0,           GL_ALPHA                  ,GL_UNSIGNED_BYTE
207         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING },
208     {WINED3DFMT_A8R3G3B2       ,0                                ,0                                      , 0,           0                         ,0
209         ,0 },
210     {WINED3DFMT_X4R4G4B4       ,GL_RGB4                          ,GL_RGB4                                , 0,           GL_BGRA                   ,GL_UNSIGNED_SHORT_4_4_4_4_REV
211         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
212     {WINED3DFMT_A2B10G10R10    ,GL_RGB10_A2                      ,GL_RGB10_A2                            , 0,           GL_RGBA                   ,GL_UNSIGNED_INT_2_10_10_10_REV
213         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
214     {WINED3DFMT_A8B8G8R8       ,GL_RGBA8                         ,GL_RGBA8                               , 0,           GL_RGBA                   ,GL_UNSIGNED_INT_8_8_8_8_REV
215         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
216     {WINED3DFMT_X8B8G8R8       ,GL_RGB8                          ,GL_RGB8                                , 0,           GL_RGBA                   ,GL_UNSIGNED_INT_8_8_8_8_REV
217         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
218     {WINED3DFMT_G16R16         ,GL_RGB16_EXT                     ,GL_RGB16_EXT                           , 0,           GL_RGB                    ,GL_UNSIGNED_SHORT
219         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING },
220     {WINED3DFMT_A2R10G10B10    ,GL_RGB10_A2                      ,GL_RGB10_A2                            , 0,           GL_BGRA                   ,GL_UNSIGNED_INT_2_10_10_10_REV
221         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING },
222     {WINED3DFMT_A16B16G16R16   ,GL_RGBA16_EXT                    ,GL_RGBA16_EXT                          , 0,           GL_RGBA                   ,GL_UNSIGNED_SHORT
223         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
224     /* Luminance */
225     {WINED3DFMT_L8             ,GL_LUMINANCE8                    ,GL_SLUMINANCE8_EXT                     , 0,           GL_LUMINANCE              ,GL_UNSIGNED_BYTE
226         ,WINED3DFMT_FLAG_FILTERING },
227     {WINED3DFMT_A8L8           ,GL_LUMINANCE8_ALPHA8             ,GL_SLUMINANCE8_ALPHA8_EXT              , 0,           GL_LUMINANCE_ALPHA        ,GL_UNSIGNED_BYTE
228         ,WINED3DFMT_FLAG_FILTERING },
229     {WINED3DFMT_A4L4           ,GL_LUMINANCE4_ALPHA4             ,GL_LUMINANCE4_ALPHA4                   , 0,           GL_LUMINANCE_ALPHA        ,GL_UNSIGNED_BYTE
230         ,0 },
231     /* Bump mapping stuff */
232     {WINED3DFMT_V8U8           ,GL_DSDT8_NV                      ,GL_DSDT8_NV                            , 0,           GL_DSDT_NV                ,GL_BYTE
233         ,WINED3DFMT_FLAG_FILTERING },
234     {WINED3DFMT_L6V5U5         ,GL_DSDT8_MAG8_NV                 ,GL_DSDT8_MAG8_NV                       , 0,           GL_DSDT_MAG_NV            ,GL_BYTE
235         ,WINED3DFMT_FLAG_FILTERING },
236     {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
237         ,WINED3DFMT_FLAG_FILTERING },
238     {WINED3DFMT_Q8W8V8U8       ,GL_SIGNED_RGBA8_NV               ,GL_SIGNED_RGBA8_NV                     , 0,           GL_RGBA                   ,GL_BYTE
239         ,WINED3DFMT_FLAG_FILTERING },
240     {WINED3DFMT_V16U16         ,GL_SIGNED_HILO16_NV              ,GL_SIGNED_HILO16_NV                    , 0,           GL_HILO_NV                ,GL_SHORT
241         ,WINED3DFMT_FLAG_FILTERING },
242     {WINED3DFMT_W11V11U10      ,0                                ,0                                      , 0,           0                         ,0
243         ,0 },
244     {WINED3DFMT_A2W10V10U10    ,0                                ,0                                      , 0,           0                         ,0
245         ,0 },
246     /* Depth stencil formats */
247     {WINED3DFMT_D16_LOCKABLE   ,GL_DEPTH_COMPONENT24_ARB         ,GL_DEPTH_COMPONENT24_ARB               , 0,           GL_DEPTH_COMPONENT        ,GL_UNSIGNED_SHORT
248         ,WINED3DFMT_FLAG_DEPTH },
249     {WINED3DFMT_D32            ,GL_DEPTH_COMPONENT32_ARB         ,GL_DEPTH_COMPONENT32_ARB               , 0,           GL_DEPTH_COMPONENT        ,GL_UNSIGNED_INT
250         ,WINED3DFMT_FLAG_DEPTH },
251     {WINED3DFMT_D15S1          ,GL_DEPTH_COMPONENT24_ARB         ,GL_DEPTH_COMPONENT24_ARB               , 0,           GL_DEPTH_COMPONENT        ,GL_UNSIGNED_SHORT
252         ,WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL },
253     {WINED3DFMT_D24S8          ,GL_DEPTH_COMPONENT24_ARB         ,GL_DEPTH_COMPONENT24_ARB               , 0,           GL_DEPTH_COMPONENT        ,GL_UNSIGNED_INT
254         ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL },
255     {WINED3DFMT_D24X8          ,GL_DEPTH_COMPONENT24_ARB         ,GL_DEPTH_COMPONENT24_ARB               , 0,           GL_DEPTH_COMPONENT        ,GL_UNSIGNED_INT
256         ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH },
257     {WINED3DFMT_D24X4S4        ,GL_DEPTH_COMPONENT24_ARB         ,GL_DEPTH_COMPONENT24_ARB               , 0,           GL_DEPTH_COMPONENT        ,GL_UNSIGNED_INT
258         ,WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL },
259     {WINED3DFMT_D16            ,GL_DEPTH_COMPONENT24_ARB         ,GL_DEPTH_COMPONENT24_ARB               , 0,           GL_DEPTH_COMPONENT        ,GL_UNSIGNED_SHORT
260         ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH },
261     {WINED3DFMT_L16            ,GL_LUMINANCE16_EXT               ,GL_LUMINANCE16_EXT                     , 0,           GL_LUMINANCE              ,GL_UNSIGNED_SHORT
262         ,WINED3DFMT_FLAG_FILTERING },
263     {WINED3DFMT_D32F_LOCKABLE  ,GL_DEPTH_COMPONENT32_ARB         ,GL_DEPTH_COMPONENT32_ARB               , 0,           GL_DEPTH_COMPONENT        ,GL_FLOAT
264         ,WINED3DFMT_FLAG_DEPTH },
265     {WINED3DFMT_D24FS8         ,GL_DEPTH_COMPONENT24_ARB         ,GL_DEPTH_COMPONENT24_ARB               , 0,           GL_DEPTH_COMPONENT        ,GL_FLOAT
266         ,WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
267     /* Is this a vertex buffer? */
268     {WINED3DFMT_VERTEXDATA     ,0                                ,0                                      , 0,           0                         ,0
269         ,0 },
270     {WINED3DFMT_INDEX16        ,0                                ,0                                      , 0,           0                         ,0
271         ,0 },
272     {WINED3DFMT_INDEX32        ,0                                ,0                                      , 0,           0                         ,0
273         ,0 },
274     {WINED3DFMT_Q16W16V16U16   ,GL_COLOR_INDEX                   ,GL_COLOR_INDEX                         , 0,           GL_COLOR_INDEX            ,GL_UNSIGNED_SHORT
275         ,0 },
276     /* Vendor-specific formats */
277     {WINED3DFMT_ATI2N          ,0                                ,0                                      , 0,           GL_LUMINANCE_ALPHA        ,GL_UNSIGNED_BYTE
278         ,0 },
279     {WINED3DFMT_NVHU           ,0                                ,0                                      , 0,           GL_LUMINANCE_ALPHA        ,GL_UNSIGNED_BYTE
280         ,0 },
281     {WINED3DFMT_NVHS           ,0                                ,0                                      , 0,           GL_LUMINANCE_ALPHA        ,GL_UNSIGNED_BYTE
282         ,0 }
283 };
284
285 static inline int getFmtIdx(WINED3DFORMAT fmt) {
286     /* First check if the format is at the position of its value.
287      * This will catch the argb formats before the loop is entered
288      */
289     if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
290         return fmt;
291     } else {
292         unsigned int i;
293         for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
294             if(formats[i].format == fmt) {
295                 return i;
296             }
297         }
298     }
299     return -1;
300 }
301
302 #define GLINFO_LOCATION (*gl_info)
303 BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
304 {
305     unsigned int src;
306     int dst;
307
308     gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
309                                     sizeof(formats) / sizeof(formats[0]) * sizeof(gl_info->gl_formats[0]));
310     if(!gl_info->gl_formats) return FALSE;
311
312     /* If a format depends on some extensions, remove them from the table above and initialize them
313      * after this loop
314      */
315     for(src = 0; src < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); src++) {
316         dst = getFmtIdx(gl_formats_template[src].fmt);
317         gl_info->gl_formats[dst].glInternal      = gl_formats_template[src].glInternal;
318         gl_info->gl_formats[dst].glGammaInternal = gl_formats_template[src].glGammaInternal;
319         gl_info->gl_formats[dst].glFormat        = gl_formats_template[src].glFormat;
320         gl_info->gl_formats[dst].glType          = gl_formats_template[src].glType;
321         gl_info->gl_formats[dst].color_fixup     = COLOR_FIXUP_IDENTITY;
322         gl_info->gl_formats[dst].Flags           = gl_formats_template[src].Flags;
323         gl_info->gl_formats[dst].heightscale     = 1.0;
324
325         if(wined3d_settings.offscreen_rendering_mode == ORM_FBO &&
326            gl_formats_template[src].rtInternal != 0) {
327             GLuint tex, fb;
328             GLenum status;
329
330             /* Check if the default internal format is supported as a frame buffer target, otherwise
331              * fall back to the render target internal.
332              *
333              * Try to stick to the standard format if possible, this limits precision differences
334              */
335             while(glGetError());
336             glGenTextures(1, &tex);
337             glBindTexture(GL_TEXTURE_2D, tex);
338             glTexImage2D(GL_TEXTURE_2D, 0, gl_formats_template[src].glInternal, 16, 16, 0,
339                          GL_RGBA, GL_UNSIGNED_BYTE, NULL);
340
341             GL_EXTCALL(glGenFramebuffersEXT(1, &fb));
342             GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb));
343             GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
344                                                  GL_TEXTURE_2D, tex, 0));
345
346             status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
347             GL_EXTCALL(glDeleteFramebuffersEXT(1, &fb));
348             glDeleteTextures(1, &tex);
349
350             checkGLcall("Framebuffer format check");
351
352             if(status != GL_FRAMEBUFFER_COMPLETE_EXT) {
353                 TRACE("Internal format of %s not supported as frame buffer target, using render target internal instead\n",
354                     debug_d3dformat(gl_formats_template[src].fmt));
355                 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].rtInternal;
356             } else {
357                 TRACE("Format %s is supported as fbo target\n", debug_d3dformat(gl_formats_template[src].fmt));
358                 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].glInternal;
359             }
360
361         } else {
362             gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].glInternal;
363         }
364     }
365
366     dst = getFmtIdx(WINED3DFMT_R16F);
367     gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
368             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
369     /* When ARB_texture_rg is supported we only require 16-bit for R16F instead of 64-bit RGBA16F */
370     if(GL_SUPPORT(ARB_TEXTURE_RG))
371     {
372         gl_info->gl_formats[dst].glInternal = GL_R16F;
373         gl_info->gl_formats[dst].glGammaInternal = GL_R16F;
374     }
375
376     dst = getFmtIdx(WINED3DFMT_R32F);
377     gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
378             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
379     /* When ARB_texture_rg is supported we only require 32-bit for R32F instead of 128-bit RGBA32F */
380     if(GL_SUPPORT(ARB_TEXTURE_RG))
381     {
382         gl_info->gl_formats[dst].glInternal = GL_R32F;
383         gl_info->gl_formats[dst].glGammaInternal = GL_R32F;
384     }
385
386     dst = getFmtIdx(WINED3DFMT_G16R16);
387     gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
388             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
389
390     dst = getFmtIdx(WINED3DFMT_G16R16F);
391     gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
392             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
393
394     dst = getFmtIdx(WINED3DFMT_G32R32F);
395     gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
396             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
397
398     /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
399      * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
400      * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
401      * the only driver that implements it(fglrx) has a buggy implementation.
402      *
403      * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
404      * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
405      * conversion for this format.
406      */
407     if (!GL_SUPPORT(NV_TEXTURE_SHADER))
408     {
409         dst = getFmtIdx(WINED3DFMT_V8U8);
410         gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
411                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
412         dst = getFmtIdx(WINED3DFMT_V16U16);
413         gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
414                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
415     }
416     else
417     {
418         dst = getFmtIdx(WINED3DFMT_V8U8);
419         gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
420                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
421         dst = getFmtIdx(WINED3DFMT_V16U16);
422         gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
423                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
424     }
425
426     if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
427         /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
428          * with each other
429          */
430         dst = getFmtIdx(WINED3DFMT_L6V5U5);
431         gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
432                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
433         dst = getFmtIdx(WINED3DFMT_X8L8V8U8);
434         gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
435                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
436         dst = getFmtIdx(WINED3DFMT_Q8W8V8U8);
437         gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
438                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
439     } else {
440         /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
441          * are converted at surface loading time, but they do not need any modification in
442          * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
443          * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
444          */
445     }
446
447     if(GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
448         dst = getFmtIdx(WINED3DFMT_ATI2N);
449         gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
450         gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
451         gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
452                 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
453     } else if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC)) {
454         dst = getFmtIdx(WINED3DFMT_ATI2N);
455         gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
456         gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
457         gl_info->gl_formats[dst].color_fixup= create_color_fixup_desc(
458                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
459     }
460
461     if(!GL_SUPPORT(APPLE_YCBCR_422)) {
462         dst = getFmtIdx(WINED3DFMT_YUY2);
463         gl_info->gl_formats[dst].glInternal = GL_LUMINANCE_ALPHA;
464         gl_info->gl_formats[dst].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
465         gl_info->gl_formats[dst].glFormat = GL_LUMINANCE_ALPHA;
466         gl_info->gl_formats[dst].glType = GL_UNSIGNED_BYTE;
467         gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
468
469         dst = getFmtIdx(WINED3DFMT_UYVY);
470         gl_info->gl_formats[dst].glInternal = GL_LUMINANCE_ALPHA;
471         gl_info->gl_formats[dst].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
472         gl_info->gl_formats[dst].glFormat = GL_LUMINANCE_ALPHA;
473         gl_info->gl_formats[dst].glType = GL_UNSIGNED_BYTE;
474         gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
475     }
476
477     dst = getFmtIdx(WINED3DFMT_YV12);
478     gl_info->gl_formats[dst].heightscale = 1.5;
479     gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
480
481     return TRUE;
482 }
483
484 /* NOTE: Make sure these are in the correct numerical order. (see /include/wined3d_types.h) */
485 static WINED3DGLTYPE const glTypeLookupTemplate[WINED3DDECLTYPE_UNUSED] = {
486                                   {WINED3DDECLTYPE_FLOAT1,    1, GL_FLOAT           , GL_FALSE ,sizeof(float)},
487                                   {WINED3DDECLTYPE_FLOAT2,    2, GL_FLOAT           , GL_FALSE ,sizeof(float)},
488                                   {WINED3DDECLTYPE_FLOAT3,    3, GL_FLOAT           , GL_FALSE ,sizeof(float)},
489                                   {WINED3DDECLTYPE_FLOAT4,    4, GL_FLOAT           , GL_FALSE ,sizeof(float)},
490                                   {WINED3DDECLTYPE_D3DCOLOR,  4, GL_UNSIGNED_BYTE   , GL_TRUE  ,sizeof(BYTE)},
491                                   {WINED3DDECLTYPE_UBYTE4,    4, GL_UNSIGNED_BYTE   , GL_FALSE ,sizeof(BYTE)},
492                                   {WINED3DDECLTYPE_SHORT2,    2, GL_SHORT           , GL_FALSE ,sizeof(short int)},
493                                   {WINED3DDECLTYPE_SHORT4,    4, GL_SHORT           , GL_FALSE ,sizeof(short int)},
494                                   {WINED3DDECLTYPE_UBYTE4N,   4, GL_UNSIGNED_BYTE   , GL_TRUE  ,sizeof(BYTE)},
495                                   {WINED3DDECLTYPE_SHORT2N,   2, GL_SHORT           , GL_TRUE  ,sizeof(short int)},
496                                   {WINED3DDECLTYPE_SHORT4N,   4, GL_SHORT           , GL_TRUE  ,sizeof(short int)},
497                                   {WINED3DDECLTYPE_USHORT2N,  2, GL_UNSIGNED_SHORT  , GL_TRUE  ,sizeof(short int)},
498                                   {WINED3DDECLTYPE_USHORT4N,  4, GL_UNSIGNED_SHORT  , GL_TRUE  ,sizeof(short int)},
499                                   {WINED3DDECLTYPE_UDEC3,     3, GL_UNSIGNED_SHORT  , GL_FALSE ,sizeof(short int)},
500                                   {WINED3DDECLTYPE_DEC3N,     3, GL_SHORT           , GL_TRUE  ,sizeof(short int)},
501                                   {WINED3DDECLTYPE_FLOAT16_2, 2, GL_HALF_FLOAT_NV   , GL_FALSE ,sizeof(GLhalfNV)},
502                                   {WINED3DDECLTYPE_FLOAT16_4, 4, GL_HALF_FLOAT_NV   , GL_FALSE ,sizeof(GLhalfNV)}};
503
504 void init_type_lookup(WineD3D_GL_Info *gl_info) {
505     memcpy(gl_info->glTypeLookup, glTypeLookupTemplate, sizeof(glTypeLookupTemplate));
506     if(!GL_SUPPORT(NV_HALF_FLOAT)) {
507         /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
508          * It is the job of the vertex buffer code to make sure that the vbos have the right format
509          */
510         gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_2].glType = GL_FLOAT;
511         gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_4].glType = GL_FLOAT;
512     }
513 }
514
515 #undef GLINFO_LOCATION
516
517 #define GLINFO_LOCATION This->adapter->gl_info
518
519 const StaticPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const WineD3D_GL_Info *gl_info,
520         const struct GlPixelFormatDesc **glDesc)
521 {
522     int idx = getFmtIdx(fmt);
523
524     if(idx == -1) {
525         FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
526         /* Get the caller a valid pointer */
527         idx = getFmtIdx(WINED3DFMT_UNKNOWN);
528     }
529     if(glDesc) {
530         if(!gl_info->gl_formats) {
531             /* If we do not have gl format information, provide a dummy NULL format. This is an easy way to make
532              * all gl caps check return "unsupported" than catching the lack of gl all over the code. ANSI C requires
533              * static variables to be initialized to 0.
534              */
535             static const struct GlPixelFormatDesc dummyFmt;
536             *glDesc = &dummyFmt;
537         } else {
538             *glDesc = &gl_info->gl_formats[idx];
539         }
540     }
541     return &formats[idx];
542 }
543
544 /*****************************************************************************
545  * Trace formatting of useful values
546  */
547 const char* debug_d3dformat(WINED3DFORMAT fmt) {
548   switch (fmt) {
549 #define FMT_TO_STR(fmt) case fmt: return #fmt
550     FMT_TO_STR(WINED3DFMT_UNKNOWN);
551     FMT_TO_STR(WINED3DFMT_R8G8B8);
552     FMT_TO_STR(WINED3DFMT_A8R8G8B8);
553     FMT_TO_STR(WINED3DFMT_X8R8G8B8);
554     FMT_TO_STR(WINED3DFMT_R5G6B5);
555     FMT_TO_STR(WINED3DFMT_X1R5G5B5);
556     FMT_TO_STR(WINED3DFMT_A1R5G5B5);
557     FMT_TO_STR(WINED3DFMT_A4R4G4B4);
558     FMT_TO_STR(WINED3DFMT_R3G3B2);
559     FMT_TO_STR(WINED3DFMT_A8);
560     FMT_TO_STR(WINED3DFMT_A8R3G3B2);
561     FMT_TO_STR(WINED3DFMT_X4R4G4B4);
562     FMT_TO_STR(WINED3DFMT_A2B10G10R10);
563     FMT_TO_STR(WINED3DFMT_A8B8G8R8);
564     FMT_TO_STR(WINED3DFMT_X8B8G8R8);
565     FMT_TO_STR(WINED3DFMT_G16R16);
566     FMT_TO_STR(WINED3DFMT_A2R10G10B10);
567     FMT_TO_STR(WINED3DFMT_A16B16G16R16);
568     FMT_TO_STR(WINED3DFMT_A8P8);
569     FMT_TO_STR(WINED3DFMT_P8);
570     FMT_TO_STR(WINED3DFMT_L8);
571     FMT_TO_STR(WINED3DFMT_A8L8);
572     FMT_TO_STR(WINED3DFMT_A4L4);
573     FMT_TO_STR(WINED3DFMT_V8U8);
574     FMT_TO_STR(WINED3DFMT_L6V5U5);
575     FMT_TO_STR(WINED3DFMT_X8L8V8U8);
576     FMT_TO_STR(WINED3DFMT_Q8W8V8U8);
577     FMT_TO_STR(WINED3DFMT_V16U16);
578     FMT_TO_STR(WINED3DFMT_W11V11U10);
579     FMT_TO_STR(WINED3DFMT_A2W10V10U10);
580     FMT_TO_STR(WINED3DFMT_UYVY);
581     FMT_TO_STR(WINED3DFMT_YUY2);
582     FMT_TO_STR(WINED3DFMT_YV12);
583     FMT_TO_STR(WINED3DFMT_DXT1);
584     FMT_TO_STR(WINED3DFMT_DXT2);
585     FMT_TO_STR(WINED3DFMT_DXT3);
586     FMT_TO_STR(WINED3DFMT_DXT4);
587     FMT_TO_STR(WINED3DFMT_DXT5);
588     FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
589     FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
590     FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
591     FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
592     FMT_TO_STR(WINED3DFMT_D32);
593     FMT_TO_STR(WINED3DFMT_D15S1);
594     FMT_TO_STR(WINED3DFMT_D24S8);
595     FMT_TO_STR(WINED3DFMT_D24X8);
596     FMT_TO_STR(WINED3DFMT_D24X4S4);
597     FMT_TO_STR(WINED3DFMT_D16);
598     FMT_TO_STR(WINED3DFMT_L16);
599     FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
600     FMT_TO_STR(WINED3DFMT_D24FS8);
601     FMT_TO_STR(WINED3DFMT_VERTEXDATA);
602     FMT_TO_STR(WINED3DFMT_INDEX16);
603     FMT_TO_STR(WINED3DFMT_INDEX32);
604     FMT_TO_STR(WINED3DFMT_Q16W16V16U16);
605     FMT_TO_STR(WINED3DFMT_R16F);
606     FMT_TO_STR(WINED3DFMT_G16R16F);
607     FMT_TO_STR(WINED3DFMT_A16B16G16R16F);
608     FMT_TO_STR(WINED3DFMT_R32F);
609     FMT_TO_STR(WINED3DFMT_G32R32F);
610     FMT_TO_STR(WINED3DFMT_A32B32G32R32F);
611     FMT_TO_STR(WINED3DFMT_CxV8U8);
612     FMT_TO_STR(WINED3DFMT_ATI2N);
613     FMT_TO_STR(WINED3DFMT_NVHU);
614     FMT_TO_STR(WINED3DFMT_NVHS);
615 #undef FMT_TO_STR
616   default:
617     {
618       char fourcc[5];
619       fourcc[0] = (char)(fmt);
620       fourcc[1] = (char)(fmt >> 8);
621       fourcc[2] = (char)(fmt >> 16);
622       fourcc[3] = (char)(fmt >> 24);
623       fourcc[4] = 0;
624       if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
625         FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
626       else
627         FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
628     }
629     return "unrecognized";
630   }
631 }
632
633 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
634   switch (devtype) {
635 #define DEVTYPE_TO_STR(dev) case dev: return #dev
636     DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
637     DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
638     DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
639 #undef DEVTYPE_TO_STR
640   default:
641     FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
642     return "unrecognized";
643   }
644 }
645
646 const char* debug_d3dusage(DWORD usage) {
647   switch (usage & WINED3DUSAGE_MASK) {
648 #define WINED3DUSAGE_TO_STR(u) case u: return #u
649     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
650     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
651     WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
652     WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
653     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
654     WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
655     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
656     WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
657     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
658     WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
659     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
660 #undef WINED3DUSAGE_TO_STR
661   case 0: return "none";
662   default:
663     FIXME("Unrecognized %u Usage!\n", usage);
664     return "unrecognized";
665   }
666 }
667
668 const char* debug_d3dusagequery(DWORD usagequery) {
669   switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
670 #define WINED3DUSAGEQUERY_TO_STR(u) case u: return #u
671     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
672     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
673     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
674     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
675     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
676     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
677     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
678 #undef WINED3DUSAGEQUERY_TO_STR
679   case 0: return "none";
680   default:
681     FIXME("Unrecognized %u Usage Query!\n", usagequery);
682     return "unrecognized";
683   }
684 }
685
686 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
687     switch (method) {
688 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
689         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
690         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
691         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
692         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
693         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
694         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
695         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
696 #undef WINED3DDECLMETHOD_TO_STR
697         default:
698             FIXME("Unrecognized %u declaration method!\n", method);
699             return "unrecognized";
700     }
701 }
702
703 const char* debug_d3ddecltype(WINED3DDECLTYPE type) {
704     switch (type) {
705 #define WINED3DDECLTYPE_TO_STR(u) case u: return #u
706         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT1);
707         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT2);
708         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT3);
709         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT4);
710         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_D3DCOLOR);
711         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4);
712         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2);
713         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4);
714         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4N);
715         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2N);
716         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4N);
717         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT2N);
718         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT4N);
719         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UDEC3);
720         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_DEC3N);
721         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_2);
722         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_4);
723         WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UNUSED);
724 #undef WINED3DDECLTYPE_TO_STR
725         default:
726             FIXME("Unrecognized %u declaration type!\n", type);
727             return "unrecognized";
728     }
729 }
730
731 const char* debug_d3ddeclusage(BYTE usage) {
732     switch (usage) {
733 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
734         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
735         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
736         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
737         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
738         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
739         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
740         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
741         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
742         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
743         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
744         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
745         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
746         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
747         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
748 #undef WINED3DDECLUSAGE_TO_STR
749         default:
750             FIXME("Unrecognized %u declaration usage!\n", usage);
751             return "unrecognized";
752     }
753 }
754
755 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
756   switch (res) {
757 #define RES_TO_STR(res) case res: return #res;
758     RES_TO_STR(WINED3DRTYPE_SURFACE);
759     RES_TO_STR(WINED3DRTYPE_VOLUME);
760     RES_TO_STR(WINED3DRTYPE_TEXTURE);
761     RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
762     RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
763     RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER);
764     RES_TO_STR(WINED3DRTYPE_INDEXBUFFER);
765 #undef  RES_TO_STR
766   default:
767     FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
768     return "unrecognized";
769   }
770 }
771
772 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
773   switch (PrimitiveType) {
774 #define PRIM_TO_STR(prim) case prim: return #prim;
775     PRIM_TO_STR(WINED3DPT_POINTLIST);
776     PRIM_TO_STR(WINED3DPT_LINELIST);
777     PRIM_TO_STR(WINED3DPT_LINESTRIP);
778     PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
779     PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
780     PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
781 #undef  PRIM_TO_STR
782   default:
783     FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
784     return "unrecognized";
785   }
786 }
787
788 const char* debug_d3drenderstate(DWORD state) {
789   switch (state) {
790 #define D3DSTATE_TO_STR(u) case u: return #u
791     D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE             );
792     D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS                 );
793     D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS            );
794     D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE        );
795     D3DSTATE_TO_STR(WINED3DRS_WRAPU                     );
796     D3DSTATE_TO_STR(WINED3DRS_WRAPV                     );
797     D3DSTATE_TO_STR(WINED3DRS_ZENABLE                   );
798     D3DSTATE_TO_STR(WINED3DRS_FILLMODE                  );
799     D3DSTATE_TO_STR(WINED3DRS_SHADEMODE                 );
800     D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN               );
801     D3DSTATE_TO_STR(WINED3DRS_MONOENABLE                );
802     D3DSTATE_TO_STR(WINED3DRS_ROP2                      );
803     D3DSTATE_TO_STR(WINED3DRS_PLANEMASK                 );
804     D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE              );
805     D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE           );
806     D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL                 );
807     D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG                );
808     D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN                );
809     D3DSTATE_TO_STR(WINED3DRS_SRCBLEND                  );
810     D3DSTATE_TO_STR(WINED3DRS_DESTBLEND                 );
811     D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND           );
812     D3DSTATE_TO_STR(WINED3DRS_CULLMODE                  );
813     D3DSTATE_TO_STR(WINED3DRS_ZFUNC                     );
814     D3DSTATE_TO_STR(WINED3DRS_ALPHAREF                  );
815     D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC                 );
816     D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE              );
817     D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE          );
818     D3DSTATE_TO_STR(WINED3DRS_FOGENABLE                 );
819     D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE            );
820     D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE                  );
821     D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL                  );
822     D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX                 );
823     D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA             );
824     D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR                  );
825     D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE              );
826     D3DSTATE_TO_STR(WINED3DRS_FOGSTART                  );
827     D3DSTATE_TO_STR(WINED3DRS_FOGEND                    );
828     D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY                );
829     D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE             );
830     D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS             );
831     D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE            );
832     D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR               );
833     D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU           );
834     D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV           );
835     D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS             );
836     D3DSTATE_TO_STR(WINED3DRS_ZBIAS                     );
837     D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE            );
838     D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY                );
839     D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH                );
840     D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
841     D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE             );
842     D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL               );
843     D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL              );
844     D3DSTATE_TO_STR(WINED3DRS_STENCILPASS               );
845     D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC               );
846     D3DSTATE_TO_STR(WINED3DRS_STENCILREF                );
847     D3DSTATE_TO_STR(WINED3DRS_STENCILMASK               );
848     D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK          );
849     D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR             );
850     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00          );
851     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01          );
852     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02          );
853     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03          );
854     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04          );
855     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05          );
856     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06          );
857     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07          );
858     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08          );
859     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09          );
860     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10          );
861     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11          );
862     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12          );
863     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13          );
864     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14          );
865     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15          );
866     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16          );
867     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17          );
868     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18          );
869     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19          );
870     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20          );
871     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21          );
872     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22          );
873     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23          );
874     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24          );
875     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25          );
876     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26          );
877     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27          );
878     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28          );
879     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29          );
880     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30          );
881     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31          );
882     D3DSTATE_TO_STR(WINED3DRS_WRAP0                     );
883     D3DSTATE_TO_STR(WINED3DRS_WRAP1                     );
884     D3DSTATE_TO_STR(WINED3DRS_WRAP2                     );
885     D3DSTATE_TO_STR(WINED3DRS_WRAP3                     );
886     D3DSTATE_TO_STR(WINED3DRS_WRAP4                     );
887     D3DSTATE_TO_STR(WINED3DRS_WRAP5                     );
888     D3DSTATE_TO_STR(WINED3DRS_WRAP6                     );
889     D3DSTATE_TO_STR(WINED3DRS_WRAP7                     );
890     D3DSTATE_TO_STR(WINED3DRS_CLIPPING                  );
891     D3DSTATE_TO_STR(WINED3DRS_LIGHTING                  );
892     D3DSTATE_TO_STR(WINED3DRS_EXTENTS                   );
893     D3DSTATE_TO_STR(WINED3DRS_AMBIENT                   );
894     D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE             );
895     D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX               );
896     D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER               );
897     D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS          );
898     D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE       );
899     D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE     );
900     D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE    );
901     D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE     );
902     D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE    );
903     D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND               );
904     D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE           );
905     D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING  );
906     D3DSTATE_TO_STR(WINED3DRS_POINTSIZE                 );
907     D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN             );
908     D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE         );
909     D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE          );
910     D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A              );
911     D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B              );
912     D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C              );
913     D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS      );
914     D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK           );
915     D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE            );
916     D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS             );
917     D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN         );
918     D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX             );
919     D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE  );
920     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE          );
921     D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR               );
922     D3DSTATE_TO_STR(WINED3DRS_BLENDOP                   );
923     D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE            );
924     D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE              );
925     D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE         );
926     D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS       );
927     D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE     );
928     D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL      );
929     D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL      );
930     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X            );
931     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y            );
932     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z            );
933     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W            );
934     D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
935     D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE       );
936     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL           );
937     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL          );
938     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS           );
939     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC           );
940     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1         );
941     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2         );
942     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3         );
943     D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR               );
944     D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE           );
945     D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS                 );
946     D3DSTATE_TO_STR(WINED3DRS_WRAP8                     );
947     D3DSTATE_TO_STR(WINED3DRS_WRAP9                     );
948     D3DSTATE_TO_STR(WINED3DRS_WRAP10                    );
949     D3DSTATE_TO_STR(WINED3DRS_WRAP11                    );
950     D3DSTATE_TO_STR(WINED3DRS_WRAP12                    );
951     D3DSTATE_TO_STR(WINED3DRS_WRAP13                    );
952     D3DSTATE_TO_STR(WINED3DRS_WRAP14                    );
953     D3DSTATE_TO_STR(WINED3DRS_WRAP15                    );
954     D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE  );
955     D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA             );
956     D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA            );
957     D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA              );
958 #undef D3DSTATE_TO_STR
959   default:
960     FIXME("Unrecognized %u render state!\n", state);
961     return "unrecognized";
962   }
963 }
964
965 const char* debug_d3dsamplerstate(DWORD state) {
966   switch (state) {
967 #define D3DSTATE_TO_STR(u) case u: return #u
968     D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR  );
969     D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU     );
970     D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV     );
971     D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW     );
972     D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER    );
973     D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER    );
974     D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER    );
975     D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
976     D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL  );
977     D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
978     D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE  );
979     D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
980     D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET   );
981 #undef D3DSTATE_TO_STR
982   default:
983     FIXME("Unrecognized %u sampler state!\n", state);
984     return "unrecognized";
985   }
986 }
987
988 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
989     switch (filter_type) {
990 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
991         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
992         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
993         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
994         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
995         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
996         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
997         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
998         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
999 #undef D3DTEXTUREFILTERTYPE_TO_STR
1000         default:
1001             FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1002             return "unrecognized";
1003     }
1004 }
1005
1006 const char* debug_d3dtexturestate(DWORD state) {
1007   switch (state) {
1008 #define D3DSTATE_TO_STR(u) case u: return #u
1009     D3DSTATE_TO_STR(WINED3DTSS_COLOROP               );
1010     D3DSTATE_TO_STR(WINED3DTSS_COLORARG1             );
1011     D3DSTATE_TO_STR(WINED3DTSS_COLORARG2             );
1012     D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP               );
1013     D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1             );
1014     D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2             );
1015     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00          );
1016     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01          );
1017     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10          );
1018     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11          );
1019     D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX         );
1020     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE         );
1021     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET        );
1022     D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1023     D3DSTATE_TO_STR(WINED3DTSS_ADDRESSW              );
1024     D3DSTATE_TO_STR(WINED3DTSS_COLORARG0             );
1025     D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0             );
1026     D3DSTATE_TO_STR(WINED3DTSS_RESULTARG             );
1027     D3DSTATE_TO_STR(WINED3DTSS_CONSTANT              );
1028 #undef D3DSTATE_TO_STR
1029   case 12:
1030     /* Note WINED3DTSS are not consecutive, so skip these */
1031     return "unused";
1032   default:
1033     FIXME("Unrecognized %u texture state!\n", state);
1034     return "unrecognized";
1035   }
1036 }
1037
1038 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1039     switch (d3dtop) {
1040 #define D3DTOP_TO_STR(u) case u: return #u
1041         D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1042         D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1043         D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1044         D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1045         D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1046         D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1047         D3DTOP_TO_STR(WINED3DTOP_ADD);
1048         D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1049         D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1050         D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1051         D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1052         D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1053         D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1054         D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1055         D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1056         D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1057         D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1058         D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1059         D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1060         D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1061         D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1062         D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1063         D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1064         D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1065         D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1066         D3DTOP_TO_STR(WINED3DTOP_LERP);
1067 #undef D3DTOP_TO_STR
1068         default:
1069             FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1070             return "unrecognized";
1071     }
1072 }
1073
1074 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1075     switch (tstype) {
1076 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1077     TSTYPE_TO_STR(WINED3DTS_VIEW);
1078     TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1079     TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1080     TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1081     TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1082     TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1083     TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1084     TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1085     TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1086     TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1087     TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1088 #undef TSTYPE_TO_STR
1089     default:
1090         if (tstype > 256 && tstype < 512) {
1091             FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1092             return ("WINED3DTS_WORLDMATRIX > 0");
1093         }
1094         FIXME("Unrecognized %u WINED3DTS\n", tstype);
1095         return "unrecognized";
1096     }
1097 }
1098
1099 const char* debug_d3dpool(WINED3DPOOL Pool) {
1100   switch (Pool) {
1101 #define POOL_TO_STR(p) case p: return #p;
1102     POOL_TO_STR(WINED3DPOOL_DEFAULT);
1103     POOL_TO_STR(WINED3DPOOL_MANAGED);
1104     POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1105     POOL_TO_STR(WINED3DPOOL_SCRATCH);
1106 #undef  POOL_TO_STR
1107   default:
1108     FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1109     return "unrecognized";
1110   }
1111 }
1112
1113 const char *debug_fbostatus(GLenum status) {
1114     switch(status) {
1115 #define FBOSTATUS_TO_STR(u) case u: return #u
1116         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1117         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1118         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1119         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1120         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1121         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1122         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1123         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
1124         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1125 #undef FBOSTATUS_TO_STR
1126         default:
1127             FIXME("Unrecognied FBO status 0x%08x\n", status);
1128             return "unrecognized";
1129     }
1130 }
1131
1132 const char *debug_glerror(GLenum error) {
1133     switch(error) {
1134 #define GLERROR_TO_STR(u) case u: return #u
1135         GLERROR_TO_STR(GL_NO_ERROR);
1136         GLERROR_TO_STR(GL_INVALID_ENUM);
1137         GLERROR_TO_STR(GL_INVALID_VALUE);
1138         GLERROR_TO_STR(GL_INVALID_OPERATION);
1139         GLERROR_TO_STR(GL_STACK_OVERFLOW);
1140         GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1141         GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1142         GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1143 #undef GLERROR_TO_STR
1144         default:
1145             FIXME("Unrecognied GL error 0x%08x\n", error);
1146             return "unrecognized";
1147     }
1148 }
1149
1150 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1151     switch(basis) {
1152         case WINED3DBASIS_BEZIER:       return "WINED3DBASIS_BEZIER";
1153         case WINED3DBASIS_BSPLINE:      return "WINED3DBASIS_BSPLINE";
1154         case WINED3DBASIS_INTERPOLATE:  return "WINED3DBASIS_INTERPOLATE";
1155         default:                        return "unrecognized";
1156     }
1157 }
1158
1159 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1160     switch(degree) {
1161         case WINED3DDEGREE_LINEAR:      return "WINED3DDEGREE_LINEAR";
1162         case WINED3DDEGREE_QUADRATIC:   return "WINED3DDEGREE_QUADRATIC";
1163         case WINED3DDEGREE_CUBIC:       return "WINED3DDEGREE_CUBIC";
1164         case WINED3DDEGREE_QUINTIC:     return "WINED3DDEGREE_QUINTIC";
1165         default:                        return "unrecognized";
1166     }
1167 }
1168
1169 const char *debug_fixup_channel_source(enum fixup_channel_source source)
1170 {
1171     switch(source)
1172     {
1173 #define WINED3D_TO_STR(x) case x: return #x
1174         WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1175         WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1176         WINED3D_TO_STR(CHANNEL_SOURCE_X);
1177         WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1178         WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1179         WINED3D_TO_STR(CHANNEL_SOURCE_W);
1180         WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1181         WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1182 #undef WINED3D_TO_STR
1183         default:
1184             FIXME("Unrecognized fixup_channel_source %#x\n", source);
1185             return "unrecognized";
1186     }
1187 }
1188
1189 const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1190 {
1191     switch(yuv_fixup)
1192     {
1193 #define WINED3D_TO_STR(x) case x: return #x
1194         WINED3D_TO_STR(YUV_FIXUP_YUY2);
1195         WINED3D_TO_STR(YUV_FIXUP_UYVY);
1196         WINED3D_TO_STR(YUV_FIXUP_YV12);
1197 #undef WINED3D_TO_STR
1198         default:
1199             FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1200             return "unrecognized";
1201     }
1202 }
1203
1204 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1205 {
1206     if (is_yuv_fixup(fixup))
1207     {
1208         TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1209         return;
1210     }
1211
1212     TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1213     TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1214     TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1215     TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1216 }
1217
1218 /*****************************************************************************
1219  * Useful functions mapping GL <-> D3D values
1220  */
1221 GLenum StencilOp(DWORD op) {
1222     switch(op) {
1223     case WINED3DSTENCILOP_KEEP    : return GL_KEEP;
1224     case WINED3DSTENCILOP_ZERO    : return GL_ZERO;
1225     case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1226     case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1227     case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1228     case WINED3DSTENCILOP_INVERT  : return GL_INVERT;
1229     case WINED3DSTENCILOP_INCR    : return GL_INCR_WRAP_EXT;
1230     case WINED3DSTENCILOP_DECR    : return GL_DECR_WRAP_EXT;
1231     default:
1232         FIXME("Unrecognized stencil op %d\n", op);
1233         return GL_KEEP;
1234     }
1235 }
1236
1237 GLenum CompareFunc(DWORD func) {
1238     switch ((WINED3DCMPFUNC)func) {
1239     case WINED3DCMP_NEVER        : return GL_NEVER;
1240     case WINED3DCMP_LESS         : return GL_LESS;
1241     case WINED3DCMP_EQUAL        : return GL_EQUAL;
1242     case WINED3DCMP_LESSEQUAL    : return GL_LEQUAL;
1243     case WINED3DCMP_GREATER      : return GL_GREATER;
1244     case WINED3DCMP_NOTEQUAL     : return GL_NOTEQUAL;
1245     case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1246     case WINED3DCMP_ALWAYS       : return GL_ALWAYS;
1247     default:
1248         FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1249         return 0;
1250     }
1251 }
1252
1253 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1254     if (op == WINED3DTOP_DISABLE) return FALSE;
1255     if (This->stateBlock->textures[stage]) return FALSE;
1256
1257     if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1258             && op != WINED3DTOP_SELECTARG2) return TRUE;
1259     if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1260             && op != WINED3DTOP_SELECTARG1) return TRUE;
1261     if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1262             && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1263
1264     return FALSE;
1265 }
1266
1267 /* Setup this textures matrix according to the texture flags*/
1268 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype,
1269                         BOOL ffp_proj_control)
1270 {
1271     float mat[16];
1272
1273     glMatrixMode(GL_TEXTURE);
1274     checkGLcall("glMatrixMode(GL_TEXTURE)");
1275
1276     if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1277         glLoadIdentity();
1278         checkGLcall("glLoadIdentity()");
1279         return;
1280     }
1281
1282     if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1283         ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1284         return;
1285     }
1286
1287     memcpy(mat, smat, 16 * sizeof(float));
1288
1289     if (flags & WINED3DTTFF_PROJECTED) {
1290         if(!ffp_proj_control) {
1291             switch (flags & ~WINED3DTTFF_PROJECTED) {
1292             case WINED3DTTFF_COUNT2:
1293                 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1294                 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1295                 break;
1296             case WINED3DTTFF_COUNT3:
1297                 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1298                 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1299                 break;
1300             }
1301         }
1302     } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1303         if(!calculatedCoords) {
1304             switch(coordtype) {
1305                 case WINED3DDECLTYPE_FLOAT1:
1306                     /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1307                      * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1308                      * the input value to the transformation will be 0, so the matrix value is irrelevant
1309                      */
1310                     mat[12] = mat[4];
1311                     mat[13] = mat[5];
1312                     mat[14] = mat[6];
1313                     mat[15] = mat[7];
1314                     break;
1315                 case WINED3DDECLTYPE_FLOAT2:
1316                     /* See above, just 3rd and 4th coord
1317                     */
1318                     mat[12] = mat[8];
1319                     mat[13] = mat[9];
1320                     mat[14] = mat[10];
1321                     mat[15] = mat[11];
1322                     break;
1323                 case WINED3DDECLTYPE_FLOAT3: /* Opengl defaults match dx defaults */
1324                 case WINED3DDECLTYPE_FLOAT4: /* No defaults apply, all app defined */
1325
1326                 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1327                  * into a bad place. The division elimination below will apply to make sure the
1328                  * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1329                  */
1330                 case WINED3DDECLTYPE_UNUSED: /* No texture coords, 0/0/0/1 defaults are passed */
1331                     break;
1332                 default:
1333                     FIXME("Unexpected fixed function texture coord input\n");
1334             }
1335         }
1336         if(!ffp_proj_control) {
1337             switch (flags & ~WINED3DTTFF_PROJECTED) {
1338                 /* case WINED3DTTFF_COUNT1: Won't ever get here */
1339                 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
1340                 /* OpenGL divides the first 3 vertex coord by the 4th by default,
1341                 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
1342                 * the 4th coord evaluates to 1.0 to eliminate that.
1343                 *
1344                 * If the fixed function pipeline is used, the 4th value remains unused,
1345                 * so there is no danger in doing this. With vertex shaders we have a
1346                 * problem. Should an app hit that problem, the code here would have to
1347                 * check for pixel shaders, and the shader has to undo the default gl divide.
1348                 *
1349                 * A more serious problem occurs if the app passes 4 coordinates in, and the
1350                 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
1351                 * or a replacement shader
1352                 */
1353                 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
1354             }
1355         }
1356     }
1357
1358     glLoadMatrixf(mat);
1359     checkGLcall("glLoadMatrixf(mat)");
1360 }
1361 #undef GLINFO_LOCATION
1362
1363 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
1364
1365 /* This small helper function is used to convert a bitmask into the number of masked bits */
1366 unsigned int count_bits(unsigned int mask)
1367 {
1368     unsigned int count;
1369     for (count = 0; mask; ++count)
1370     {
1371         mask &= mask - 1;
1372     }
1373     return count;
1374 }
1375
1376 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
1377  * The later function requires individual color components. */
1378 BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
1379 {
1380     const StaticPixelFormatDesc *desc;
1381
1382     TRACE("fmt: %s\n", debug_d3dformat(fmt));
1383     switch(fmt)
1384     {
1385         case WINED3DFMT_X8R8G8B8:
1386         case WINED3DFMT_R8G8B8:
1387         case WINED3DFMT_A8R8G8B8:
1388         case WINED3DFMT_A2R10G10B10:
1389         case WINED3DFMT_X1R5G5B5:
1390         case WINED3DFMT_A1R5G5B5:
1391         case WINED3DFMT_R5G6B5:
1392         case WINED3DFMT_X4R4G4B4:
1393         case WINED3DFMT_A4R4G4B4:
1394         case WINED3DFMT_R3G3B2:
1395         case WINED3DFMT_A8P8:
1396         case WINED3DFMT_P8:
1397             break;
1398         default:
1399             ERR("Unsupported format: %s\n", debug_d3dformat(fmt));
1400             return FALSE;
1401     }
1402
1403     desc = getFormatDescEntry(fmt, NULL, NULL);
1404     if(!desc)
1405     {
1406         ERR("Unable to look up format: 0x%x\n", fmt);
1407         return FALSE;
1408     }
1409     *redSize = count_bits(desc->redMask);
1410     *greenSize = count_bits(desc->greenMask);
1411     *blueSize = count_bits(desc->blueMask);
1412     *alphaSize = count_bits(desc->alphaMask);
1413     *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
1414
1415     TRACE("Returning red:  %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n", *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(fmt));
1416     return TRUE;
1417 }
1418
1419 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
1420 BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize)
1421 {
1422     const StaticPixelFormatDesc *desc;
1423
1424     TRACE("fmt: %s\n", debug_d3dformat(fmt));
1425     switch(fmt)
1426     {
1427         case WINED3DFMT_D16_LOCKABLE:
1428         case WINED3DFMT_D16:
1429         case WINED3DFMT_D15S1:
1430         case WINED3DFMT_D24X8:
1431         case WINED3DFMT_D24X4S4:
1432         case WINED3DFMT_D24S8:
1433         case WINED3DFMT_D24FS8:
1434         case WINED3DFMT_D32:
1435         case WINED3DFMT_D32F_LOCKABLE:
1436             break;
1437         default:
1438             FIXME("Unsupported stencil format: %s\n", debug_d3dformat(fmt));
1439             return FALSE;
1440     }
1441
1442     desc = getFormatDescEntry(fmt, NULL, NULL);
1443     if(!desc)
1444     {
1445         ERR("Unable to look up format: 0x%x\n", fmt);
1446         return FALSE;
1447     }
1448     *depthSize = desc->depthSize;
1449     *stencilSize = desc->stencilSize;
1450
1451     TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n", *depthSize, *stencilSize, debug_d3dformat(fmt));
1452     return TRUE;
1453 }
1454
1455 #undef GLINFO_LOCATION
1456
1457 /* DirectDraw stuff */
1458 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
1459     switch(depth) {
1460         case 8:  return WINED3DFMT_P8;
1461         case 15: return WINED3DFMT_X1R5G5B5;
1462         case 16: return WINED3DFMT_R5G6B5;
1463         case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
1464         case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
1465         default: return WINED3DFMT_UNKNOWN;
1466     }
1467 }
1468
1469 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
1470     WINED3DMATRIX temp;
1471
1472     /* Now do the multiplication 'by hand'.
1473        I know that all this could be optimised, but this will be done later :-) */
1474     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);
1475     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);
1476     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);
1477     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);
1478
1479     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);
1480     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);
1481     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);
1482     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);
1483
1484     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);
1485     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);
1486     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);
1487     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);
1488
1489     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);
1490     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);
1491     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);
1492     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);
1493
1494     /* And copy the new matrix in the good storage.. */
1495     memcpy(dest, &temp, 16 * sizeof(float));
1496 }
1497
1498 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
1499     DWORD size = 0;
1500     int i;
1501     int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
1502
1503     if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
1504     if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
1505     if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
1506     if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
1507     switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
1508         case WINED3DFVF_XYZ:    size += 3 * sizeof(float); break;
1509         case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
1510         case WINED3DFVF_XYZB1:  size += 4 * sizeof(float); break;
1511         case WINED3DFVF_XYZB2:  size += 5 * sizeof(float); break;
1512         case WINED3DFVF_XYZB3:  size += 6 * sizeof(float); break;
1513         case WINED3DFVF_XYZB4:  size += 7 * sizeof(float); break;
1514         case WINED3DFVF_XYZB5:  size += 8 * sizeof(float); break;
1515         default: ERR("Unexpected position mask\n");
1516     }
1517     for (i = 0; i < numTextures; i++) {
1518         size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
1519     }
1520
1521     return size;
1522 }
1523
1524 /***********************************************************************
1525  * CalculateTexRect
1526  *
1527  * Calculates the dimensions of the opengl texture used for blits.
1528  * Handled oversized opengl textures and updates the source rectangle
1529  * accordingly
1530  *
1531  * Params:
1532  *  This: Surface to operate on
1533  *  Rect: Requested rectangle
1534  *
1535  * Returns:
1536  *  TRUE if the texture part can be loaded,
1537  *  FALSE otherwise
1538  *
1539  *********************************************************************/
1540 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
1541
1542 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
1543     int x1 = Rect->left, x2 = Rect->right;
1544     int y1 = Rect->top, y2 = Rect->bottom;
1545     GLint maxSize = GL_LIMITS(texture_size);
1546
1547     TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
1548           Rect->left, Rect->top, Rect->right, Rect->bottom);
1549
1550     /* The sizes might be reversed */
1551     if(Rect->left > Rect->right) {
1552         x1 = Rect->right;
1553         x2 = Rect->left;
1554     }
1555     if(Rect->top > Rect->bottom) {
1556         y1 = Rect->bottom;
1557         y2 = Rect->top;
1558     }
1559
1560     /* No oversized texture? This is easy */
1561     if(!(This->Flags & SFLAG_OVERSIZE)) {
1562         /* Which rect from the texture do I need? */
1563         if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
1564             glTexCoord[0] = (float) Rect->left;
1565             glTexCoord[2] = (float) Rect->top;
1566             glTexCoord[1] = (float) Rect->right;
1567             glTexCoord[3] = (float) Rect->bottom;
1568         } else {
1569             glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
1570             glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
1571             glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
1572             glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
1573         }
1574
1575         return TRUE;
1576     } else {
1577         /* Check if we can succeed at all */
1578         if( (x2 - x1) > maxSize ||
1579             (y2 - y1) > maxSize ) {
1580             TRACE("Requested rectangle is too large for gl\n");
1581             return FALSE;
1582         }
1583
1584         /* A part of the texture has to be picked. First, check if
1585          * some texture part is loaded already, if yes try to re-use it.
1586          * If the texture is dirty, or the part can't be used,
1587          * re-position the part to load
1588          */
1589         if(This->Flags & SFLAG_INTEXTURE) {
1590             if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
1591                This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
1592                 /* Ok, the rectangle is ok, re-use it */
1593                 TRACE("Using existing gl Texture\n");
1594             } else {
1595                 /* Rectangle is not ok, dirtify the texture to reload it */
1596                 TRACE("Dirtifying texture to force reload\n");
1597                 This->Flags &= ~SFLAG_INTEXTURE;
1598             }
1599         }
1600
1601         /* Now if we are dirty(no else if!) */
1602         if(!(This->Flags & SFLAG_INTEXTURE)) {
1603             /* Set the new rectangle. Use the following strategy:
1604              * 1) Use as big textures as possible.
1605              * 2) Place the texture part in the way that the requested
1606              *    part is in the middle of the texture(well, almost)
1607              * 3) If the texture is moved over the edges of the
1608              *    surface, replace it nicely
1609              * 4) If the coord is not limiting the texture size,
1610              *    use the whole size
1611              */
1612             if((This->pow2Width) > maxSize) {
1613                 This->glRect.left = x1 - maxSize / 2;
1614                 if(This->glRect.left < 0) {
1615                     This->glRect.left = 0;
1616                 }
1617                 This->glRect.right = This->glRect.left + maxSize;
1618                 if(This->glRect.right > This->currentDesc.Width) {
1619                     This->glRect.right = This->currentDesc.Width;
1620                     This->glRect.left = This->glRect.right - maxSize;
1621                 }
1622             } else {
1623                 This->glRect.left = 0;
1624                 This->glRect.right = This->pow2Width;
1625             }
1626
1627             if(This->pow2Height > maxSize) {
1628                 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
1629                 if(This->glRect.top < 0) This->glRect.top = 0;
1630                 This->glRect.bottom = This->glRect.left + maxSize;
1631                 if(This->glRect.bottom > This->currentDesc.Height) {
1632                     This->glRect.bottom = This->currentDesc.Height;
1633                     This->glRect.top = This->glRect.bottom - maxSize;
1634                 }
1635             } else {
1636                 This->glRect.top = 0;
1637                 This->glRect.bottom = This->pow2Height;
1638             }
1639             TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
1640                    This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
1641         }
1642
1643         /* Re-calculate the rect to draw */
1644         Rect->left -= This->glRect.left;
1645         Rect->right -= This->glRect.left;
1646         Rect->top -= This->glRect.top;
1647         Rect->bottom -= This->glRect.top;
1648
1649         /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
1650          * or the pow2Width / pow2Height of the surface.
1651          *
1652          * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
1653          * as regular GL_TEXTURE_2D.
1654          */
1655         glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
1656         glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
1657         glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
1658         glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
1659     }
1660     return TRUE;
1661 }
1662 #undef GLINFO_LOCATION
1663
1664 /* Hash table functions */
1665
1666 struct hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
1667 {
1668     struct hash_table_t *table;
1669     unsigned int initial_size = 8;
1670
1671     table = HeapAlloc(GetProcessHeap(), 0, sizeof(struct hash_table_t) + (initial_size * sizeof(struct list)));
1672     if (!table)
1673     {
1674         ERR("Failed to allocate table, returning NULL.\n");
1675         return NULL;
1676     }
1677
1678     table->hash_function = hash_function;
1679     table->compare_function = compare_function;
1680
1681     table->grow_size = initial_size - (initial_size >> 2);
1682     table->shrink_size = 0;
1683
1684     table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
1685     if (!table->buckets)
1686     {
1687         ERR("Failed to allocate table buckets, returning NULL.\n");
1688         HeapFree(GetProcessHeap(), 0, table);
1689         return NULL;
1690     }
1691     table->bucket_count = initial_size;
1692
1693     table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(struct hash_table_entry_t));
1694     if (!table->entries)
1695     {
1696         ERR("Failed to allocate table entries, returning NULL.\n");
1697         HeapFree(GetProcessHeap(), 0, table->buckets);
1698         HeapFree(GetProcessHeap(), 0, table);
1699         return NULL;
1700     }
1701     table->entry_count = 0;
1702
1703     list_init(&table->free_entries);
1704     table->count = 0;
1705
1706     return table;
1707 }
1708
1709 void hash_table_destroy(struct hash_table_t *table, void (*free_value)(void *value, void *cb), void *cb)
1710 {
1711     unsigned int i = 0;
1712
1713     for (i = 0; i < table->entry_count; ++i)
1714     {
1715         if(free_value) {
1716             free_value(table->entries[i].value, cb);
1717         }
1718         HeapFree(GetProcessHeap(), 0, table->entries[i].key);
1719     }
1720
1721     HeapFree(GetProcessHeap(), 0, table->entries);
1722     HeapFree(GetProcessHeap(), 0, table->buckets);
1723     HeapFree(GetProcessHeap(), 0, table);
1724 }
1725
1726 void hash_table_for_each_entry(struct hash_table_t *table, void (*callback)(void *value, void *context), void *context)
1727 {
1728     unsigned int i = 0;
1729
1730     for (i = 0; i < table->entry_count; ++i)
1731     {
1732         callback(table->entries[i].value, context);
1733     }
1734 }
1735
1736 static inline struct hash_table_entry_t *hash_table_get_by_idx(const struct hash_table_t *table, const void *key,
1737         unsigned int idx)
1738 {
1739     struct hash_table_entry_t *entry;
1740
1741     if (table->buckets[idx].next)
1742         LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), struct hash_table_entry_t, entry)
1743             if (table->compare_function(entry->key, key)) return entry;
1744
1745     return NULL;
1746 }
1747
1748 static BOOL hash_table_resize(struct hash_table_t *table, unsigned int new_bucket_count)
1749 {
1750     unsigned int new_entry_count = 0;
1751     struct hash_table_entry_t *new_entries;
1752     struct list *new_buckets;
1753     unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
1754     unsigned int i;
1755
1756     new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
1757     if (!new_buckets)
1758     {
1759         ERR("Failed to allocate new buckets, returning FALSE.\n");
1760         return FALSE;
1761     }
1762
1763     new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(struct hash_table_entry_t));
1764     if (!new_entries)
1765     {
1766         ERR("Failed to allocate new entries, returning FALSE.\n");
1767         HeapFree(GetProcessHeap(), 0, new_buckets);
1768         return FALSE;
1769     }
1770
1771     for (i = 0; i < table->bucket_count; ++i)
1772     {
1773         if (table->buckets[i].next)
1774         {
1775             struct hash_table_entry_t *entry, *entry2;
1776
1777             LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], struct hash_table_entry_t, entry)
1778             {
1779                 int j;
1780                 struct hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
1781                 *new_entry = *entry;
1782
1783                 j = new_entry->hash & (new_bucket_count - 1);
1784
1785                 if (!new_buckets[j].next) list_init(&new_buckets[j]);
1786                 list_add_head(&new_buckets[j], &new_entry->entry);
1787             }
1788         }
1789     }
1790
1791     HeapFree(GetProcessHeap(), 0, table->buckets);
1792     table->buckets = new_buckets;
1793
1794     HeapFree(GetProcessHeap(), 0, table->entries);
1795     table->entries = new_entries;
1796
1797     table->entry_count = new_entry_count;
1798     list_init(&table->free_entries);
1799
1800     table->bucket_count = new_bucket_count;
1801     table->grow_size = grow_size;
1802     table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
1803
1804     return TRUE;
1805 }
1806
1807 void hash_table_put(struct hash_table_t *table, void *key, void *value)
1808 {
1809     unsigned int idx;
1810     unsigned int hash;
1811     struct hash_table_entry_t *entry;
1812
1813     hash = table->hash_function(key);
1814     idx = hash & (table->bucket_count - 1);
1815     entry = hash_table_get_by_idx(table, key, idx);
1816
1817     if (entry)
1818     {
1819         HeapFree(GetProcessHeap(), 0, key);
1820         entry->value = value;
1821
1822         if (!value)
1823         {
1824             HeapFree(GetProcessHeap(), 0, entry->key);
1825             entry->key = NULL;
1826
1827             /* Remove the entry */
1828             list_remove(&entry->entry);
1829             list_add_head(&table->free_entries, &entry->entry);
1830
1831             --table->count;
1832
1833             /* Shrink if necessary */
1834             if (table->count < table->shrink_size) {
1835                 if (!hash_table_resize(table, table->bucket_count >> 1))
1836                 {
1837                     ERR("Failed to shrink the table...\n");
1838                 }
1839             }
1840         }
1841
1842         return;
1843     }
1844
1845     if (!value) return;
1846
1847     /* Grow if necessary */
1848     if (table->count >= table->grow_size)
1849     {
1850         if (!hash_table_resize(table, table->bucket_count << 1))
1851         {
1852             ERR("Failed to grow the table, returning.\n");
1853             return;
1854         }
1855
1856         idx = hash & (table->bucket_count - 1);
1857     }
1858
1859     /* Find an entry to insert */
1860     if (!list_empty(&table->free_entries))
1861     {
1862         struct list *elem = list_head(&table->free_entries);
1863
1864         list_remove(elem);
1865         entry = LIST_ENTRY(elem, struct hash_table_entry_t, entry);
1866     } else {
1867         entry = table->entries + (table->entry_count++);
1868     }
1869
1870     /* Insert the entry */
1871     entry->key = key;
1872     entry->value = value;
1873     entry->hash = hash;
1874     if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
1875     list_add_head(&table->buckets[idx], &entry->entry);
1876
1877     ++table->count;
1878 }
1879
1880 void hash_table_remove(struct hash_table_t *table, void *key)
1881 {
1882     hash_table_put(table, key, NULL);
1883 }
1884
1885 void *hash_table_get(const struct hash_table_t *table, const void *key)
1886 {
1887     unsigned int idx;
1888     struct hash_table_entry_t *entry;
1889
1890     idx = table->hash_function(key) & (table->bucket_count - 1);
1891     entry = hash_table_get_by_idx(table, key, idx);
1892
1893     return entry ? entry->value : NULL;
1894 }
1895
1896 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
1897 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
1898 #define ARG1 0x01
1899 #define ARG2 0x02
1900 #define ARG0 0x04
1901     static const unsigned char args[WINED3DTOP_LERP + 1] = {
1902         /* undefined                        */  0,
1903         /* D3DTOP_DISABLE                   */  0,
1904         /* D3DTOP_SELECTARG1                */  ARG1,
1905         /* D3DTOP_SELECTARG2                */  ARG2,
1906         /* D3DTOP_MODULATE                  */  ARG1 | ARG2,
1907         /* D3DTOP_MODULATE2X                */  ARG1 | ARG2,
1908         /* D3DTOP_MODULATE4X                */  ARG1 | ARG2,
1909         /* D3DTOP_ADD                       */  ARG1 | ARG2,
1910         /* D3DTOP_ADDSIGNED                 */  ARG1 | ARG2,
1911         /* D3DTOP_ADDSIGNED2X               */  ARG1 | ARG2,
1912         /* D3DTOP_SUBTRACT                  */  ARG1 | ARG2,
1913         /* D3DTOP_ADDSMOOTH                 */  ARG1 | ARG2,
1914         /* D3DTOP_BLENDDIFFUSEALPHA         */  ARG1 | ARG2,
1915         /* D3DTOP_BLENDTEXTUREALPHA         */  ARG1 | ARG2,
1916         /* D3DTOP_BLENDFACTORALPHA          */  ARG1 | ARG2,
1917         /* D3DTOP_BLENDTEXTUREALPHAPM       */  ARG1 | ARG2,
1918         /* D3DTOP_BLENDCURRENTALPHA         */  ARG1 | ARG2,
1919         /* D3DTOP_PREMODULATE               */  ARG1 | ARG2,
1920         /* D3DTOP_MODULATEALPHA_ADDCOLOR    */  ARG1 | ARG2,
1921         /* D3DTOP_MODULATECOLOR_ADDALPHA    */  ARG1 | ARG2,
1922         /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */  ARG1 | ARG2,
1923         /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */  ARG1 | ARG2,
1924         /* D3DTOP_BUMPENVMAP                */  ARG1 | ARG2,
1925         /* D3DTOP_BUMPENVMAPLUMINANCE       */  ARG1 | ARG2,
1926         /* D3DTOP_DOTPRODUCT3               */  ARG1 | ARG2,
1927         /* D3DTOP_MULTIPLYADD               */  ARG1 | ARG2 | ARG0,
1928         /* D3DTOP_LERP                      */  ARG1 | ARG2 | ARG0
1929     };
1930     unsigned int i;
1931     DWORD ttff;
1932     DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
1933
1934     for(i = 0; i < GL_LIMITS(texture_stages); i++) {
1935         IWineD3DBaseTextureImpl *texture;
1936         settings->op[i].padding = 0;
1937         if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
1938             settings->op[i].cop = WINED3DTOP_DISABLE;
1939             settings->op[i].aop = WINED3DTOP_DISABLE;
1940             settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
1941             settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
1942             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
1943             settings->op[i].dst = resultreg;
1944             settings->op[i].tex_type = tex_1d;
1945             settings->op[i].projected = proj_none;
1946             i++;
1947             break;
1948         }
1949
1950         texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
1951         if(texture) {
1952             settings->op[i].color_fixup = texture->baseTexture.shader_color_fixup;
1953             if(ignore_textype) {
1954                 settings->op[i].tex_type = tex_1d;
1955             } else {
1956                 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
1957                     case GL_TEXTURE_1D:
1958                         settings->op[i].tex_type = tex_1d;
1959                         break;
1960                     case GL_TEXTURE_2D:
1961                         settings->op[i].tex_type = tex_2d;
1962                         break;
1963                     case GL_TEXTURE_3D:
1964                         settings->op[i].tex_type = tex_3d;
1965                         break;
1966                     case GL_TEXTURE_CUBE_MAP_ARB:
1967                         settings->op[i].tex_type = tex_cube;
1968                         break;
1969                     case GL_TEXTURE_RECTANGLE_ARB:
1970                         settings->op[i].tex_type = tex_rect;
1971                         break;
1972                 }
1973             }
1974         } else {
1975             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
1976             settings->op[i].tex_type = tex_1d;
1977         }
1978
1979         cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
1980         aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
1981
1982         carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
1983         carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
1984         carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
1985
1986         if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
1987                          carg1, carg2, carg0)) {
1988             carg0 = ARG_UNUSED;
1989             carg2 = ARG_UNUSED;
1990             carg1 = WINED3DTA_CURRENT;
1991             cop = WINED3DTOP_SELECTARG1;
1992         }
1993
1994         if(cop == WINED3DTOP_DOTPRODUCT3) {
1995             /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
1996              * the color result to the alpha component of the destination
1997              */
1998             aop = cop;
1999             aarg1 = carg1;
2000             aarg2 = carg2;
2001             aarg0 = carg0;
2002         } else {
2003             aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2004             aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2005             aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2006         }
2007
2008         if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2009         {
2010             UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2011
2012             if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2013             {
2014                 IWineD3DSurfaceImpl *surf;
2015                 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2016
2017                 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT
2018                         && getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000)
2019                 {
2020                     if (aop == WINED3DTOP_DISABLE)
2021                     {
2022                        aarg1 = WINED3DTA_TEXTURE;
2023                        aop = WINED3DTOP_SELECTARG1;
2024                     }
2025                     else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2026                     {
2027                         if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2028                         {
2029                             aarg2 = WINED3DTA_TEXTURE;
2030                             aop = WINED3DTOP_MODULATE;
2031                         }
2032                         else aarg1 = WINED3DTA_TEXTURE;
2033                     }
2034                     else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2035                     {
2036                         if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2037                         {
2038                             aarg1 = WINED3DTA_TEXTURE;
2039                             aop = WINED3DTOP_MODULATE;
2040                         }
2041                         else aarg2 = WINED3DTA_TEXTURE;
2042                     }
2043                 }
2044             }
2045         }
2046
2047         if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
2048            aarg1, aarg2, aarg0)) {
2049                aarg0 = ARG_UNUSED;
2050                aarg2 = ARG_UNUSED;
2051                aarg1 = WINED3DTA_CURRENT;
2052                aop = WINED3DTOP_SELECTARG1;
2053         }
2054
2055         if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2056            aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2057             ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2058             if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2059                 settings->op[i].projected = proj_count3;
2060             } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2061                 settings->op[i].projected = proj_count4;
2062             } else {
2063                 settings->op[i].projected = proj_none;
2064             }
2065         } else {
2066             settings->op[i].projected = proj_none;
2067         }
2068
2069         settings->op[i].cop = cop;
2070         settings->op[i].aop = aop;
2071         settings->op[i].carg0 = carg0;
2072         settings->op[i].carg1 = carg1;
2073         settings->op[i].carg2 = carg2;
2074         settings->op[i].aarg0 = aarg0;
2075         settings->op[i].aarg1 = aarg1;
2076         settings->op[i].aarg2 = aarg2;
2077
2078         if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2079             settings->op[i].dst = tempreg;
2080         } else {
2081             settings->op[i].dst = resultreg;
2082         }
2083     }
2084
2085     /* Clear unsupported stages */
2086     for(; i < MAX_TEXTURES; i++) {
2087         memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2088     }
2089
2090     if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2091         settings->fog = FOG_OFF;
2092     } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2093         switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2094             case WINED3DFOG_NONE:
2095             case WINED3DFOG_LINEAR:
2096                 settings->fog = FOG_LINEAR;
2097                 break;
2098             case WINED3DFOG_EXP:
2099                 settings->fog = FOG_EXP;
2100                 break;
2101             case WINED3DFOG_EXP2:
2102                 settings->fog = FOG_EXP2;
2103                 break;
2104         }
2105     } else {
2106         switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2107             case WINED3DFOG_LINEAR:
2108                 settings->fog = FOG_LINEAR;
2109                 break;
2110             case WINED3DFOG_EXP:
2111                 settings->fog = FOG_EXP;
2112                 break;
2113             case WINED3DFOG_EXP2:
2114                 settings->fog = FOG_EXP2;
2115                 break;
2116         }
2117     }
2118     if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2119         settings->sRGB_write = 1;
2120     } else {
2121         settings->sRGB_write = 0;
2122     }
2123 }
2124 #undef GLINFO_LOCATION
2125
2126 const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
2127         const struct ffp_frag_settings *settings)
2128 {
2129     return (const struct ffp_frag_desc *)hash_table_get(fragment_shaders, settings);
2130 }
2131
2132 void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *desc) {
2133     struct ffp_frag_settings *key = HeapAlloc(GetProcessHeap(), 0, sizeof(*key));
2134     /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2135      * whereas desc points to an extended structure with implementation specific parts.
2136      * Make a copy of the key because hash_table_put takes ownership of it
2137      */
2138     *key = desc->settings;
2139     hash_table_put(shaders, key, desc);
2140 }
2141
2142 /* Activates the texture dimension according to the bound D3D texture.
2143  * Does not care for the colorop or correct gl texture unit(when using nvrc)
2144  * Requires the caller to activate the correct unit before
2145  */
2146 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2147 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2148     if(stateblock->textures[stage]) {
2149         switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2150             case GL_TEXTURE_2D:
2151                 glDisable(GL_TEXTURE_3D);
2152                 checkGLcall("glDisable(GL_TEXTURE_3D)");
2153                 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2154                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2155                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2156                 }
2157                 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2158                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
2159                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2160                 }
2161                 glEnable(GL_TEXTURE_2D);
2162                 checkGLcall("glEnable(GL_TEXTURE_2D)");
2163                 break;
2164             case GL_TEXTURE_RECTANGLE_ARB:
2165                 glDisable(GL_TEXTURE_2D);
2166                 checkGLcall("glDisable(GL_TEXTURE_2D)");
2167                 glDisable(GL_TEXTURE_3D);
2168                 checkGLcall("glDisable(GL_TEXTURE_3D)");
2169                 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2170                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2171                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2172                 }
2173                 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2174                 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2175                 break;
2176             case GL_TEXTURE_3D:
2177                 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2178                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2179                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2180                 }
2181                 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2182                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
2183                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2184                 }
2185                 glDisable(GL_TEXTURE_2D);
2186                 checkGLcall("glDisable(GL_TEXTURE_2D)");
2187                 glEnable(GL_TEXTURE_3D);
2188                 checkGLcall("glEnable(GL_TEXTURE_3D)");
2189                 break;
2190             case GL_TEXTURE_CUBE_MAP_ARB:
2191                 glDisable(GL_TEXTURE_2D);
2192                 checkGLcall("glDisable(GL_TEXTURE_2D)");
2193                 glDisable(GL_TEXTURE_3D);
2194                 checkGLcall("glDisable(GL_TEXTURE_3D)");
2195                 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2196                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
2197                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2198                 }
2199                 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2200                 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2201               break;
2202         }
2203     } else {
2204         glEnable(GL_TEXTURE_2D);
2205         checkGLcall("glEnable(GL_TEXTURE_2D)");
2206         glDisable(GL_TEXTURE_3D);
2207         checkGLcall("glDisable(GL_TEXTURE_3D)");
2208         if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2209             glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2210             checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2211         }
2212         if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2213             glDisable(GL_TEXTURE_RECTANGLE_ARB);
2214             checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2215         }
2216         /* Binding textures is done by samplers. A dummy texture will be bound */
2217     }
2218 }
2219
2220 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2221     DWORD sampler = state - STATE_SAMPLER(0);
2222     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2223
2224     /* No need to enable / disable anything here for unused samplers. The tex_colorop
2225     * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2226     * will take care of this business
2227     */
2228     if(mapped_stage == -1 || mapped_stage >= GL_LIMITS(textures)) return;
2229     if(sampler >= stateblock->lowest_disabled_stage) return;
2230     if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2231
2232     texture_activate_dimensions(sampler, stateblock, context);
2233 }
2234 #undef GLINFO_LOCATION
2235
2236 unsigned int ffp_frag_program_key_hash(const void *key)
2237 {
2238     const struct ffp_frag_settings *k = (const struct ffp_frag_settings *)key;
2239     unsigned int hash = 0, i;
2240     const DWORD *blob;
2241
2242     /* This takes the texture op settings of stage 0 and 1 into account.
2243      * how exactly depends on the memory laybout of the compiler, but it
2244      * should not matter too much. Stages > 1 are used rarely, so there's
2245      * no need to process them. Even if they're used it is likely that
2246      * the ffp setup has distinct stage 0 and 1 settings.
2247      */
2248     for(i = 0; i < 2; i++) {
2249         blob = (const DWORD *)&k->op[i];
2250         hash ^= blob[0] ^ blob[1];
2251     }
2252
2253     hash += ~(hash << 15);
2254     hash ^=  (hash >> 10);
2255     hash +=  (hash << 3);
2256     hash ^=  (hash >> 6);
2257     hash += ~(hash << 11);
2258     hash ^=  (hash >> 16);
2259
2260     return hash;
2261 }
2262
2263 BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb)
2264 {
2265     const struct ffp_frag_settings *ka = (const struct ffp_frag_settings *)keya;
2266     const struct ffp_frag_settings *kb = (const struct ffp_frag_settings *)keyb;
2267
2268     return memcmp(ka, kb, sizeof(*ka)) == 0;
2269 }
2270
2271 UINT wined3d_log2i(UINT32 x)
2272 {
2273     static const BYTE l[] =
2274     {
2275         0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2276         4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2277         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2278         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2279         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2280         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2281         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2282         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2283         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2284         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2285         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2286         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2287         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2288         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2289         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2290         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2291     };
2292     UINT32 i;
2293
2294     return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
2295 }