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