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