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