wined3d: Simplify wined3d_format_convert_from_float().
[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     enum wined3d_format_id id;
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   /* format id                           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     enum wined3d_format_id id;
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     enum wined3d_format_id id;
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     enum wined3d_format_id id;
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     enum wined3d_format_id id;
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     /* format id                        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(enum wined3d_format_id format_id)
860 {
861     /* First check if the format is at the position of its value.
862      * This will catch the argb formats before the loop is entered. */
863     if (format_id < (sizeof(formats) / sizeof(*formats))
864             && formats[format_id].id == format_id)
865     {
866         return format_id;
867     }
868     else
869     {
870         unsigned int i;
871
872         for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
873         {
874             if (formats[i].id == format_id) return i;
875         }
876     }
877     return -1;
878 }
879
880 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
881 {
882     UINT format_count = sizeof(formats) / sizeof(*formats);
883     UINT i;
884
885     gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->gl_formats));
886     if (!gl_info->gl_formats)
887     {
888         ERR("Failed to allocate memory.\n");
889         return FALSE;
890     }
891
892     for (i = 0; i < format_count; ++i)
893     {
894         struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
895         desc->id = formats[i].id;
896         desc->red_mask = formats[i].redMask;
897         desc->green_mask = formats[i].greenMask;
898         desc->blue_mask = formats[i].blueMask;
899         desc->alpha_mask = formats[i].alphaMask;
900         desc->byte_count = formats[i].bpp;
901         desc->depth_size = formats[i].depthSize;
902         desc->stencil_size = formats[i].stencilSize;
903     }
904
905     for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
906     {
907         int fmt_idx = getFmtIdx(format_base_flags[i].id);
908
909         if (fmt_idx == -1)
910         {
911             ERR("Format %s (%#x) not found.\n",
912                     debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
913             HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
914             return FALSE;
915         }
916
917         gl_info->gl_formats[fmt_idx].Flags |= format_base_flags[i].flags;
918     }
919
920     return TRUE;
921 }
922
923 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
924 {
925     unsigned int i;
926
927     for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
928     {
929         struct wined3d_format_desc *format_desc;
930         int fmt_idx = getFmtIdx(format_compression_info[i].id);
931
932         if (fmt_idx == -1)
933         {
934             ERR("Format %s (%#x) not found.\n",
935                     debug_d3dformat(format_compression_info[i].id), format_compression_info[i].id);
936             return FALSE;
937         }
938
939         format_desc = &gl_info->gl_formats[fmt_idx];
940         format_desc->block_width = format_compression_info[i].block_width;
941         format_desc->block_height = format_compression_info[i].block_height;
942         format_desc->block_byte_count = format_compression_info[i].block_byte_count;
943         format_desc->Flags |= WINED3DFMT_FLAG_COMPRESSED;
944     }
945
946     return TRUE;
947 }
948
949 /* Context activation is done by the caller. */
950 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format_desc *format_desc)
951 {
952     /* Check if the default internal format is supported as a frame buffer
953      * target, otherwise fall back to the render target internal.
954      *
955      * Try to stick to the standard format if possible, this limits precision differences. */
956     GLenum status;
957     GLuint tex;
958
959     ENTER_GL();
960
961     while(glGetError());
962     glDisable(GL_BLEND);
963
964     glGenTextures(1, &tex);
965     glBindTexture(GL_TEXTURE_2D, tex);
966
967     glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glInternal, 16, 16, 0,
968             format_desc->glFormat, format_desc->glType, NULL);
969     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
970     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
971
972     gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
973
974     status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
975     checkGLcall("Framebuffer format check");
976
977     if (status == GL_FRAMEBUFFER_COMPLETE)
978     {
979         TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format_desc->id));
980         format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
981         format_desc->rtInternal = format_desc->glInternal;
982     }
983     else
984     {
985         if (!format_desc->rtInternal)
986         {
987             if (format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)
988             {
989                 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
990                         " and no fallback specified.\n", debug_d3dformat(format_desc->id));
991                 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
992             }
993             else
994             {
995                 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format_desc->id));
996             }
997             format_desc->rtInternal = format_desc->glInternal;
998         }
999         else
1000         {
1001             TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1002                     debug_d3dformat(format_desc->id));
1003
1004             while(glGetError());
1005
1006             gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1007
1008             glTexImage2D(GL_TEXTURE_2D, 0, format_desc->rtInternal, 16, 16, 0,
1009                     format_desc->glFormat, format_desc->glType, NULL);
1010             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1011             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1012
1013             gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1014
1015             status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1016             checkGLcall("Framebuffer format check");
1017
1018             if (status == GL_FRAMEBUFFER_COMPLETE)
1019             {
1020                 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1021                         debug_d3dformat(format_desc->id));
1022             }
1023             else
1024             {
1025                 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1026                         debug_d3dformat(format_desc->id));
1027                 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1028             }
1029         }
1030     }
1031
1032     if (status == GL_FRAMEBUFFER_COMPLETE && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1033     {
1034         GLuint rb;
1035
1036         if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1037                 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1038         {
1039             gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1040             gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1041             gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1042             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1043             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1044             checkGLcall("RB attachment");
1045         }
1046
1047         glEnable(GL_BLEND);
1048         glClear(GL_COLOR_BUFFER_BIT);
1049         if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1050         {
1051             while(glGetError());
1052             TRACE("Format doesn't support post-pixelshader blending.\n");
1053             format_desc->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1054         }
1055
1056         if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1057                 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1058         {
1059             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1060             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1061             gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1062             checkGLcall("RB cleanup");
1063         }
1064     }
1065
1066     if (format_desc->glInternal != format_desc->glGammaInternal)
1067     {
1068         glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glGammaInternal, 16, 16, 0,
1069                 format_desc->glFormat, format_desc->glType, NULL);
1070         gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1071
1072         status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1073         checkGLcall("Framebuffer format check");
1074
1075         if (status == GL_FRAMEBUFFER_COMPLETE)
1076         {
1077             TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format_desc->id));
1078             format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1079         }
1080         else
1081         {
1082             WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format_desc->id));
1083         }
1084     }
1085
1086     glDeleteTextures(1, &tex);
1087
1088     LEAVE_GL();
1089 }
1090
1091 /* Context activation is done by the caller. */
1092 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1093 {
1094     unsigned int i;
1095     GLuint fbo;
1096
1097     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1098     {
1099         ENTER_GL();
1100
1101         gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1102         gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1103
1104         LEAVE_GL();
1105     }
1106
1107     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1108     {
1109         struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
1110
1111         if (!desc->glInternal) continue;
1112
1113         if (desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1114         {
1115             TRACE("Skipping format %s because it's a depth/stencil format.\n",
1116                     debug_d3dformat(desc->id));
1117             continue;
1118         }
1119
1120         if (desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
1121         {
1122             TRACE("Skipping format %s because it's a compressed format.\n",
1123                     debug_d3dformat(desc->id));
1124             continue;
1125         }
1126
1127         if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1128         {
1129             TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc->id));
1130             check_fbo_compat(gl_info, desc);
1131         }
1132         else
1133         {
1134             desc->rtInternal = desc->glInternal;
1135         }
1136     }
1137
1138     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1139     {
1140         ENTER_GL();
1141
1142         gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1143
1144         LEAVE_GL();
1145     }
1146 }
1147
1148 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1149 {
1150     unsigned int i;
1151
1152     for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1153     {
1154         int fmt_idx = getFmtIdx(format_texture_info[i].id);
1155         struct wined3d_format_desc *desc;
1156
1157         if (fmt_idx == -1)
1158         {
1159             ERR("Format %s (%#x) not found.\n",
1160                     debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1161             return FALSE;
1162         }
1163
1164         if (!gl_info->supported[format_texture_info[i].extension]) continue;
1165
1166         desc = &gl_info->gl_formats[fmt_idx];
1167         desc->glInternal = format_texture_info[i].gl_internal;
1168         desc->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1169         desc->rtInternal = format_texture_info[i].gl_rt_internal;
1170         desc->glFormat = format_texture_info[i].gl_format;
1171         desc->glType = format_texture_info[i].gl_type;
1172         desc->color_fixup = COLOR_FIXUP_IDENTITY;
1173         desc->Flags |= format_texture_info[i].flags;
1174         desc->heightscale = 1.0f;
1175
1176         /* Texture conversion stuff */
1177         desc->convert = format_texture_info[i].convert;
1178         desc->conv_byte_count = format_texture_info[i].conv_byte_count;
1179     }
1180
1181     return TRUE;
1182 }
1183
1184 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1185 {
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     c1 >>= 8; c2 >>= 8;
1190     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1191     c1 >>= 8; c2 >>= 8;
1192     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1193     return TRUE;
1194 }
1195
1196 /* A context is provided by the caller */
1197 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1198 {
1199     static const DWORD data[] = {0x00000000, 0xffffffff};
1200     GLuint tex, fbo, buffer;
1201     DWORD readback[16 * 1];
1202     BOOL ret = FALSE;
1203
1204     /* Render a filtered texture and see what happens. This is intended to detect the lack of
1205      * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1206      * falling back to software. If this changes in the future this code will get fooled and
1207      * apps might hit the software path due to incorrectly advertised caps.
1208      *
1209      * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1210      * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1211      * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1212      */
1213
1214     ENTER_GL();
1215     while(glGetError());
1216
1217     glGenTextures(1, &buffer);
1218     glBindTexture(GL_TEXTURE_2D, buffer);
1219     memset(readback, 0x7e, sizeof(readback));
1220     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1221     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1222     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1223     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1224     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1225     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1226
1227     glGenTextures(1, &tex);
1228     glBindTexture(GL_TEXTURE_2D, tex);
1229     glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1230     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1231     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1232     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1233     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1234     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1235     glEnable(GL_TEXTURE_2D);
1236
1237     gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1238     gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1239     gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1240     glDrawBuffer(GL_COLOR_ATTACHMENT0);
1241
1242     glViewport(0, 0, 16, 1);
1243     glDisable(GL_LIGHTING);
1244     glMatrixMode(GL_MODELVIEW);
1245     glLoadIdentity();
1246     glMatrixMode(GL_PROJECTION);
1247     glLoadIdentity();
1248
1249     glClearColor(0, 1, 0, 0);
1250     glClear(GL_COLOR_BUFFER_BIT);
1251
1252     glBegin(GL_TRIANGLE_STRIP);
1253     glTexCoord2f(0.0, 0.0);
1254     glVertex2f(-1.0f, -1.0f);
1255     glTexCoord2f(1.0, 0.0);
1256     glVertex2f(1.0f, -1.0f);
1257     glTexCoord2f(0.0, 1.0);
1258     glVertex2f(-1.0f, 1.0f);
1259     glTexCoord2f(1.0, 1.0);
1260     glVertex2f(1.0f, 1.0f);
1261     glEnd();
1262
1263     glBindTexture(GL_TEXTURE_2D, buffer);
1264     memset(readback, 0x7f, sizeof(readback));
1265     glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1266     if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1267        color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1268     {
1269         TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1270               readback[6], readback[9]);
1271         ret = FALSE;
1272     }
1273     else
1274     {
1275         TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1276               readback[6], readback[9]);
1277         ret = TRUE;
1278     }
1279
1280     gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1281     gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1282     glDeleteTextures(1, &tex);
1283     glDeleteTextures(1, &buffer);
1284
1285     if(glGetError())
1286     {
1287         FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1288         ret = FALSE;
1289     }
1290     LEAVE_GL();
1291     return ret;
1292 }
1293
1294 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1295 {
1296     struct wined3d_format_desc *desc;
1297     unsigned int fmt_idx, i;
1298     static const enum wined3d_format_id fmts16[] =
1299     {
1300         WINED3DFMT_R16_FLOAT,
1301         WINED3DFMT_R16G16_FLOAT,
1302         WINED3DFMT_R16G16B16A16_FLOAT,
1303     };
1304     BOOL filtered;
1305
1306     if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1307     {
1308         WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1309         if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1310         {
1311             TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1312             filtered = TRUE;
1313         }
1314         else if (gl_info->limits.glsl_varyings > 44)
1315         {
1316             TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1317             filtered = TRUE;
1318         }
1319         else
1320         {
1321             TRACE("Assuming no float16 blending\n");
1322             filtered = FALSE;
1323         }
1324
1325         if(filtered)
1326         {
1327             for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1328             {
1329                 fmt_idx = getFmtIdx(fmts16[i]);
1330                 gl_info->gl_formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
1331             }
1332         }
1333         return;
1334     }
1335
1336     for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1337     {
1338         fmt_idx = getFmtIdx(fmts16[i]);
1339         desc = &gl_info->gl_formats[fmt_idx];
1340         if(!desc->glInternal) continue; /* Not supported by GL */
1341
1342         filtered = check_filter(gl_info, gl_info->gl_formats[fmt_idx].glInternal);
1343         if(filtered)
1344         {
1345             TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1346             desc->Flags |= WINED3DFMT_FLAG_FILTERING;
1347         }
1348         else
1349         {
1350             TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1351         }
1352     }
1353 }
1354
1355 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1356 {
1357     int idx;
1358
1359     idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1360     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1361             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1362
1363     idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1364     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1365             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1366
1367     idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1368     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1369             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1370
1371     idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1372     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1373             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1374
1375     idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1376     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1377             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1378
1379     /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1380      * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1381      * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1382      * the only driver that implements it(fglrx) has a buggy implementation.
1383      *
1384      * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1385      * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1386      * conversion for this format.
1387      */
1388     if (!gl_info->supported[NV_TEXTURE_SHADER])
1389     {
1390         idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1391         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1392                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1393         idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1394         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1395                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1396     }
1397     else
1398     {
1399         idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1400         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1401                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1402
1403         idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1404         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1405                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1406     }
1407
1408     if (!gl_info->supported[NV_TEXTURE_SHADER])
1409     {
1410         /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1411          * with each other
1412          */
1413         idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1414         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1415                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1416         idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1417         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1418                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1419         idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1420         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1421                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1422     }
1423     else
1424     {
1425         /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1426          * are converted at surface loading time, but they do not need any modification in
1427          * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1428          * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1429          */
1430     }
1431
1432     if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1433     {
1434         idx = getFmtIdx(WINED3DFMT_ATI2N);
1435         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1436                 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1437     }
1438     else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1439     {
1440         idx = getFmtIdx(WINED3DFMT_ATI2N);
1441         gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
1442                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1443     }
1444
1445     if (!gl_info->supported[APPLE_YCBCR_422])
1446     {
1447         idx = getFmtIdx(WINED3DFMT_YUY2);
1448         gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1449
1450         idx = getFmtIdx(WINED3DFMT_UYVY);
1451         gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1452     }
1453
1454     idx = getFmtIdx(WINED3DFMT_YV12);
1455     gl_info->gl_formats[idx].heightscale = 1.5f;
1456     gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1457
1458     if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1459     {
1460         idx = getFmtIdx(WINED3DFMT_P8_UINT);
1461         gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1462     }
1463
1464     if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1465     {
1466         idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1467         gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
1468     }
1469
1470     if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1471     {
1472         /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1473          * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1474         idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1475         gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1476
1477         idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1478         gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1479     }
1480 }
1481
1482 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1483 {
1484     unsigned int i;
1485
1486     for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1487     {
1488         struct wined3d_format_desc *format_desc;
1489         int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1490
1491         if (fmt_idx == -1)
1492         {
1493             ERR("Format %s (%#x) not found.\n",
1494                     debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1495             return FALSE;
1496         }
1497
1498         format_desc = &gl_info->gl_formats[fmt_idx];
1499         format_desc->emit_idx = format_vertex_info[i].emit_idx;
1500         format_desc->component_count = format_vertex_info[i].component_count;
1501         format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1502         format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1503         format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
1504         format_desc->component_size = format_vertex_info[i].component_size;
1505     }
1506
1507     return TRUE;
1508 }
1509
1510 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1511 {
1512     if (!init_format_base_info(gl_info)) return FALSE;
1513
1514     if (!init_format_compression_info(gl_info))
1515     {
1516         HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1517         gl_info->gl_formats = NULL;
1518         return FALSE;
1519     }
1520
1521     return TRUE;
1522 }
1523
1524 /* Context activation is done by the caller. */
1525 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1526 {
1527     if (!init_format_base_info(gl_info)) return FALSE;
1528
1529     if (!init_format_compression_info(gl_info)) goto fail;
1530     if (!init_format_texture_info(gl_info)) goto fail;
1531     if (!init_format_vertex_info(gl_info)) goto fail;
1532
1533     apply_format_fixups(gl_info);
1534     init_format_fbo_compat_info(gl_info);
1535     init_format_filter_info(gl_info, vendor);
1536
1537     return TRUE;
1538
1539 fail:
1540     HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1541     gl_info->gl_formats = NULL;
1542     return FALSE;
1543 }
1544
1545 const struct wined3d_format_desc *getFormatDescEntry(enum wined3d_format_id format_id,
1546         const struct wined3d_gl_info *gl_info)
1547 {
1548     int idx = getFmtIdx(format_id);
1549
1550     if (idx == -1)
1551     {
1552         FIXME("Can't find format %s (%#x) in the format lookup table\n",
1553                 debug_d3dformat(format_id), format_id);
1554         /* Get the caller a valid pointer */
1555         idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1556     }
1557
1558     return &gl_info->gl_formats[idx];
1559 }
1560
1561 UINT wined3d_format_calculate_size(const struct wined3d_format_desc *format, UINT alignment, UINT width, UINT height)
1562 {
1563     UINT size;
1564
1565     if (format->id == WINED3DFMT_UNKNOWN)
1566     {
1567         size = 0;
1568     }
1569     else if (format->Flags & WINED3DFMT_FLAG_COMPRESSED)
1570     {
1571         UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1572         UINT row_count = (height + format->block_height - 1) / format->block_height;
1573         size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1574     }
1575     else
1576     {
1577         size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1578     }
1579
1580     if (format->heightscale != 0.0f) size *= format->heightscale;
1581
1582     return size;
1583 }
1584
1585 /*****************************************************************************
1586  * Trace formatting of useful values
1587  */
1588 const char *debug_d3dformat(enum wined3d_format_id format_id)
1589 {
1590     switch (format_id)
1591     {
1592 #define FMT_TO_STR(format_id) case format_id: return #format_id
1593         FMT_TO_STR(WINED3DFMT_UNKNOWN);
1594         FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1595         FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1596         FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1597         FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1598         FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1599         FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1600         FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1601         FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1602         FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1603         FMT_TO_STR(WINED3DFMT_P8_UINT);
1604         FMT_TO_STR(WINED3DFMT_L8_UNORM);
1605         FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1606         FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1607         FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1608         FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1609         FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1610         FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1611         FMT_TO_STR(WINED3DFMT_UYVY);
1612         FMT_TO_STR(WINED3DFMT_YUY2);
1613         FMT_TO_STR(WINED3DFMT_YV12);
1614         FMT_TO_STR(WINED3DFMT_DXT1);
1615         FMT_TO_STR(WINED3DFMT_DXT2);
1616         FMT_TO_STR(WINED3DFMT_DXT3);
1617         FMT_TO_STR(WINED3DFMT_DXT4);
1618         FMT_TO_STR(WINED3DFMT_DXT5);
1619         FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1620         FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1621         FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1622         FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1623         FMT_TO_STR(WINED3DFMT_D32_UNORM);
1624         FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1625         FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1626         FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1627         FMT_TO_STR(WINED3DFMT_L16_UNORM);
1628         FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1629         FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1630         FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1631         FMT_TO_STR(WINED3DFMT_ATI2N);
1632         FMT_TO_STR(WINED3DFMT_NVHU);
1633         FMT_TO_STR(WINED3DFMT_NVHS);
1634         FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1635         FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1636         FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1637         FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1638         FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1639         FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1640         FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1641         FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1642         FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1643         FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1644         FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1645         FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1646         FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1647         FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1648         FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1649         FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1650         FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1651         FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1652         FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1653         FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1654         FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1655         FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1656         FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1657         FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1658         FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1659         FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1660         FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1661         FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1662         FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1663         FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1664         FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1665         FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1666         FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1667         FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1668         FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1669         FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1670         FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1671         FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1672         FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1673         FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1674         FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1675         FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1676         FMT_TO_STR(WINED3DFMT_R32_UINT);
1677         FMT_TO_STR(WINED3DFMT_R32_SINT);
1678         FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1679         FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1680         FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1681         FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1682         FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1683         FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1684         FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1685         FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1686         FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1687         FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1688         FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1689         FMT_TO_STR(WINED3DFMT_D16_UNORM);
1690         FMT_TO_STR(WINED3DFMT_R16_UNORM);
1691         FMT_TO_STR(WINED3DFMT_R16_UINT);
1692         FMT_TO_STR(WINED3DFMT_R16_SNORM);
1693         FMT_TO_STR(WINED3DFMT_R16_SINT);
1694         FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1695         FMT_TO_STR(WINED3DFMT_R8_UNORM);
1696         FMT_TO_STR(WINED3DFMT_R8_UINT);
1697         FMT_TO_STR(WINED3DFMT_R8_SNORM);
1698         FMT_TO_STR(WINED3DFMT_R8_SINT);
1699         FMT_TO_STR(WINED3DFMT_A8_UNORM);
1700         FMT_TO_STR(WINED3DFMT_R1_UNORM);
1701         FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1702         FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1703         FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1704         FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1705         FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1706         FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1707         FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1708         FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1709         FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1710         FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1711         FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1712         FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1713         FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1714         FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1715         FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1716         FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1717         FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1718         FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1719         FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1720         FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1721         FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1722         FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1723 #undef FMT_TO_STR
1724         default:
1725         {
1726             char fourcc[5];
1727             fourcc[0] = (char)(format_id);
1728             fourcc[1] = (char)(format_id >> 8);
1729             fourcc[2] = (char)(format_id >> 16);
1730             fourcc[3] = (char)(format_id >> 24);
1731             fourcc[4] = 0;
1732             if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1733                 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1734             else
1735                 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1736         }
1737         return "unrecognized";
1738     }
1739 }
1740
1741 const char *debug_d3ddevicetype(WINED3DDEVTYPE devtype)
1742 {
1743     switch (devtype)
1744     {
1745 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1746         DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1747         DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1748         DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1749 #undef DEVTYPE_TO_STR
1750         default:
1751             FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1752             return "unrecognized";
1753     }
1754 }
1755
1756 const char *debug_d3dusage(DWORD usage)
1757 {
1758     char buf[333];
1759
1760     buf[0] = '\0';
1761 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1762     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1763     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1764     WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1765     WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1766     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1767     WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1768     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1769     WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1770     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1771     WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1772     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1773     WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1774     WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1775 #undef WINED3DUSAGE_TO_STR
1776     if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1777
1778     return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1779 }
1780
1781 const char *debug_d3dusagequery(DWORD usagequery)
1782 {
1783     char buf[238];
1784
1785     buf[0] = '\0';
1786 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1787     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1788     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1789     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1790     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1791     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1792     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1793     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1794 #undef WINED3DUSAGEQUERY_TO_STR
1795     if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1796
1797     return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1798 }
1799
1800 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1801     switch (method) {
1802 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1803         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1804         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1805         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1806         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1807         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1808         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1809         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1810 #undef WINED3DDECLMETHOD_TO_STR
1811         default:
1812             FIXME("Unrecognized %u declaration method!\n", method);
1813             return "unrecognized";
1814     }
1815 }
1816
1817 const char* debug_d3ddeclusage(BYTE usage) {
1818     switch (usage) {
1819 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1820         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1821         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1822         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1823         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1824         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1825         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1826         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1827         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1828         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1829         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1830         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1831         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1832         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1833         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1834 #undef WINED3DDECLUSAGE_TO_STR
1835         default:
1836             FIXME("Unrecognized %u declaration usage!\n", usage);
1837             return "unrecognized";
1838     }
1839 }
1840
1841 const char *debug_d3dresourcetype(WINED3DRESOURCETYPE res)
1842 {
1843     switch (res)
1844     {
1845 #define RES_TO_STR(res) case res: return #res
1846         RES_TO_STR(WINED3DRTYPE_SURFACE);
1847         RES_TO_STR(WINED3DRTYPE_VOLUME);
1848         RES_TO_STR(WINED3DRTYPE_TEXTURE);
1849         RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1850         RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1851         RES_TO_STR(WINED3DRTYPE_BUFFER);
1852 #undef  RES_TO_STR
1853         default:
1854             FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1855             return "unrecognized";
1856     }
1857 }
1858
1859 const char *debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType)
1860 {
1861     switch (PrimitiveType)
1862     {
1863 #define PRIM_TO_STR(prim) case prim: return #prim
1864         PRIM_TO_STR(WINED3DPT_UNDEFINED);
1865         PRIM_TO_STR(WINED3DPT_POINTLIST);
1866         PRIM_TO_STR(WINED3DPT_LINELIST);
1867         PRIM_TO_STR(WINED3DPT_LINESTRIP);
1868         PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1869         PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1870         PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1871         PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1872         PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1873         PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1874         PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1875 #undef  PRIM_TO_STR
1876         default:
1877             FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1878             return "unrecognized";
1879     }
1880 }
1881
1882 const char *debug_d3drenderstate(WINED3DRENDERSTATETYPE state)
1883 {
1884     switch (state)
1885     {
1886 #define D3DSTATE_TO_STR(u) case u: return #u
1887         D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS);
1888         D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE);
1889         D3DSTATE_TO_STR(WINED3DRS_WRAPU);
1890         D3DSTATE_TO_STR(WINED3DRS_WRAPV);
1891         D3DSTATE_TO_STR(WINED3DRS_ZENABLE);
1892         D3DSTATE_TO_STR(WINED3DRS_FILLMODE);
1893         D3DSTATE_TO_STR(WINED3DRS_SHADEMODE);
1894         D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN);
1895         D3DSTATE_TO_STR(WINED3DRS_MONOENABLE);
1896         D3DSTATE_TO_STR(WINED3DRS_ROP2);
1897         D3DSTATE_TO_STR(WINED3DRS_PLANEMASK);
1898         D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE);
1899         D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE);
1900         D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL);
1901         D3DSTATE_TO_STR(WINED3DRS_SRCBLEND);
1902         D3DSTATE_TO_STR(WINED3DRS_DESTBLEND);
1903         D3DSTATE_TO_STR(WINED3DRS_CULLMODE);
1904         D3DSTATE_TO_STR(WINED3DRS_ZFUNC);
1905         D3DSTATE_TO_STR(WINED3DRS_ALPHAREF);
1906         D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC);
1907         D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE);
1908         D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE);
1909         D3DSTATE_TO_STR(WINED3DRS_FOGENABLE);
1910         D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE);
1911         D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE);
1912         D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL);
1913         D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX);
1914         D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA);
1915         D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR);
1916         D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE);
1917         D3DSTATE_TO_STR(WINED3DRS_FOGSTART);
1918         D3DSTATE_TO_STR(WINED3DRS_FOGEND);
1919         D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY);
1920         D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE);
1921         D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS);
1922         D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE);
1923         D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS);
1924         D3DSTATE_TO_STR(WINED3DRS_ZBIAS);
1925         D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE);
1926         D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY);
1927         D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH);
1928         D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1929         D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE);
1930         D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL);
1931         D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL);
1932         D3DSTATE_TO_STR(WINED3DRS_STENCILPASS);
1933         D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC);
1934         D3DSTATE_TO_STR(WINED3DRS_STENCILREF);
1935         D3DSTATE_TO_STR(WINED3DRS_STENCILMASK);
1936         D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK);
1937         D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR);
1938         D3DSTATE_TO_STR(WINED3DRS_WRAP0);
1939         D3DSTATE_TO_STR(WINED3DRS_WRAP1);
1940         D3DSTATE_TO_STR(WINED3DRS_WRAP2);
1941         D3DSTATE_TO_STR(WINED3DRS_WRAP3);
1942         D3DSTATE_TO_STR(WINED3DRS_WRAP4);
1943         D3DSTATE_TO_STR(WINED3DRS_WRAP5);
1944         D3DSTATE_TO_STR(WINED3DRS_WRAP6);
1945         D3DSTATE_TO_STR(WINED3DRS_WRAP7);
1946         D3DSTATE_TO_STR(WINED3DRS_CLIPPING);
1947         D3DSTATE_TO_STR(WINED3DRS_LIGHTING);
1948         D3DSTATE_TO_STR(WINED3DRS_EXTENTS);
1949         D3DSTATE_TO_STR(WINED3DRS_AMBIENT);
1950         D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE);
1951         D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX);
1952         D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER);
1953         D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS);
1954         D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE);
1955         D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE);
1956         D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE);
1957         D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE);
1958         D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE);
1959         D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND);
1960         D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE);
1961         D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING);
1962         D3DSTATE_TO_STR(WINED3DRS_POINTSIZE);
1963         D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN);
1964         D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE);
1965         D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE);
1966         D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A);
1967         D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B);
1968         D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C);
1969         D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS);
1970         D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK);
1971         D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE);
1972         D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS);
1973         D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN);
1974         D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX);
1975         D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE);
1976         D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE);
1977         D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR);
1978         D3DSTATE_TO_STR(WINED3DRS_BLENDOP);
1979         D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE);
1980         D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE);
1981         D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE);
1982         D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS);
1983         D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE);
1984         D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL);
1985         D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL);
1986         D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X);
1987         D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y);
1988         D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z);
1989         D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W);
1990         D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1991         D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE);
1992         D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL);
1993         D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL);
1994         D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS);
1995         D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC);
1996         D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1);
1997         D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2);
1998         D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3);
1999         D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR);
2000         D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE);
2001         D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS);
2002         D3DSTATE_TO_STR(WINED3DRS_WRAP8);
2003         D3DSTATE_TO_STR(WINED3DRS_WRAP9);
2004         D3DSTATE_TO_STR(WINED3DRS_WRAP10);
2005         D3DSTATE_TO_STR(WINED3DRS_WRAP11);
2006         D3DSTATE_TO_STR(WINED3DRS_WRAP12);
2007         D3DSTATE_TO_STR(WINED3DRS_WRAP13);
2008         D3DSTATE_TO_STR(WINED3DRS_WRAP14);
2009         D3DSTATE_TO_STR(WINED3DRS_WRAP15);
2010         D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE);
2011         D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA);
2012         D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA);
2013         D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA);
2014 #undef D3DSTATE_TO_STR
2015         default:
2016             FIXME("Unrecognized %u render state!\n", state);
2017             return "unrecognized";
2018     }
2019 }
2020
2021 const char *debug_d3dsamplerstate(DWORD state)
2022 {
2023     switch (state)
2024     {
2025 #define D3DSTATE_TO_STR(u) case u: return #u
2026         D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR);
2027         D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU);
2028         D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV);
2029         D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW);
2030         D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER);
2031         D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER);
2032         D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER);
2033         D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
2034         D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL);
2035         D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
2036         D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE);
2037         D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX);
2038         D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET);
2039 #undef D3DSTATE_TO_STR
2040         default:
2041             FIXME("Unrecognized %u sampler state!\n", state);
2042             return "unrecognized";
2043     }
2044 }
2045
2046 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2047     switch (filter_type) {
2048 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2049         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2050         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2051         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2052         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2053         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2054         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2055         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2056         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2057 #undef D3DTEXTUREFILTERTYPE_TO_STR
2058         default:
2059             FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2060             return "unrecognized";
2061     }
2062 }
2063
2064 const char *debug_d3dtexturestate(DWORD state)
2065 {
2066     switch (state)
2067     {
2068 #define D3DSTATE_TO_STR(u) case u: return #u
2069         D3DSTATE_TO_STR(WINED3DTSS_COLOROP);
2070         D3DSTATE_TO_STR(WINED3DTSS_COLORARG1);
2071         D3DSTATE_TO_STR(WINED3DTSS_COLORARG2);
2072         D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP);
2073         D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1);
2074         D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2);
2075         D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00);
2076         D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01);
2077         D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10);
2078         D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11);
2079         D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX);
2080         D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE);
2081         D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET);
2082         D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS);
2083         D3DSTATE_TO_STR(WINED3DTSS_COLORARG0);
2084         D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0);
2085         D3DSTATE_TO_STR(WINED3DTSS_RESULTARG);
2086         D3DSTATE_TO_STR(WINED3DTSS_CONSTANT);
2087 #undef D3DSTATE_TO_STR
2088         default:
2089             FIXME("Unrecognized %u texture state!\n", state);
2090             return "unrecognized";
2091     }
2092 }
2093
2094 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2095     switch (d3dtop) {
2096 #define D3DTOP_TO_STR(u) case u: return #u
2097         D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2098         D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2099         D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2100         D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2101         D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2102         D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2103         D3DTOP_TO_STR(WINED3DTOP_ADD);
2104         D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2105         D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2106         D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2107         D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2108         D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2109         D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2110         D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2111         D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2112         D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2113         D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2114         D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2115         D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2116         D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2117         D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2118         D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2119         D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2120         D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2121         D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2122         D3DTOP_TO_STR(WINED3DTOP_LERP);
2123 #undef D3DTOP_TO_STR
2124         default:
2125             FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2126             return "unrecognized";
2127     }
2128 }
2129
2130 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2131     switch (tstype) {
2132 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2133     TSTYPE_TO_STR(WINED3DTS_VIEW);
2134     TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2135     TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2136     TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2137     TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2138     TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2139     TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2140     TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2141     TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2142     TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2143     TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2144 #undef TSTYPE_TO_STR
2145     default:
2146         if (tstype > 256 && tstype < 512) {
2147             FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2148             return ("WINED3DTS_WORLDMATRIX > 0");
2149         }
2150         FIXME("Unrecognized %u WINED3DTS\n", tstype);
2151         return "unrecognized";
2152     }
2153 }
2154
2155 const char *debug_d3dstate(DWORD state)
2156 {
2157     if (STATE_IS_RENDER(state))
2158         return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2159     if (STATE_IS_TEXTURESTAGE(state))
2160     {
2161         DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2162         DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2163         return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2164                 texture_stage, debug_d3dtexturestate(texture_state));
2165     }
2166     if (STATE_IS_SAMPLER(state))
2167         return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2168     if (STATE_IS_PIXELSHADER(state))
2169         return "STATE_PIXELSHADER";
2170     if (STATE_IS_TRANSFORM(state))
2171         return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2172     if (STATE_IS_STREAMSRC(state))
2173         return "STATE_STREAMSRC";
2174     if (STATE_IS_INDEXBUFFER(state))
2175         return "STATE_INDEXBUFFER";
2176     if (STATE_IS_VDECL(state))
2177         return "STATE_VDECL";
2178     if (STATE_IS_VSHADER(state))
2179         return "STATE_VSHADER";
2180     if (STATE_IS_VIEWPORT(state))
2181         return "STATE_VIEWPORT";
2182     if (STATE_IS_VERTEXSHADERCONSTANT(state))
2183         return "STATE_VERTEXSHADERCONSTANT";
2184     if (STATE_IS_PIXELSHADERCONSTANT(state))
2185         return "STATE_PIXELSHADERCONSTANT";
2186     if (STATE_IS_ACTIVELIGHT(state))
2187         return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2188     if (STATE_IS_SCISSORRECT(state))
2189         return "STATE_SCISSORRECT";
2190     if (STATE_IS_CLIPPLANE(state))
2191         return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2192     if (STATE_IS_MATERIAL(state))
2193         return "STATE_MATERIAL";
2194     if (STATE_IS_FRONTFACE(state))
2195         return "STATE_FRONTFACE";
2196
2197     return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2198 }
2199
2200 const char *debug_d3dpool(WINED3DPOOL pool)
2201 {
2202     switch (pool)
2203     {
2204 #define POOL_TO_STR(p) case p: return #p
2205         POOL_TO_STR(WINED3DPOOL_DEFAULT);
2206         POOL_TO_STR(WINED3DPOOL_MANAGED);
2207         POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2208         POOL_TO_STR(WINED3DPOOL_SCRATCH);
2209 #undef  POOL_TO_STR
2210         default:
2211             FIXME("Unrecognized %u WINED3DPOOL!\n", pool);
2212             return "unrecognized";
2213     }
2214 }
2215
2216 const char *debug_fbostatus(GLenum status) {
2217     switch(status) {
2218 #define FBOSTATUS_TO_STR(u) case u: return #u
2219         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2220         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2221         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2222         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2223         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2224         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2225         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2226         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2227         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2228         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2229 #undef FBOSTATUS_TO_STR
2230         default:
2231             FIXME("Unrecognied FBO status 0x%08x\n", status);
2232             return "unrecognized";
2233     }
2234 }
2235
2236 const char *debug_glerror(GLenum error) {
2237     switch(error) {
2238 #define GLERROR_TO_STR(u) case u: return #u
2239         GLERROR_TO_STR(GL_NO_ERROR);
2240         GLERROR_TO_STR(GL_INVALID_ENUM);
2241         GLERROR_TO_STR(GL_INVALID_VALUE);
2242         GLERROR_TO_STR(GL_INVALID_OPERATION);
2243         GLERROR_TO_STR(GL_STACK_OVERFLOW);
2244         GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2245         GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2246         GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2247 #undef GLERROR_TO_STR
2248         default:
2249             FIXME("Unrecognied GL error 0x%08x\n", error);
2250             return "unrecognized";
2251     }
2252 }
2253
2254 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2255     switch(basis) {
2256         case WINED3DBASIS_BEZIER:       return "WINED3DBASIS_BEZIER";
2257         case WINED3DBASIS_BSPLINE:      return "WINED3DBASIS_BSPLINE";
2258         case WINED3DBASIS_INTERPOLATE:  return "WINED3DBASIS_INTERPOLATE";
2259         default:                        return "unrecognized";
2260     }
2261 }
2262
2263 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2264     switch(degree) {
2265         case WINED3DDEGREE_LINEAR:      return "WINED3DDEGREE_LINEAR";
2266         case WINED3DDEGREE_QUADRATIC:   return "WINED3DDEGREE_QUADRATIC";
2267         case WINED3DDEGREE_CUBIC:       return "WINED3DDEGREE_CUBIC";
2268         case WINED3DDEGREE_QUINTIC:     return "WINED3DDEGREE_QUINTIC";
2269         default:                        return "unrecognized";
2270     }
2271 }
2272
2273 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2274 {
2275     switch(source)
2276     {
2277 #define WINED3D_TO_STR(x) case x: return #x
2278         WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2279         WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2280         WINED3D_TO_STR(CHANNEL_SOURCE_X);
2281         WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2282         WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2283         WINED3D_TO_STR(CHANNEL_SOURCE_W);
2284         WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2285         WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2286 #undef WINED3D_TO_STR
2287         default:
2288             FIXME("Unrecognized fixup_channel_source %#x\n", source);
2289             return "unrecognized";
2290     }
2291 }
2292
2293 static const char *debug_complex_fixup(enum complex_fixup fixup)
2294 {
2295     switch(fixup)
2296     {
2297 #define WINED3D_TO_STR(x) case x: return #x
2298         WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2299         WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2300         WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2301         WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2302 #undef WINED3D_TO_STR
2303         default:
2304             FIXME("Unrecognized complex fixup %#x\n", fixup);
2305             return "unrecognized";
2306     }
2307 }
2308
2309 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2310 {
2311     if (is_complex_fixup(fixup))
2312     {
2313         TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2314         return;
2315     }
2316
2317     TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2318     TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2319     TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2320     TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2321 }
2322
2323 const char *debug_surflocation(DWORD flag) {
2324     char buf[128];
2325
2326     buf[0] = 0;
2327     if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2328     if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2329     if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2330     if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2331     return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2332 }
2333
2334 /*****************************************************************************
2335  * Useful functions mapping GL <-> D3D values
2336  */
2337 GLenum StencilOp(DWORD op) {
2338     switch(op) {
2339     case WINED3DSTENCILOP_KEEP    : return GL_KEEP;
2340     case WINED3DSTENCILOP_ZERO    : return GL_ZERO;
2341     case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2342     case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2343     case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2344     case WINED3DSTENCILOP_INVERT  : return GL_INVERT;
2345     case WINED3DSTENCILOP_INCR    : return GL_INCR_WRAP_EXT;
2346     case WINED3DSTENCILOP_DECR    : return GL_DECR_WRAP_EXT;
2347     default:
2348         FIXME("Unrecognized stencil op %d\n", op);
2349         return GL_KEEP;
2350     }
2351 }
2352
2353 GLenum CompareFunc(DWORD func) {
2354     switch ((WINED3DCMPFUNC)func) {
2355     case WINED3DCMP_NEVER        : return GL_NEVER;
2356     case WINED3DCMP_LESS         : return GL_LESS;
2357     case WINED3DCMP_EQUAL        : return GL_EQUAL;
2358     case WINED3DCMP_LESSEQUAL    : return GL_LEQUAL;
2359     case WINED3DCMP_GREATER      : return GL_GREATER;
2360     case WINED3DCMP_NOTEQUAL     : return GL_NOTEQUAL;
2361     case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2362     case WINED3DCMP_ALWAYS       : return GL_ALWAYS;
2363     default:
2364         FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2365         return 0;
2366     }
2367 }
2368
2369 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
2370     if (op == WINED3DTOP_DISABLE) return FALSE;
2371     if (This->stateBlock->textures[stage]) return FALSE;
2372
2373     if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2374             && op != WINED3DTOP_SELECTARG2) return TRUE;
2375     if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2376             && op != WINED3DTOP_SELECTARG1) return TRUE;
2377     if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2378             && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2379
2380     return FALSE;
2381 }
2382
2383 /* Setup this textures matrix according to the texture flags*/
2384 /* GL locking is done by the caller (state handler) */
2385 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2386         enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2387 {
2388     float mat[16];
2389
2390     glMatrixMode(GL_TEXTURE);
2391     checkGLcall("glMatrixMode(GL_TEXTURE)");
2392
2393     if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2394         glLoadIdentity();
2395         checkGLcall("glLoadIdentity()");
2396         return;
2397     }
2398
2399     if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2400         ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2401         return;
2402     }
2403
2404     memcpy(mat, smat, 16 * sizeof(float));
2405
2406     if (flags & WINED3DTTFF_PROJECTED) {
2407         if(!ffp_proj_control) {
2408             switch (flags & ~WINED3DTTFF_PROJECTED) {
2409             case WINED3DTTFF_COUNT2:
2410                 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2411                 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2412                 break;
2413             case WINED3DTTFF_COUNT3:
2414                 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2415                 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2416                 break;
2417             }
2418         }
2419     } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2420         if(!calculatedCoords) {
2421             switch(vtx_fmt)
2422             {
2423                 case WINED3DFMT_R32_FLOAT:
2424                     /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2425                      * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2426                      * the input value to the transformation will be 0, so the matrix value is irrelevant
2427                      */
2428                     mat[12] = mat[4];
2429                     mat[13] = mat[5];
2430                     mat[14] = mat[6];
2431                     mat[15] = mat[7];
2432                     break;
2433                 case WINED3DFMT_R32G32_FLOAT:
2434                     /* See above, just 3rd and 4th coord
2435                     */
2436                     mat[12] = mat[8];
2437                     mat[13] = mat[9];
2438                     mat[14] = mat[10];
2439                     mat[15] = mat[11];
2440                     break;
2441                 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2442                 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2443
2444                 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2445                  * into a bad place. The division elimination below will apply to make sure the
2446                  * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2447                  */
2448                 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2449                     break;
2450                 default:
2451                     FIXME("Unexpected fixed function texture coord input\n");
2452             }
2453         }
2454         if(!ffp_proj_control) {
2455             switch (flags & ~WINED3DTTFF_PROJECTED) {
2456                 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2457                 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2458                 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2459                 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2460                 * the 4th coord evaluates to 1.0 to eliminate that.
2461                 *
2462                 * If the fixed function pipeline is used, the 4th value remains unused,
2463                 * so there is no danger in doing this. With vertex shaders we have a
2464                 * problem. Should an app hit that problem, the code here would have to
2465                 * check for pixel shaders, and the shader has to undo the default gl divide.
2466                 *
2467                 * A more serious problem occurs if the app passes 4 coordinates in, and the
2468                 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2469                 * or a replacement shader
2470                 */
2471                 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2472             }
2473         }
2474     }
2475
2476     glLoadMatrixf(mat);
2477     checkGLcall("glLoadMatrixf(mat)");
2478 }
2479
2480 /* This small helper function is used to convert a bitmask into the number of masked bits */
2481 unsigned int count_bits(unsigned int mask)
2482 {
2483     unsigned int count;
2484     for (count = 0; mask; ++count)
2485     {
2486         mask &= mask - 1;
2487     }
2488     return count;
2489 }
2490
2491 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2492  * The later function requires individual color components. */
2493 BOOL getColorBits(const struct wined3d_format_desc *format_desc,
2494         short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2495 {
2496     TRACE("format %s.\n", debug_d3dformat(format_desc->id));
2497
2498     switch (format_desc->id)
2499     {
2500         case WINED3DFMT_B8G8R8X8_UNORM:
2501         case WINED3DFMT_B8G8R8_UNORM:
2502         case WINED3DFMT_B8G8R8A8_UNORM:
2503         case WINED3DFMT_R8G8B8A8_UNORM:
2504         case WINED3DFMT_B10G10R10A2_UNORM:
2505         case WINED3DFMT_B5G5R5X1_UNORM:
2506         case WINED3DFMT_B5G5R5A1_UNORM:
2507         case WINED3DFMT_B5G6R5_UNORM:
2508         case WINED3DFMT_B4G4R4X4_UNORM:
2509         case WINED3DFMT_B4G4R4A4_UNORM:
2510         case WINED3DFMT_B2G3R3_UNORM:
2511         case WINED3DFMT_P8_UINT_A8_UNORM:
2512         case WINED3DFMT_P8_UINT:
2513             break;
2514         default:
2515             FIXME("Unsupported format %s.\n", debug_d3dformat(format_desc->id));
2516             return FALSE;
2517     }
2518
2519     *redSize = count_bits(format_desc->red_mask);
2520     *greenSize = count_bits(format_desc->green_mask);
2521     *blueSize = count_bits(format_desc->blue_mask);
2522     *alphaSize = count_bits(format_desc->alpha_mask);
2523     *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2524
2525     TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2526             *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->id));
2527     return TRUE;
2528 }
2529
2530 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2531 BOOL getDepthStencilBits(const struct wined3d_format_desc *format_desc, short *depthSize, short *stencilSize)
2532 {
2533     TRACE("format %s.\n", debug_d3dformat(format_desc->id));
2534
2535     switch (format_desc->id)
2536     {
2537         case WINED3DFMT_D16_LOCKABLE:
2538         case WINED3DFMT_D16_UNORM:
2539         case WINED3DFMT_S1_UINT_D15_UNORM:
2540         case WINED3DFMT_X8D24_UNORM:
2541         case WINED3DFMT_S4X4_UINT_D24_UNORM:
2542         case WINED3DFMT_D24_UNORM_S8_UINT:
2543         case WINED3DFMT_S8_UINT_D24_FLOAT:
2544         case WINED3DFMT_D32_UNORM:
2545         case WINED3DFMT_D32_FLOAT:
2546             break;
2547         default:
2548             FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format_desc->id));
2549             return FALSE;
2550     }
2551
2552     *depthSize = format_desc->depth_size;
2553     *stencilSize = format_desc->stencil_size;
2554
2555     TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2556             *depthSize, *stencilSize, debug_d3dformat(format_desc->id));
2557     return TRUE;
2558 }
2559
2560 /* Note: It's the caller's responsibility to ensure values can be expressed
2561  * in the requested format. UNORM formats for example can only express values
2562  * in the range 0.0f -> 1.0f. */
2563 DWORD wined3d_format_convert_from_float(const struct wined3d_format_desc *format, const WINED3DCOLORVALUE *color)
2564 {
2565     static const struct
2566     {
2567         enum wined3d_format_id format_id;
2568         float r_mul;
2569         float g_mul;
2570         float b_mul;
2571         float a_mul;
2572         BYTE r_shift;
2573         BYTE g_shift;
2574         BYTE b_shift;
2575         BYTE a_shift;
2576     }
2577     conv[] =
2578     {
2579         {WINED3DFMT_B8G8R8A8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
2580         {WINED3DFMT_B8G8R8X8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
2581         {WINED3DFMT_B8G8R8_UNORM,       255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
2582         {WINED3DFMT_B5G6R5_UNORM,        31.0f,   63.0f,   31.0f,    0.0f, 11,  5,  0,  0},
2583         {WINED3DFMT_B5G5R5A1_UNORM,      31.0f,   31.0f,   31.0f,    1.0f, 10,  5,  0, 15},
2584         {WINED3DFMT_B5G5R5X1_UNORM,      31.0f,   31.0f,   31.0f,    1.0f, 10,  5,  0, 15},
2585         {WINED3DFMT_A8_UNORM,             0.0f,    0.0f,    0.0f,  255.0f,  0,  0,  0,  0},
2586         {WINED3DFMT_B4G4R4A4_UNORM,      15.0f,   15.0f,   15.0f,   15.0f,  8,  4,  0, 12},
2587         {WINED3DFMT_B4G4R4X4_UNORM,      15.0f,   15.0f,   15.0f,   15.0f,  8,  4,  0, 12},
2588         {WINED3DFMT_B2G3R3_UNORM,         7.0f,    7.0f,    3.0f,    0.0f,  5,  2,  0,  0},
2589         {WINED3DFMT_R8G8B8A8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f,  0,  8, 16, 24},
2590         {WINED3DFMT_R8G8B8X8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f,  0,  8, 16, 24},
2591         {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f,    3.0f, 20, 10,  0, 30},
2592         {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f,    3.0f,  0, 10, 20, 30},
2593     };
2594     unsigned int i;
2595
2596     TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2597             color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2598
2599     for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2600     {
2601         DWORD ret;
2602
2603         if (format->id != conv[i].format_id) continue;
2604
2605         ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2606         ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2607         ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2608         ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2609
2610         TRACE("Returning 0x%08x.\n", ret);
2611
2612         return ret;
2613     }
2614
2615     FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2616
2617     return 0;
2618 }
2619
2620 /* DirectDraw stuff */
2621 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2622 {
2623     switch (depth)
2624     {
2625         case 8:  return WINED3DFMT_P8_UINT;
2626         case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2627         case 16: return WINED3DFMT_B5G6R5_UNORM;
2628         case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2629         case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2630         default: return WINED3DFMT_UNKNOWN;
2631     }
2632 }
2633
2634 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2635     WINED3DMATRIX temp;
2636
2637     /* Now do the multiplication 'by hand'.
2638        I know that all this could be optimised, but this will be done later :-) */
2639     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);
2640     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);
2641     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);
2642     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);
2643
2644     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);
2645     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);
2646     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);
2647     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);
2648
2649     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);
2650     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);
2651     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);
2652     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);
2653
2654     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);
2655     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);
2656     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);
2657     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);
2658
2659     /* And copy the new matrix in the good storage.. */
2660     memcpy(dest, &temp, 16 * sizeof(float));
2661 }
2662
2663 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2664     DWORD size = 0;
2665     int i;
2666     int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2667
2668     if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2669     if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2670     if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2671     if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2672     switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2673         case WINED3DFVF_XYZ:    size += 3 * sizeof(float); break;
2674         case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2675         case WINED3DFVF_XYZB1:  size += 4 * sizeof(float); break;
2676         case WINED3DFVF_XYZB2:  size += 5 * sizeof(float); break;
2677         case WINED3DFVF_XYZB3:  size += 6 * sizeof(float); break;
2678         case WINED3DFVF_XYZB4:  size += 7 * sizeof(float); break;
2679         case WINED3DFVF_XYZB5:  size += 8 * sizeof(float); break;
2680         case WINED3DFVF_XYZW:   size += 4 * sizeof(float); break;
2681         default: ERR("Unexpected position mask\n");
2682     }
2683     for (i = 0; i < numTextures; i++) {
2684         size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2685     }
2686
2687     return size;
2688 }
2689
2690 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2691 #define ARG1 0x01
2692 #define ARG2 0x02
2693 #define ARG0 0x04
2694     static const unsigned char args[WINED3DTOP_LERP + 1] = {
2695         /* undefined                        */  0,
2696         /* D3DTOP_DISABLE                   */  0,
2697         /* D3DTOP_SELECTARG1                */  ARG1,
2698         /* D3DTOP_SELECTARG2                */  ARG2,
2699         /* D3DTOP_MODULATE                  */  ARG1 | ARG2,
2700         /* D3DTOP_MODULATE2X                */  ARG1 | ARG2,
2701         /* D3DTOP_MODULATE4X                */  ARG1 | ARG2,
2702         /* D3DTOP_ADD                       */  ARG1 | ARG2,
2703         /* D3DTOP_ADDSIGNED                 */  ARG1 | ARG2,
2704         /* D3DTOP_ADDSIGNED2X               */  ARG1 | ARG2,
2705         /* D3DTOP_SUBTRACT                  */  ARG1 | ARG2,
2706         /* D3DTOP_ADDSMOOTH                 */  ARG1 | ARG2,
2707         /* D3DTOP_BLENDDIFFUSEALPHA         */  ARG1 | ARG2,
2708         /* D3DTOP_BLENDTEXTUREALPHA         */  ARG1 | ARG2,
2709         /* D3DTOP_BLENDFACTORALPHA          */  ARG1 | ARG2,
2710         /* D3DTOP_BLENDTEXTUREALPHAPM       */  ARG1 | ARG2,
2711         /* D3DTOP_BLENDCURRENTALPHA         */  ARG1 | ARG2,
2712         /* D3DTOP_PREMODULATE               */  ARG1 | ARG2,
2713         /* D3DTOP_MODULATEALPHA_ADDCOLOR    */  ARG1 | ARG2,
2714         /* D3DTOP_MODULATECOLOR_ADDALPHA    */  ARG1 | ARG2,
2715         /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */  ARG1 | ARG2,
2716         /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */  ARG1 | ARG2,
2717         /* D3DTOP_BUMPENVMAP                */  ARG1 | ARG2,
2718         /* D3DTOP_BUMPENVMAPLUMINANCE       */  ARG1 | ARG2,
2719         /* D3DTOP_DOTPRODUCT3               */  ARG1 | ARG2,
2720         /* D3DTOP_MULTIPLYADD               */  ARG1 | ARG2 | ARG0,
2721         /* D3DTOP_LERP                      */  ARG1 | ARG2 | ARG0
2722     };
2723     unsigned int i;
2724     DWORD ttff;
2725     DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2726     IWineD3DDeviceImpl *device = stateblock->device;
2727     IWineD3DSurfaceImpl *rt = device->render_targets[0];
2728     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2729
2730     for (i = 0; i < gl_info->limits.texture_stages; ++i)
2731     {
2732         IWineD3DBaseTextureImpl *texture;
2733         settings->op[i].padding = 0;
2734         if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2735             settings->op[i].cop = WINED3DTOP_DISABLE;
2736             settings->op[i].aop = WINED3DTOP_DISABLE;
2737             settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2738             settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2739             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2740             settings->op[i].dst = resultreg;
2741             settings->op[i].tex_type = tex_1d;
2742             settings->op[i].projected = proj_none;
2743             i++;
2744             break;
2745         }
2746
2747         texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2748         if(texture) {
2749             settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2750             if(ignore_textype) {
2751                 settings->op[i].tex_type = tex_1d;
2752             } else {
2753                 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2754                     case GL_TEXTURE_1D:
2755                         settings->op[i].tex_type = tex_1d;
2756                         break;
2757                     case GL_TEXTURE_2D:
2758                         settings->op[i].tex_type = tex_2d;
2759                         break;
2760                     case GL_TEXTURE_3D:
2761                         settings->op[i].tex_type = tex_3d;
2762                         break;
2763                     case GL_TEXTURE_CUBE_MAP_ARB:
2764                         settings->op[i].tex_type = tex_cube;
2765                         break;
2766                     case GL_TEXTURE_RECTANGLE_ARB:
2767                         settings->op[i].tex_type = tex_rect;
2768                         break;
2769                 }
2770             }
2771         } else {
2772             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2773             settings->op[i].tex_type = tex_1d;
2774         }
2775
2776         cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2777         aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2778
2779         carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2780         carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2781         carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2782
2783         if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2784             carg0 = ARG_UNUSED;
2785             carg2 = ARG_UNUSED;
2786             carg1 = WINED3DTA_CURRENT;
2787             cop = WINED3DTOP_SELECTARG1;
2788         }
2789
2790         if(cop == WINED3DTOP_DOTPRODUCT3) {
2791             /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2792              * the color result to the alpha component of the destination
2793              */
2794             aop = cop;
2795             aarg1 = carg1;
2796             aarg2 = carg2;
2797             aarg0 = carg0;
2798         } else {
2799             aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2800             aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2801             aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2802         }
2803
2804         if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2805         {
2806             UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2807
2808             if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2809             {
2810                 IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)stateblock->textures[0];
2811                 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
2812
2813                 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2814                 {
2815                     if (aop == WINED3DTOP_DISABLE)
2816                     {
2817                        aarg1 = WINED3DTA_TEXTURE;
2818                        aop = WINED3DTOP_SELECTARG1;
2819                     }
2820                     else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2821                     {
2822                         if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2823                         {
2824                             aarg2 = WINED3DTA_TEXTURE;
2825                             aop = WINED3DTOP_MODULATE;
2826                         }
2827                         else aarg1 = WINED3DTA_TEXTURE;
2828                     }
2829                     else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2830                     {
2831                         if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2832                         {
2833                             aarg1 = WINED3DTA_TEXTURE;
2834                             aop = WINED3DTOP_MODULATE;
2835                         }
2836                         else aarg2 = WINED3DTA_TEXTURE;
2837                     }
2838                 }
2839             }
2840         }
2841
2842         if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2843                aarg0 = ARG_UNUSED;
2844                aarg2 = ARG_UNUSED;
2845                aarg1 = WINED3DTA_CURRENT;
2846                aop = WINED3DTOP_SELECTARG1;
2847         }
2848
2849         if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2850            aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2851             ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2852             if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2853                 settings->op[i].projected = proj_count3;
2854             } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2855                 settings->op[i].projected = proj_count4;
2856             } else {
2857                 settings->op[i].projected = proj_none;
2858             }
2859         } else {
2860             settings->op[i].projected = proj_none;
2861         }
2862
2863         settings->op[i].cop = cop;
2864         settings->op[i].aop = aop;
2865         settings->op[i].carg0 = carg0;
2866         settings->op[i].carg1 = carg1;
2867         settings->op[i].carg2 = carg2;
2868         settings->op[i].aarg0 = aarg0;
2869         settings->op[i].aarg1 = aarg1;
2870         settings->op[i].aarg2 = aarg2;
2871
2872         if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2873             settings->op[i].dst = tempreg;
2874         } else {
2875             settings->op[i].dst = resultreg;
2876         }
2877     }
2878
2879     /* Clear unsupported stages */
2880     for(; i < MAX_TEXTURES; i++) {
2881         memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2882     }
2883
2884     if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2885         settings->fog = FOG_OFF;
2886     } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2887         if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2888             settings->fog = FOG_LINEAR;
2889         } else {
2890             switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2891                 case WINED3DFOG_NONE:
2892                 case WINED3DFOG_LINEAR:
2893                     settings->fog = FOG_LINEAR;
2894                     break;
2895                 case WINED3DFOG_EXP:
2896                     settings->fog = FOG_EXP;
2897                     break;
2898                 case WINED3DFOG_EXP2:
2899                     settings->fog = FOG_EXP2;
2900                     break;
2901             }
2902         }
2903     } else {
2904         switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2905             case WINED3DFOG_LINEAR:
2906                 settings->fog = FOG_LINEAR;
2907                 break;
2908             case WINED3DFOG_EXP:
2909                 settings->fog = FOG_EXP;
2910                 break;
2911             case WINED3DFOG_EXP2:
2912                 settings->fog = FOG_EXP2;
2913                 break;
2914         }
2915     }
2916     if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE] &&
2917        rt->resource.format_desc->Flags & WINED3DFMT_FLAG_SRGB_WRITE) {
2918         settings->sRGB_write = 1;
2919     } else {
2920         settings->sRGB_write = 0;
2921     }
2922     if(device->vs_clipping || !use_vs(stateblock) || !stateblock->renderState[WINED3DRS_CLIPPING] ||
2923        !stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
2924         /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2925          * the fixed function vertex pipeline is used(which always supports clipplanes), or
2926          * if no clipplane is enabled
2927          */
2928         settings->emul_clipplanes = 0;
2929     } else {
2930         settings->emul_clipplanes = 1;
2931     }
2932 }
2933
2934 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2935         const struct ffp_frag_settings *settings)
2936 {
2937     struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2938     return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2939 }
2940
2941 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2942 {
2943     /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2944      * whereas desc points to an extended structure with implementation specific parts. */
2945     if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2946     {
2947         ERR("Failed to insert ffp frag shader.\n");
2948     }
2949 }
2950
2951 /* Activates the texture dimension according to the bound D3D texture.
2952  * Does not care for the colorop or correct gl texture unit(when using nvrc)
2953  * Requires the caller to activate the correct unit before
2954  */
2955 /* GL locking is done by the caller (state handler) */
2956 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2957 {
2958     const struct wined3d_gl_info *gl_info = context->gl_info;
2959
2960     if (stateblock->textures[stage])
2961     {
2962         switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2963             case GL_TEXTURE_2D:
2964                 glDisable(GL_TEXTURE_3D);
2965                 checkGLcall("glDisable(GL_TEXTURE_3D)");
2966                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2967                 {
2968                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2969                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2970                 }
2971                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2972                 {
2973                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
2974                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2975                 }
2976                 glEnable(GL_TEXTURE_2D);
2977                 checkGLcall("glEnable(GL_TEXTURE_2D)");
2978                 break;
2979             case GL_TEXTURE_RECTANGLE_ARB:
2980                 glDisable(GL_TEXTURE_2D);
2981                 checkGLcall("glDisable(GL_TEXTURE_2D)");
2982                 glDisable(GL_TEXTURE_3D);
2983                 checkGLcall("glDisable(GL_TEXTURE_3D)");
2984                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2985                 {
2986                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2987                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2988                 }
2989                 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2990                 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2991                 break;
2992             case GL_TEXTURE_3D:
2993                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2994                 {
2995                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2996                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2997                 }
2998                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2999                 {
3000                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
3001                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3002                 }
3003                 glDisable(GL_TEXTURE_2D);
3004                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3005                 glEnable(GL_TEXTURE_3D);
3006                 checkGLcall("glEnable(GL_TEXTURE_3D)");
3007                 break;
3008             case GL_TEXTURE_CUBE_MAP_ARB:
3009                 glDisable(GL_TEXTURE_2D);
3010                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3011                 glDisable(GL_TEXTURE_3D);
3012                 checkGLcall("glDisable(GL_TEXTURE_3D)");
3013                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3014                 {
3015                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
3016                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3017                 }
3018                 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3019                 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3020               break;
3021         }
3022     } else {
3023         glEnable(GL_TEXTURE_2D);
3024         checkGLcall("glEnable(GL_TEXTURE_2D)");
3025         glDisable(GL_TEXTURE_3D);
3026         checkGLcall("glDisable(GL_TEXTURE_3D)");
3027         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3028         {
3029             glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3030             checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3031         }
3032         if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3033         {
3034             glDisable(GL_TEXTURE_RECTANGLE_ARB);
3035             checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3036         }
3037         /* Binding textures is done by samplers. A dummy texture will be bound */
3038     }
3039 }
3040
3041 /* GL locking is done by the caller (state handler) */
3042 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3043 {
3044     DWORD sampler = state - STATE_SAMPLER(0);
3045     DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3046
3047     /* No need to enable / disable anything here for unused samplers. The tex_colorop
3048     * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3049     * will take care of this business
3050     */
3051     if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3052     if(sampler >= stateblock->lowest_disabled_stage) return;
3053     if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3054
3055     texture_activate_dimensions(sampler, stateblock, context);
3056 }
3057
3058 void *wined3d_rb_alloc(size_t size)
3059 {
3060     return HeapAlloc(GetProcessHeap(), 0, size);
3061 }
3062
3063 void *wined3d_rb_realloc(void *ptr, size_t size)
3064 {
3065     return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3066 }
3067
3068 void wined3d_rb_free(void *ptr)
3069 {
3070     HeapFree(GetProcessHeap(), 0, ptr);
3071 }
3072
3073 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3074 {
3075     const struct ffp_frag_settings *ka = key;
3076     const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3077
3078     return memcmp(ka, kb, sizeof(*ka));
3079 }
3080
3081 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3082 {
3083     wined3d_rb_alloc,
3084     wined3d_rb_realloc,
3085     wined3d_rb_free,
3086     ffp_frag_program_key_compare,
3087 };
3088
3089 UINT wined3d_log2i(UINT32 x)
3090 {
3091     static const UINT l[] =
3092     {
3093         ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3094           4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3095           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3096           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3097           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3098           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3099           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3100           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3101           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3102           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3103           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3104           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3105           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3106           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3107           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3108           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3109     };
3110     UINT32 i;
3111
3112     return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3113 }
3114
3115 /* Set the shader type for this device, depending on the given capabilities
3116  * and the user preferences in wined3d_settings. */
3117 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3118 {
3119     BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3120
3121     if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3122     else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3123     {
3124         /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3125          * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3126          * shaders only on this card. */
3127         if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3128         else *vs_selected = SHADER_GLSL;
3129     }
3130     else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3131     else *vs_selected = SHADER_NONE;
3132
3133     if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3134     else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3135     else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3136     else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3137     else *ps_selected = SHADER_NONE;
3138 }