wined3d: Add missing GL locking to check_fbo_compat().
[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   switch (usage & WINED3DUSAGE_MASK) {
916 #define WINED3DUSAGE_TO_STR(u) case u: return #u
917     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
918     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
919     WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
920     WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
921     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
922     WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
923     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
924     WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
925     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
926     WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
927     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
928 #undef WINED3DUSAGE_TO_STR
929   case 0: return "none";
930   default:
931     FIXME("Unrecognized %u Usage!\n", usage);
932     return "unrecognized";
933   }
934 }
935
936 const char* debug_d3dusagequery(DWORD usagequery) {
937   switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
938 #define WINED3DUSAGEQUERY_TO_STR(u) case u: return #u
939     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
940     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
941     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
942     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
943     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
944     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
945     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
946 #undef WINED3DUSAGEQUERY_TO_STR
947   case 0: return "none";
948   default:
949     FIXME("Unrecognized %u Usage Query!\n", usagequery);
950     return "unrecognized";
951   }
952 }
953
954 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
955     switch (method) {
956 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
957         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
958         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
959         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
960         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
961         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
962         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
963         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
964 #undef WINED3DDECLMETHOD_TO_STR
965         default:
966             FIXME("Unrecognized %u declaration method!\n", method);
967             return "unrecognized";
968     }
969 }
970
971 const char* debug_d3ddeclusage(BYTE usage) {
972     switch (usage) {
973 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
974         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
975         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
976         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
977         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
978         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
979         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
980         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
981         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
982         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
983         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
984         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
985         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
986         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
987         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
988 #undef WINED3DDECLUSAGE_TO_STR
989         default:
990             FIXME("Unrecognized %u declaration usage!\n", usage);
991             return "unrecognized";
992     }
993 }
994
995 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
996   switch (res) {
997 #define RES_TO_STR(res) case res: return #res
998     RES_TO_STR(WINED3DRTYPE_SURFACE);
999     RES_TO_STR(WINED3DRTYPE_VOLUME);
1000     RES_TO_STR(WINED3DRTYPE_TEXTURE);
1001     RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1002     RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1003     RES_TO_STR(WINED3DRTYPE_BUFFER);
1004 #undef  RES_TO_STR
1005   default:
1006     FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1007     return "unrecognized";
1008   }
1009 }
1010
1011 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1012   switch (PrimitiveType) {
1013 #define PRIM_TO_STR(prim) case prim: return #prim
1014     PRIM_TO_STR(WINED3DPT_UNDEFINED);
1015     PRIM_TO_STR(WINED3DPT_POINTLIST);
1016     PRIM_TO_STR(WINED3DPT_LINELIST);
1017     PRIM_TO_STR(WINED3DPT_LINESTRIP);
1018     PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1019     PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1020     PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1021     PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1022     PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1023     PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1024     PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1025 #undef  PRIM_TO_STR
1026   default:
1027     FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1028     return "unrecognized";
1029   }
1030 }
1031
1032 const char* debug_d3drenderstate(DWORD state) {
1033   switch (state) {
1034 #define D3DSTATE_TO_STR(u) case u: return #u
1035     D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE             );
1036     D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS                 );
1037     D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS            );
1038     D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE        );
1039     D3DSTATE_TO_STR(WINED3DRS_WRAPU                     );
1040     D3DSTATE_TO_STR(WINED3DRS_WRAPV                     );
1041     D3DSTATE_TO_STR(WINED3DRS_ZENABLE                   );
1042     D3DSTATE_TO_STR(WINED3DRS_FILLMODE                  );
1043     D3DSTATE_TO_STR(WINED3DRS_SHADEMODE                 );
1044     D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN               );
1045     D3DSTATE_TO_STR(WINED3DRS_MONOENABLE                );
1046     D3DSTATE_TO_STR(WINED3DRS_ROP2                      );
1047     D3DSTATE_TO_STR(WINED3DRS_PLANEMASK                 );
1048     D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE              );
1049     D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE           );
1050     D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL                 );
1051     D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG                );
1052     D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN                );
1053     D3DSTATE_TO_STR(WINED3DRS_SRCBLEND                  );
1054     D3DSTATE_TO_STR(WINED3DRS_DESTBLEND                 );
1055     D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND           );
1056     D3DSTATE_TO_STR(WINED3DRS_CULLMODE                  );
1057     D3DSTATE_TO_STR(WINED3DRS_ZFUNC                     );
1058     D3DSTATE_TO_STR(WINED3DRS_ALPHAREF                  );
1059     D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC                 );
1060     D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE              );
1061     D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE          );
1062     D3DSTATE_TO_STR(WINED3DRS_FOGENABLE                 );
1063     D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE            );
1064     D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE                  );
1065     D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL                  );
1066     D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX                 );
1067     D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA             );
1068     D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR                  );
1069     D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE              );
1070     D3DSTATE_TO_STR(WINED3DRS_FOGSTART                  );
1071     D3DSTATE_TO_STR(WINED3DRS_FOGEND                    );
1072     D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY                );
1073     D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE             );
1074     D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS             );
1075     D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE            );
1076     D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR               );
1077     D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU           );
1078     D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV           );
1079     D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS             );
1080     D3DSTATE_TO_STR(WINED3DRS_ZBIAS                     );
1081     D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE            );
1082     D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY                );
1083     D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH                );
1084     D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1085     D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE             );
1086     D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL               );
1087     D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL              );
1088     D3DSTATE_TO_STR(WINED3DRS_STENCILPASS               );
1089     D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC               );
1090     D3DSTATE_TO_STR(WINED3DRS_STENCILREF                );
1091     D3DSTATE_TO_STR(WINED3DRS_STENCILMASK               );
1092     D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK          );
1093     D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR             );
1094     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00          );
1095     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01          );
1096     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02          );
1097     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03          );
1098     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04          );
1099     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05          );
1100     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06          );
1101     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07          );
1102     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08          );
1103     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09          );
1104     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10          );
1105     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11          );
1106     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12          );
1107     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13          );
1108     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14          );
1109     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15          );
1110     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16          );
1111     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17          );
1112     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18          );
1113     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19          );
1114     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20          );
1115     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21          );
1116     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22          );
1117     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23          );
1118     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24          );
1119     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25          );
1120     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26          );
1121     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27          );
1122     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28          );
1123     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29          );
1124     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30          );
1125     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31          );
1126     D3DSTATE_TO_STR(WINED3DRS_WRAP0                     );
1127     D3DSTATE_TO_STR(WINED3DRS_WRAP1                     );
1128     D3DSTATE_TO_STR(WINED3DRS_WRAP2                     );
1129     D3DSTATE_TO_STR(WINED3DRS_WRAP3                     );
1130     D3DSTATE_TO_STR(WINED3DRS_WRAP4                     );
1131     D3DSTATE_TO_STR(WINED3DRS_WRAP5                     );
1132     D3DSTATE_TO_STR(WINED3DRS_WRAP6                     );
1133     D3DSTATE_TO_STR(WINED3DRS_WRAP7                     );
1134     D3DSTATE_TO_STR(WINED3DRS_CLIPPING                  );
1135     D3DSTATE_TO_STR(WINED3DRS_LIGHTING                  );
1136     D3DSTATE_TO_STR(WINED3DRS_EXTENTS                   );
1137     D3DSTATE_TO_STR(WINED3DRS_AMBIENT                   );
1138     D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE             );
1139     D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX               );
1140     D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER               );
1141     D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS          );
1142     D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE       );
1143     D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE     );
1144     D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE    );
1145     D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE     );
1146     D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE    );
1147     D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND               );
1148     D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE           );
1149     D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING  );
1150     D3DSTATE_TO_STR(WINED3DRS_POINTSIZE                 );
1151     D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN             );
1152     D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE         );
1153     D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE          );
1154     D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A              );
1155     D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B              );
1156     D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C              );
1157     D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS      );
1158     D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK           );
1159     D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE            );
1160     D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS             );
1161     D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN         );
1162     D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX             );
1163     D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE  );
1164     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE          );
1165     D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR               );
1166     D3DSTATE_TO_STR(WINED3DRS_BLENDOP                   );
1167     D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE            );
1168     D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE              );
1169     D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE         );
1170     D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS       );
1171     D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE     );
1172     D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL      );
1173     D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL      );
1174     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X            );
1175     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y            );
1176     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z            );
1177     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W            );
1178     D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1179     D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE       );
1180     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL           );
1181     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL          );
1182     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS           );
1183     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC           );
1184     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1         );
1185     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2         );
1186     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3         );
1187     D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR               );
1188     D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE           );
1189     D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS                 );
1190     D3DSTATE_TO_STR(WINED3DRS_WRAP8                     );
1191     D3DSTATE_TO_STR(WINED3DRS_WRAP9                     );
1192     D3DSTATE_TO_STR(WINED3DRS_WRAP10                    );
1193     D3DSTATE_TO_STR(WINED3DRS_WRAP11                    );
1194     D3DSTATE_TO_STR(WINED3DRS_WRAP12                    );
1195     D3DSTATE_TO_STR(WINED3DRS_WRAP13                    );
1196     D3DSTATE_TO_STR(WINED3DRS_WRAP14                    );
1197     D3DSTATE_TO_STR(WINED3DRS_WRAP15                    );
1198     D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE  );
1199     D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA             );
1200     D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA            );
1201     D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA              );
1202 #undef D3DSTATE_TO_STR
1203   default:
1204     FIXME("Unrecognized %u render state!\n", state);
1205     return "unrecognized";
1206   }
1207 }
1208
1209 const char* debug_d3dsamplerstate(DWORD state) {
1210   switch (state) {
1211 #define D3DSTATE_TO_STR(u) case u: return #u
1212     D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR  );
1213     D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU     );
1214     D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV     );
1215     D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW     );
1216     D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER    );
1217     D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER    );
1218     D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER    );
1219     D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1220     D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL  );
1221     D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1222     D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE  );
1223     D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1224     D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET   );
1225 #undef D3DSTATE_TO_STR
1226   default:
1227     FIXME("Unrecognized %u sampler state!\n", state);
1228     return "unrecognized";
1229   }
1230 }
1231
1232 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1233     switch (filter_type) {
1234 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1235         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1236         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1237         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1238         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1239         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1240         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1241         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1242         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1243 #undef D3DTEXTUREFILTERTYPE_TO_STR
1244         default:
1245             FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1246             return "unrecognized";
1247     }
1248 }
1249
1250 const char* debug_d3dtexturestate(DWORD state) {
1251   switch (state) {
1252 #define D3DSTATE_TO_STR(u) case u: return #u
1253     D3DSTATE_TO_STR(WINED3DTSS_COLOROP               );
1254     D3DSTATE_TO_STR(WINED3DTSS_COLORARG1             );
1255     D3DSTATE_TO_STR(WINED3DTSS_COLORARG2             );
1256     D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP               );
1257     D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1             );
1258     D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2             );
1259     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00          );
1260     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01          );
1261     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10          );
1262     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11          );
1263     D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX         );
1264     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE         );
1265     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET        );
1266     D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1267     D3DSTATE_TO_STR(WINED3DTSS_COLORARG0             );
1268     D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0             );
1269     D3DSTATE_TO_STR(WINED3DTSS_RESULTARG             );
1270     D3DSTATE_TO_STR(WINED3DTSS_CONSTANT              );
1271 #undef D3DSTATE_TO_STR
1272   default:
1273     FIXME("Unrecognized %u texture state!\n", state);
1274     return "unrecognized";
1275   }
1276 }
1277
1278 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1279     switch (d3dtop) {
1280 #define D3DTOP_TO_STR(u) case u: return #u
1281         D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1282         D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1283         D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1284         D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1285         D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1286         D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1287         D3DTOP_TO_STR(WINED3DTOP_ADD);
1288         D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1289         D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1290         D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1291         D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1292         D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1293         D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1294         D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1295         D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1296         D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1297         D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1298         D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1299         D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1300         D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1301         D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1302         D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1303         D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1304         D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1305         D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1306         D3DTOP_TO_STR(WINED3DTOP_LERP);
1307 #undef D3DTOP_TO_STR
1308         default:
1309             FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1310             return "unrecognized";
1311     }
1312 }
1313
1314 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1315     switch (tstype) {
1316 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1317     TSTYPE_TO_STR(WINED3DTS_VIEW);
1318     TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1319     TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1320     TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1321     TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1322     TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1323     TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1324     TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1325     TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1326     TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1327     TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1328 #undef TSTYPE_TO_STR
1329     default:
1330         if (tstype > 256 && tstype < 512) {
1331             FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1332             return ("WINED3DTS_WORLDMATRIX > 0");
1333         }
1334         FIXME("Unrecognized %u WINED3DTS\n", tstype);
1335         return "unrecognized";
1336     }
1337 }
1338
1339 const char* debug_d3dpool(WINED3DPOOL Pool) {
1340   switch (Pool) {
1341 #define POOL_TO_STR(p) case p: return #p
1342     POOL_TO_STR(WINED3DPOOL_DEFAULT);
1343     POOL_TO_STR(WINED3DPOOL_MANAGED);
1344     POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1345     POOL_TO_STR(WINED3DPOOL_SCRATCH);
1346 #undef  POOL_TO_STR
1347   default:
1348     FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1349     return "unrecognized";
1350   }
1351 }
1352
1353 const char *debug_fbostatus(GLenum status) {
1354     switch(status) {
1355 #define FBOSTATUS_TO_STR(u) case u: return #u
1356         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1357         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1358         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1359         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1360         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1361         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1362         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1363         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
1364         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1365 #undef FBOSTATUS_TO_STR
1366         default:
1367             FIXME("Unrecognied FBO status 0x%08x\n", status);
1368             return "unrecognized";
1369     }
1370 }
1371
1372 const char *debug_glerror(GLenum error) {
1373     switch(error) {
1374 #define GLERROR_TO_STR(u) case u: return #u
1375         GLERROR_TO_STR(GL_NO_ERROR);
1376         GLERROR_TO_STR(GL_INVALID_ENUM);
1377         GLERROR_TO_STR(GL_INVALID_VALUE);
1378         GLERROR_TO_STR(GL_INVALID_OPERATION);
1379         GLERROR_TO_STR(GL_STACK_OVERFLOW);
1380         GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1381         GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1382         GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1383 #undef GLERROR_TO_STR
1384         default:
1385             FIXME("Unrecognied GL error 0x%08x\n", error);
1386             return "unrecognized";
1387     }
1388 }
1389
1390 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1391     switch(basis) {
1392         case WINED3DBASIS_BEZIER:       return "WINED3DBASIS_BEZIER";
1393         case WINED3DBASIS_BSPLINE:      return "WINED3DBASIS_BSPLINE";
1394         case WINED3DBASIS_INTERPOLATE:  return "WINED3DBASIS_INTERPOLATE";
1395         default:                        return "unrecognized";
1396     }
1397 }
1398
1399 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1400     switch(degree) {
1401         case WINED3DDEGREE_LINEAR:      return "WINED3DDEGREE_LINEAR";
1402         case WINED3DDEGREE_QUADRATIC:   return "WINED3DDEGREE_QUADRATIC";
1403         case WINED3DDEGREE_CUBIC:       return "WINED3DDEGREE_CUBIC";
1404         case WINED3DDEGREE_QUINTIC:     return "WINED3DDEGREE_QUINTIC";
1405         default:                        return "unrecognized";
1406     }
1407 }
1408
1409 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
1410 {
1411     switch(source)
1412     {
1413 #define WINED3D_TO_STR(x) case x: return #x
1414         WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1415         WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1416         WINED3D_TO_STR(CHANNEL_SOURCE_X);
1417         WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1418         WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1419         WINED3D_TO_STR(CHANNEL_SOURCE_W);
1420         WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1421         WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1422 #undef WINED3D_TO_STR
1423         default:
1424             FIXME("Unrecognized fixup_channel_source %#x\n", source);
1425             return "unrecognized";
1426     }
1427 }
1428
1429 static const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1430 {
1431     switch(yuv_fixup)
1432     {
1433 #define WINED3D_TO_STR(x) case x: return #x
1434         WINED3D_TO_STR(YUV_FIXUP_YUY2);
1435         WINED3D_TO_STR(YUV_FIXUP_UYVY);
1436         WINED3D_TO_STR(YUV_FIXUP_YV12);
1437 #undef WINED3D_TO_STR
1438         default:
1439             FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1440             return "unrecognized";
1441     }
1442 }
1443
1444 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1445 {
1446     if (is_yuv_fixup(fixup))
1447     {
1448         TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1449         return;
1450     }
1451
1452     TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1453     TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1454     TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1455     TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1456 }
1457
1458 const char *debug_surflocation(DWORD flag) {
1459     char buf[128];
1460
1461     buf[0] = 0;
1462     if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
1463     if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
1464     if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
1465     if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
1466     return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
1467 }
1468
1469 /*****************************************************************************
1470  * Useful functions mapping GL <-> D3D values
1471  */
1472 GLenum StencilOp(DWORD op) {
1473     switch(op) {
1474     case WINED3DSTENCILOP_KEEP    : return GL_KEEP;
1475     case WINED3DSTENCILOP_ZERO    : return GL_ZERO;
1476     case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1477     case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1478     case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1479     case WINED3DSTENCILOP_INVERT  : return GL_INVERT;
1480     case WINED3DSTENCILOP_INCR    : return GL_INCR_WRAP_EXT;
1481     case WINED3DSTENCILOP_DECR    : return GL_DECR_WRAP_EXT;
1482     default:
1483         FIXME("Unrecognized stencil op %d\n", op);
1484         return GL_KEEP;
1485     }
1486 }
1487
1488 GLenum CompareFunc(DWORD func) {
1489     switch ((WINED3DCMPFUNC)func) {
1490     case WINED3DCMP_NEVER        : return GL_NEVER;
1491     case WINED3DCMP_LESS         : return GL_LESS;
1492     case WINED3DCMP_EQUAL        : return GL_EQUAL;
1493     case WINED3DCMP_LESSEQUAL    : return GL_LEQUAL;
1494     case WINED3DCMP_GREATER      : return GL_GREATER;
1495     case WINED3DCMP_NOTEQUAL     : return GL_NOTEQUAL;
1496     case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1497     case WINED3DCMP_ALWAYS       : return GL_ALWAYS;
1498     default:
1499         FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1500         return 0;
1501     }
1502 }
1503
1504 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1505     if (op == WINED3DTOP_DISABLE) return FALSE;
1506     if (This->stateBlock->textures[stage]) return FALSE;
1507
1508     if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1509             && op != WINED3DTOP_SELECTARG2) return TRUE;
1510     if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1511             && op != WINED3DTOP_SELECTARG1) return TRUE;
1512     if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1513             && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1514
1515     return FALSE;
1516 }
1517
1518 /* Setup this textures matrix according to the texture flags*/
1519 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
1520         WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
1521 {
1522     float mat[16];
1523
1524     glMatrixMode(GL_TEXTURE);
1525     checkGLcall("glMatrixMode(GL_TEXTURE)");
1526
1527     if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1528         glLoadIdentity();
1529         checkGLcall("glLoadIdentity()");
1530         return;
1531     }
1532
1533     if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1534         ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1535         return;
1536     }
1537
1538     memcpy(mat, smat, 16 * sizeof(float));
1539
1540     if (flags & WINED3DTTFF_PROJECTED) {
1541         if(!ffp_proj_control) {
1542             switch (flags & ~WINED3DTTFF_PROJECTED) {
1543             case WINED3DTTFF_COUNT2:
1544                 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1545                 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1546                 break;
1547             case WINED3DTTFF_COUNT3:
1548                 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1549                 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1550                 break;
1551             }
1552         }
1553     } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1554         if(!calculatedCoords) {
1555             switch(vtx_fmt)
1556             {
1557                 case WINED3DFMT_R32_FLOAT:
1558                     /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1559                      * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1560                      * the input value to the transformation will be 0, so the matrix value is irrelevant
1561                      */
1562                     mat[12] = mat[4];
1563                     mat[13] = mat[5];
1564                     mat[14] = mat[6];
1565                     mat[15] = mat[7];
1566                     break;
1567                 case WINED3DFMT_R32G32_FLOAT:
1568                     /* See above, just 3rd and 4th coord
1569                     */
1570                     mat[12] = mat[8];
1571                     mat[13] = mat[9];
1572                     mat[14] = mat[10];
1573                     mat[15] = mat[11];
1574                     break;
1575                 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
1576                 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
1577
1578                 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1579                  * into a bad place. The division elimination below will apply to make sure the
1580                  * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1581                  */
1582                 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
1583                     break;
1584                 default:
1585                     FIXME("Unexpected fixed function texture coord input\n");
1586             }
1587         }
1588         if(!ffp_proj_control) {
1589             switch (flags & ~WINED3DTTFF_PROJECTED) {
1590                 /* case WINED3DTTFF_COUNT1: Won't ever get here */
1591                 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
1592                 /* OpenGL divides the first 3 vertex coord by the 4th by default,
1593                 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
1594                 * the 4th coord evaluates to 1.0 to eliminate that.
1595                 *
1596                 * If the fixed function pipeline is used, the 4th value remains unused,
1597                 * so there is no danger in doing this. With vertex shaders we have a
1598                 * problem. Should an app hit that problem, the code here would have to
1599                 * check for pixel shaders, and the shader has to undo the default gl divide.
1600                 *
1601                 * A more serious problem occurs if the app passes 4 coordinates in, and the
1602                 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
1603                 * or a replacement shader
1604                 */
1605                 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
1606             }
1607         }
1608     }
1609
1610     glLoadMatrixf(mat);
1611     checkGLcall("glLoadMatrixf(mat)");
1612 }
1613 #undef GLINFO_LOCATION
1614
1615 /* This small helper function is used to convert a bitmask into the number of masked bits */
1616 unsigned int count_bits(unsigned int mask)
1617 {
1618     unsigned int count;
1619     for (count = 0; mask; ++count)
1620     {
1621         mask &= mask - 1;
1622     }
1623     return count;
1624 }
1625
1626 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
1627  * The later function requires individual color components. */
1628 BOOL getColorBits(const struct GlPixelFormatDesc *format_desc,
1629         short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
1630 {
1631     TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
1632     switch(format_desc->format)
1633     {
1634         case WINED3DFMT_X8R8G8B8:
1635         case WINED3DFMT_R8G8B8:
1636         case WINED3DFMT_A8R8G8B8:
1637         case WINED3DFMT_R8G8B8A8_UNORM:
1638         case WINED3DFMT_A2R10G10B10:
1639         case WINED3DFMT_X1R5G5B5:
1640         case WINED3DFMT_A1R5G5B5:
1641         case WINED3DFMT_R5G6B5:
1642         case WINED3DFMT_X4R4G4B4:
1643         case WINED3DFMT_A4R4G4B4:
1644         case WINED3DFMT_R3G3B2:
1645         case WINED3DFMT_A8P8:
1646         case WINED3DFMT_P8:
1647             break;
1648         default:
1649             ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
1650             return FALSE;
1651     }
1652
1653     *redSize = count_bits(format_desc->red_mask);
1654     *greenSize = count_bits(format_desc->green_mask);
1655     *blueSize = count_bits(format_desc->blue_mask);
1656     *alphaSize = count_bits(format_desc->alpha_mask);
1657     *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
1658
1659     TRACE("Returning red:  %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
1660             *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
1661     return TRUE;
1662 }
1663
1664 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
1665 BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize)
1666 {
1667     TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
1668     switch(format_desc->format)
1669     {
1670         case WINED3DFMT_D16_LOCKABLE:
1671         case WINED3DFMT_D16_UNORM:
1672         case WINED3DFMT_D15S1:
1673         case WINED3DFMT_D24X8:
1674         case WINED3DFMT_D24X4S4:
1675         case WINED3DFMT_D24S8:
1676         case WINED3DFMT_D24FS8:
1677         case WINED3DFMT_D32:
1678         case WINED3DFMT_D32F_LOCKABLE:
1679             break;
1680         default:
1681             FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
1682             return FALSE;
1683     }
1684
1685     *depthSize = format_desc->depth_size;
1686     *stencilSize = format_desc->stencil_size;
1687
1688     TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
1689             *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
1690     return TRUE;
1691 }
1692
1693 /* DirectDraw stuff */
1694 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
1695     switch(depth) {
1696         case 8:  return WINED3DFMT_P8;
1697         case 15: return WINED3DFMT_X1R5G5B5;
1698         case 16: return WINED3DFMT_R5G6B5;
1699         case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
1700         case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
1701         default: return WINED3DFMT_UNKNOWN;
1702     }
1703 }
1704
1705 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
1706     WINED3DMATRIX temp;
1707
1708     /* Now do the multiplication 'by hand'.
1709        I know that all this could be optimised, but this will be done later :-) */
1710     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);
1711     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);
1712     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);
1713     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);
1714
1715     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);
1716     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);
1717     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);
1718     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);
1719
1720     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);
1721     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);
1722     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);
1723     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);
1724
1725     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);
1726     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);
1727     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);
1728     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);
1729
1730     /* And copy the new matrix in the good storage.. */
1731     memcpy(dest, &temp, 16 * sizeof(float));
1732 }
1733
1734 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
1735     DWORD size = 0;
1736     int i;
1737     int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
1738
1739     if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
1740     if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
1741     if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
1742     if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
1743     switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
1744         case WINED3DFVF_XYZ:    size += 3 * sizeof(float); break;
1745         case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
1746         case WINED3DFVF_XYZB1:  size += 4 * sizeof(float); break;
1747         case WINED3DFVF_XYZB2:  size += 5 * sizeof(float); break;
1748         case WINED3DFVF_XYZB3:  size += 6 * sizeof(float); break;
1749         case WINED3DFVF_XYZB4:  size += 7 * sizeof(float); break;
1750         case WINED3DFVF_XYZB5:  size += 8 * sizeof(float); break;
1751         case WINED3DFVF_XYZW:   size += 4 * sizeof(float); break;
1752         default: ERR("Unexpected position mask\n");
1753     }
1754     for (i = 0; i < numTextures; i++) {
1755         size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
1756     }
1757
1758     return size;
1759 }
1760
1761 /***********************************************************************
1762  * CalculateTexRect
1763  *
1764  * Calculates the dimensions of the opengl texture used for blits.
1765  * Handled oversized opengl textures and updates the source rectangle
1766  * accordingly
1767  *
1768  * Params:
1769  *  This: Surface to operate on
1770  *  Rect: Requested rectangle
1771  *
1772  * Returns:
1773  *  TRUE if the texture part can be loaded,
1774  *  FALSE otherwise
1775  *
1776  *********************************************************************/
1777 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
1778
1779 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
1780     int x1 = Rect->left, x2 = Rect->right;
1781     int y1 = Rect->top, y2 = Rect->bottom;
1782     GLint maxSize = GL_LIMITS(texture_size);
1783
1784     TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
1785           Rect->left, Rect->top, Rect->right, Rect->bottom);
1786
1787     /* The sizes might be reversed */
1788     if(Rect->left > Rect->right) {
1789         x1 = Rect->right;
1790         x2 = Rect->left;
1791     }
1792     if(Rect->top > Rect->bottom) {
1793         y1 = Rect->bottom;
1794         y2 = Rect->top;
1795     }
1796
1797     /* No oversized texture? This is easy */
1798     if(!(This->Flags & SFLAG_OVERSIZE)) {
1799         /* Which rect from the texture do I need? */
1800         if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
1801             glTexCoord[0] = (float) Rect->left;
1802             glTexCoord[2] = (float) Rect->top;
1803             glTexCoord[1] = (float) Rect->right;
1804             glTexCoord[3] = (float) Rect->bottom;
1805         } else {
1806             glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
1807             glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
1808             glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
1809             glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
1810         }
1811
1812         return TRUE;
1813     } else {
1814         /* Check if we can succeed at all */
1815         if( (x2 - x1) > maxSize ||
1816             (y2 - y1) > maxSize ) {
1817             TRACE("Requested rectangle is too large for gl\n");
1818             return FALSE;
1819         }
1820
1821         /* A part of the texture has to be picked. First, check if
1822          * some texture part is loaded already, if yes try to re-use it.
1823          * If the texture is dirty, or the part can't be used,
1824          * re-position the part to load
1825          */
1826         if(This->Flags & SFLAG_INTEXTURE) {
1827             if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
1828                This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
1829                 /* Ok, the rectangle is ok, re-use it */
1830                 TRACE("Using existing gl Texture\n");
1831             } else {
1832                 /* Rectangle is not ok, dirtify the texture to reload it */
1833                 TRACE("Dirtifying texture to force reload\n");
1834                 This->Flags &= ~SFLAG_INTEXTURE;
1835             }
1836         }
1837
1838         /* Now if we are dirty(no else if!) */
1839         if(!(This->Flags & SFLAG_INTEXTURE)) {
1840             /* Set the new rectangle. Use the following strategy:
1841              * 1) Use as big textures as possible.
1842              * 2) Place the texture part in the way that the requested
1843              *    part is in the middle of the texture(well, almost)
1844              * 3) If the texture is moved over the edges of the
1845              *    surface, replace it nicely
1846              * 4) If the coord is not limiting the texture size,
1847              *    use the whole size
1848              */
1849             if((This->pow2Width) > maxSize) {
1850                 This->glRect.left = x1 - maxSize / 2;
1851                 if(This->glRect.left < 0) {
1852                     This->glRect.left = 0;
1853                 }
1854                 This->glRect.right = This->glRect.left + maxSize;
1855                 if(This->glRect.right > This->currentDesc.Width) {
1856                     This->glRect.right = This->currentDesc.Width;
1857                     This->glRect.left = This->glRect.right - maxSize;
1858                 }
1859             } else {
1860                 This->glRect.left = 0;
1861                 This->glRect.right = This->pow2Width;
1862             }
1863
1864             if(This->pow2Height > maxSize) {
1865                 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
1866                 if(This->glRect.top < 0) This->glRect.top = 0;
1867                 This->glRect.bottom = This->glRect.left + maxSize;
1868                 if(This->glRect.bottom > This->currentDesc.Height) {
1869                     This->glRect.bottom = This->currentDesc.Height;
1870                     This->glRect.top = This->glRect.bottom - maxSize;
1871                 }
1872             } else {
1873                 This->glRect.top = 0;
1874                 This->glRect.bottom = This->pow2Height;
1875             }
1876             TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
1877                    This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
1878         }
1879
1880         /* Re-calculate the rect to draw */
1881         Rect->left -= This->glRect.left;
1882         Rect->right -= This->glRect.left;
1883         Rect->top -= This->glRect.top;
1884         Rect->bottom -= This->glRect.top;
1885
1886         /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
1887          * or the pow2Width / pow2Height of the surface.
1888          *
1889          * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
1890          * as regular GL_TEXTURE_2D.
1891          */
1892         glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
1893         glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
1894         glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
1895         glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
1896     }
1897     return TRUE;
1898 }
1899 #undef GLINFO_LOCATION
1900
1901 /* Hash table functions */
1902
1903 struct hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
1904 {
1905     struct hash_table_t *table;
1906     unsigned int initial_size = 8;
1907
1908     table = HeapAlloc(GetProcessHeap(), 0, sizeof(struct hash_table_t) + (initial_size * sizeof(struct list)));
1909     if (!table)
1910     {
1911         ERR("Failed to allocate table, returning NULL.\n");
1912         return NULL;
1913     }
1914
1915     table->hash_function = hash_function;
1916     table->compare_function = compare_function;
1917
1918     table->grow_size = initial_size - (initial_size >> 2);
1919     table->shrink_size = 0;
1920
1921     table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
1922     if (!table->buckets)
1923     {
1924         ERR("Failed to allocate table buckets, returning NULL.\n");
1925         HeapFree(GetProcessHeap(), 0, table);
1926         return NULL;
1927     }
1928     table->bucket_count = initial_size;
1929
1930     table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(struct hash_table_entry_t));
1931     if (!table->entries)
1932     {
1933         ERR("Failed to allocate table entries, returning NULL.\n");
1934         HeapFree(GetProcessHeap(), 0, table->buckets);
1935         HeapFree(GetProcessHeap(), 0, table);
1936         return NULL;
1937     }
1938     table->entry_count = 0;
1939
1940     list_init(&table->free_entries);
1941     table->count = 0;
1942
1943     return table;
1944 }
1945
1946 void hash_table_destroy(struct hash_table_t *table, void (*free_value)(void *value, void *cb), void *cb)
1947 {
1948     unsigned int i = 0;
1949
1950     for (i = 0; i < table->entry_count; ++i)
1951     {
1952         if(free_value) {
1953             free_value(table->entries[i].value, cb);
1954         }
1955         HeapFree(GetProcessHeap(), 0, table->entries[i].key);
1956     }
1957
1958     HeapFree(GetProcessHeap(), 0, table->entries);
1959     HeapFree(GetProcessHeap(), 0, table->buckets);
1960     HeapFree(GetProcessHeap(), 0, table);
1961 }
1962
1963 void hash_table_for_each_entry(struct hash_table_t *table, void (*callback)(void *value, void *context), void *context)
1964 {
1965     unsigned int i = 0;
1966
1967     for (i = 0; i < table->entry_count; ++i)
1968     {
1969         callback(table->entries[i].value, context);
1970     }
1971 }
1972
1973 static inline struct hash_table_entry_t *hash_table_get_by_idx(const struct hash_table_t *table, const void *key,
1974         unsigned int idx)
1975 {
1976     struct hash_table_entry_t *entry;
1977
1978     if (table->buckets[idx].next)
1979         LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), struct hash_table_entry_t, entry)
1980             if (table->compare_function(entry->key, key)) return entry;
1981
1982     return NULL;
1983 }
1984
1985 static BOOL hash_table_resize(struct hash_table_t *table, unsigned int new_bucket_count)
1986 {
1987     unsigned int new_entry_count = 0;
1988     struct hash_table_entry_t *new_entries;
1989     struct list *new_buckets;
1990     unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
1991     unsigned int i;
1992
1993     new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
1994     if (!new_buckets)
1995     {
1996         ERR("Failed to allocate new buckets, returning FALSE.\n");
1997         return FALSE;
1998     }
1999
2000     new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(struct hash_table_entry_t));
2001     if (!new_entries)
2002     {
2003         ERR("Failed to allocate new entries, returning FALSE.\n");
2004         HeapFree(GetProcessHeap(), 0, new_buckets);
2005         return FALSE;
2006     }
2007
2008     for (i = 0; i < table->bucket_count; ++i)
2009     {
2010         if (table->buckets[i].next)
2011         {
2012             struct hash_table_entry_t *entry, *entry2;
2013
2014             LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], struct hash_table_entry_t, entry)
2015             {
2016                 int j;
2017                 struct hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
2018                 *new_entry = *entry;
2019
2020                 j = new_entry->hash & (new_bucket_count - 1);
2021
2022                 if (!new_buckets[j].next) list_init(&new_buckets[j]);
2023                 list_add_head(&new_buckets[j], &new_entry->entry);
2024             }
2025         }
2026     }
2027
2028     HeapFree(GetProcessHeap(), 0, table->buckets);
2029     table->buckets = new_buckets;
2030
2031     HeapFree(GetProcessHeap(), 0, table->entries);
2032     table->entries = new_entries;
2033
2034     table->entry_count = new_entry_count;
2035     list_init(&table->free_entries);
2036
2037     table->bucket_count = new_bucket_count;
2038     table->grow_size = grow_size;
2039     table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
2040
2041     return TRUE;
2042 }
2043
2044 void hash_table_put(struct hash_table_t *table, void *key, void *value)
2045 {
2046     unsigned int idx;
2047     unsigned int hash;
2048     struct hash_table_entry_t *entry;
2049
2050     hash = table->hash_function(key);
2051     idx = hash & (table->bucket_count - 1);
2052     entry = hash_table_get_by_idx(table, key, idx);
2053
2054     if (entry)
2055     {
2056         HeapFree(GetProcessHeap(), 0, key);
2057         entry->value = value;
2058
2059         if (!value)
2060         {
2061             HeapFree(GetProcessHeap(), 0, entry->key);
2062             entry->key = NULL;
2063
2064             /* Remove the entry */
2065             list_remove(&entry->entry);
2066             list_add_head(&table->free_entries, &entry->entry);
2067
2068             --table->count;
2069
2070             /* Shrink if necessary */
2071             if (table->count < table->shrink_size) {
2072                 if (!hash_table_resize(table, table->bucket_count >> 1))
2073                 {
2074                     ERR("Failed to shrink the table...\n");
2075                 }
2076             }
2077         }
2078
2079         return;
2080     }
2081
2082     if (!value) return;
2083
2084     /* Grow if necessary */
2085     if (table->count >= table->grow_size)
2086     {
2087         if (!hash_table_resize(table, table->bucket_count << 1))
2088         {
2089             ERR("Failed to grow the table, returning.\n");
2090             return;
2091         }
2092
2093         idx = hash & (table->bucket_count - 1);
2094     }
2095
2096     /* Find an entry to insert */
2097     if (!list_empty(&table->free_entries))
2098     {
2099         struct list *elem = list_head(&table->free_entries);
2100
2101         list_remove(elem);
2102         entry = LIST_ENTRY(elem, struct hash_table_entry_t, entry);
2103     } else {
2104         entry = table->entries + (table->entry_count++);
2105     }
2106
2107     /* Insert the entry */
2108     entry->key = key;
2109     entry->value = value;
2110     entry->hash = hash;
2111     if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
2112     list_add_head(&table->buckets[idx], &entry->entry);
2113
2114     ++table->count;
2115 }
2116
2117 void hash_table_remove(struct hash_table_t *table, void *key)
2118 {
2119     hash_table_put(table, key, NULL);
2120 }
2121
2122 void *hash_table_get(const struct hash_table_t *table, const void *key)
2123 {
2124     unsigned int idx;
2125     struct hash_table_entry_t *entry;
2126
2127     idx = table->hash_function(key) & (table->bucket_count - 1);
2128     entry = hash_table_get_by_idx(table, key, idx);
2129
2130     return entry ? entry->value : NULL;
2131 }
2132
2133 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2134 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2135 #define ARG1 0x01
2136 #define ARG2 0x02
2137 #define ARG0 0x04
2138     static const unsigned char args[WINED3DTOP_LERP + 1] = {
2139         /* undefined                        */  0,
2140         /* D3DTOP_DISABLE                   */  0,
2141         /* D3DTOP_SELECTARG1                */  ARG1,
2142         /* D3DTOP_SELECTARG2                */  ARG2,
2143         /* D3DTOP_MODULATE                  */  ARG1 | ARG2,
2144         /* D3DTOP_MODULATE2X                */  ARG1 | ARG2,
2145         /* D3DTOP_MODULATE4X                */  ARG1 | ARG2,
2146         /* D3DTOP_ADD                       */  ARG1 | ARG2,
2147         /* D3DTOP_ADDSIGNED                 */  ARG1 | ARG2,
2148         /* D3DTOP_ADDSIGNED2X               */  ARG1 | ARG2,
2149         /* D3DTOP_SUBTRACT                  */  ARG1 | ARG2,
2150         /* D3DTOP_ADDSMOOTH                 */  ARG1 | ARG2,
2151         /* D3DTOP_BLENDDIFFUSEALPHA         */  ARG1 | ARG2,
2152         /* D3DTOP_BLENDTEXTUREALPHA         */  ARG1 | ARG2,
2153         /* D3DTOP_BLENDFACTORALPHA          */  ARG1 | ARG2,
2154         /* D3DTOP_BLENDTEXTUREALPHAPM       */  ARG1 | ARG2,
2155         /* D3DTOP_BLENDCURRENTALPHA         */  ARG1 | ARG2,
2156         /* D3DTOP_PREMODULATE               */  ARG1 | ARG2,
2157         /* D3DTOP_MODULATEALPHA_ADDCOLOR    */  ARG1 | ARG2,
2158         /* D3DTOP_MODULATECOLOR_ADDALPHA    */  ARG1 | ARG2,
2159         /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */  ARG1 | ARG2,
2160         /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */  ARG1 | ARG2,
2161         /* D3DTOP_BUMPENVMAP                */  ARG1 | ARG2,
2162         /* D3DTOP_BUMPENVMAPLUMINANCE       */  ARG1 | ARG2,
2163         /* D3DTOP_DOTPRODUCT3               */  ARG1 | ARG2,
2164         /* D3DTOP_MULTIPLYADD               */  ARG1 | ARG2 | ARG0,
2165         /* D3DTOP_LERP                      */  ARG1 | ARG2 | ARG0
2166     };
2167     unsigned int i;
2168     DWORD ttff;
2169     DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2170
2171     for(i = 0; i < GL_LIMITS(texture_stages); i++) {
2172         IWineD3DBaseTextureImpl *texture;
2173         settings->op[i].padding = 0;
2174         if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2175             settings->op[i].cop = WINED3DTOP_DISABLE;
2176             settings->op[i].aop = WINED3DTOP_DISABLE;
2177             settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2178             settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2179             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2180             settings->op[i].dst = resultreg;
2181             settings->op[i].tex_type = tex_1d;
2182             settings->op[i].projected = proj_none;
2183             i++;
2184             break;
2185         }
2186
2187         texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2188         if(texture) {
2189             settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2190             if(ignore_textype) {
2191                 settings->op[i].tex_type = tex_1d;
2192             } else {
2193                 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2194                     case GL_TEXTURE_1D:
2195                         settings->op[i].tex_type = tex_1d;
2196                         break;
2197                     case GL_TEXTURE_2D:
2198                         settings->op[i].tex_type = tex_2d;
2199                         break;
2200                     case GL_TEXTURE_3D:
2201                         settings->op[i].tex_type = tex_3d;
2202                         break;
2203                     case GL_TEXTURE_CUBE_MAP_ARB:
2204                         settings->op[i].tex_type = tex_cube;
2205                         break;
2206                     case GL_TEXTURE_RECTANGLE_ARB:
2207                         settings->op[i].tex_type = tex_rect;
2208                         break;
2209                 }
2210             }
2211         } else {
2212             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2213             settings->op[i].tex_type = tex_1d;
2214         }
2215
2216         cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2217         aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2218
2219         carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2220         carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2221         carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2222
2223         if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
2224                          carg1, carg2, carg0)) {
2225             carg0 = ARG_UNUSED;
2226             carg2 = ARG_UNUSED;
2227             carg1 = WINED3DTA_CURRENT;
2228             cop = WINED3DTOP_SELECTARG1;
2229         }
2230
2231         if(cop == WINED3DTOP_DOTPRODUCT3) {
2232             /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2233              * the color result to the alpha component of the destination
2234              */
2235             aop = cop;
2236             aarg1 = carg1;
2237             aarg2 = carg2;
2238             aarg0 = carg0;
2239         } else {
2240             aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2241             aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2242             aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2243         }
2244
2245         if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2246         {
2247             UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2248
2249             if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2250             {
2251                 IWineD3DSurfaceImpl *surf;
2252                 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2253
2254                 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2255                 {
2256                     if (aop == WINED3DTOP_DISABLE)
2257                     {
2258                        aarg1 = WINED3DTA_TEXTURE;
2259                        aop = WINED3DTOP_SELECTARG1;
2260                     }
2261                     else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2262                     {
2263                         if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2264                         {
2265                             aarg2 = WINED3DTA_TEXTURE;
2266                             aop = WINED3DTOP_MODULATE;
2267                         }
2268                         else aarg1 = WINED3DTA_TEXTURE;
2269                     }
2270                     else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2271                     {
2272                         if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2273                         {
2274                             aarg1 = WINED3DTA_TEXTURE;
2275                             aop = WINED3DTOP_MODULATE;
2276                         }
2277                         else aarg2 = WINED3DTA_TEXTURE;
2278                     }
2279                 }
2280             }
2281         }
2282
2283         if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
2284            aarg1, aarg2, aarg0)) {
2285                aarg0 = ARG_UNUSED;
2286                aarg2 = ARG_UNUSED;
2287                aarg1 = WINED3DTA_CURRENT;
2288                aop = WINED3DTOP_SELECTARG1;
2289         }
2290
2291         if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2292            aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2293             ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2294             if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2295                 settings->op[i].projected = proj_count3;
2296             } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2297                 settings->op[i].projected = proj_count4;
2298             } else {
2299                 settings->op[i].projected = proj_none;
2300             }
2301         } else {
2302             settings->op[i].projected = proj_none;
2303         }
2304
2305         settings->op[i].cop = cop;
2306         settings->op[i].aop = aop;
2307         settings->op[i].carg0 = carg0;
2308         settings->op[i].carg1 = carg1;
2309         settings->op[i].carg2 = carg2;
2310         settings->op[i].aarg0 = aarg0;
2311         settings->op[i].aarg1 = aarg1;
2312         settings->op[i].aarg2 = aarg2;
2313
2314         if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2315             settings->op[i].dst = tempreg;
2316         } else {
2317             settings->op[i].dst = resultreg;
2318         }
2319     }
2320
2321     /* Clear unsupported stages */
2322     for(; i < MAX_TEXTURES; i++) {
2323         memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2324     }
2325
2326     if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2327         settings->fog = FOG_OFF;
2328     } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2329         if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2330             settings->fog = FOG_LINEAR;
2331         } else {
2332             switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2333                 case WINED3DFOG_NONE:
2334                 case WINED3DFOG_LINEAR:
2335                     settings->fog = FOG_LINEAR;
2336                     break;
2337                 case WINED3DFOG_EXP:
2338                     settings->fog = FOG_EXP;
2339                     break;
2340                 case WINED3DFOG_EXP2:
2341                     settings->fog = FOG_EXP2;
2342                     break;
2343             }
2344         }
2345     } else {
2346         switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2347             case WINED3DFOG_LINEAR:
2348                 settings->fog = FOG_LINEAR;
2349                 break;
2350             case WINED3DFOG_EXP:
2351                 settings->fog = FOG_EXP;
2352                 break;
2353             case WINED3DFOG_EXP2:
2354                 settings->fog = FOG_EXP2;
2355                 break;
2356         }
2357     }
2358     if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2359         settings->sRGB_write = 1;
2360     } else {
2361         settings->sRGB_write = 0;
2362     }
2363 }
2364 #undef GLINFO_LOCATION
2365
2366 const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
2367         const struct ffp_frag_settings *settings)
2368 {
2369     return hash_table_get(fragment_shaders, settings);
2370 }
2371
2372 void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *desc) {
2373     struct ffp_frag_settings *key = HeapAlloc(GetProcessHeap(), 0, sizeof(*key));
2374     /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2375      * whereas desc points to an extended structure with implementation specific parts.
2376      * Make a copy of the key because hash_table_put takes ownership of it
2377      */
2378     *key = desc->settings;
2379     hash_table_put(shaders, key, desc);
2380 }
2381
2382 /* Activates the texture dimension according to the bound D3D texture.
2383  * Does not care for the colorop or correct gl texture unit(when using nvrc)
2384  * Requires the caller to activate the correct unit before
2385  */
2386 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2387 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2388     if(stateblock->textures[stage]) {
2389         switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2390             case GL_TEXTURE_2D:
2391                 glDisable(GL_TEXTURE_3D);
2392                 checkGLcall("glDisable(GL_TEXTURE_3D)");
2393                 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2394                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2395                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2396                 }
2397                 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2398                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
2399                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2400                 }
2401                 glEnable(GL_TEXTURE_2D);
2402                 checkGLcall("glEnable(GL_TEXTURE_2D)");
2403                 break;
2404             case GL_TEXTURE_RECTANGLE_ARB:
2405                 glDisable(GL_TEXTURE_2D);
2406                 checkGLcall("glDisable(GL_TEXTURE_2D)");
2407                 glDisable(GL_TEXTURE_3D);
2408                 checkGLcall("glDisable(GL_TEXTURE_3D)");
2409                 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2410                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2411                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2412                 }
2413                 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2414                 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2415                 break;
2416             case GL_TEXTURE_3D:
2417                 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2418                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2419                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2420                 }
2421                 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2422                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
2423                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2424                 }
2425                 glDisable(GL_TEXTURE_2D);
2426                 checkGLcall("glDisable(GL_TEXTURE_2D)");
2427                 glEnable(GL_TEXTURE_3D);
2428                 checkGLcall("glEnable(GL_TEXTURE_3D)");
2429                 break;
2430             case GL_TEXTURE_CUBE_MAP_ARB:
2431                 glDisable(GL_TEXTURE_2D);
2432                 checkGLcall("glDisable(GL_TEXTURE_2D)");
2433                 glDisable(GL_TEXTURE_3D);
2434                 checkGLcall("glDisable(GL_TEXTURE_3D)");
2435                 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2436                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
2437                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2438                 }
2439                 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2440                 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2441               break;
2442         }
2443     } else {
2444         glEnable(GL_TEXTURE_2D);
2445         checkGLcall("glEnable(GL_TEXTURE_2D)");
2446         glDisable(GL_TEXTURE_3D);
2447         checkGLcall("glDisable(GL_TEXTURE_3D)");
2448         if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2449             glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2450             checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2451         }
2452         if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2453             glDisable(GL_TEXTURE_RECTANGLE_ARB);
2454             checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2455         }
2456         /* Binding textures is done by samplers. A dummy texture will be bound */
2457     }
2458 }
2459
2460 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2461     DWORD sampler = state - STATE_SAMPLER(0);
2462     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2463
2464     /* No need to enable / disable anything here for unused samplers. The tex_colorop
2465     * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2466     * will take care of this business
2467     */
2468     if(mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= GL_LIMITS(textures)) return;
2469     if(sampler >= stateblock->lowest_disabled_stage) return;
2470     if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2471
2472     texture_activate_dimensions(sampler, stateblock, context);
2473 }
2474 #undef GLINFO_LOCATION
2475
2476 unsigned int ffp_frag_program_key_hash(const void *key)
2477 {
2478     const struct ffp_frag_settings *k = key;
2479     unsigned int hash = 0, i;
2480     const DWORD *blob;
2481
2482     /* This takes the texture op settings of stage 0 and 1 into account.
2483      * how exactly depends on the memory laybout of the compiler, but it
2484      * should not matter too much. Stages > 1 are used rarely, so there's
2485      * no need to process them. Even if they're used it is likely that
2486      * the ffp setup has distinct stage 0 and 1 settings.
2487      */
2488     for(i = 0; i < 2; i++) {
2489         blob = (const DWORD *)&k->op[i];
2490         hash ^= blob[0] ^ blob[1];
2491     }
2492
2493     hash += ~(hash << 15);
2494     hash ^=  (hash >> 10);
2495     hash +=  (hash << 3);
2496     hash ^=  (hash >> 6);
2497     hash += ~(hash << 11);
2498     hash ^=  (hash >> 16);
2499
2500     return hash;
2501 }
2502
2503 BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb)
2504 {
2505     const struct ffp_frag_settings *ka = keya;
2506     const struct ffp_frag_settings *kb = keyb;
2507
2508     return memcmp(ka, kb, sizeof(*ka)) == 0;
2509 }
2510
2511 UINT wined3d_log2i(UINT32 x)
2512 {
2513     static const BYTE l[] =
2514     {
2515         0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2516         4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2517         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2518         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2519         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2520         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2521         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2522         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2523         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2524         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2525         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2526         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2527         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2528         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2529         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2530         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2531     };
2532     UINT32 i;
2533
2534     return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
2535 }