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