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