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