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