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