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