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