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