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