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