windowscodecs: Handle TIFF's with RowsPerStrip greater than Height.
[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->format = 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->format));
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->format));
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->format));
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->format));
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->format));
1022             }
1023             else
1024             {
1025                 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1026                         debug_d3dformat(format_desc->format));
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->format));
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->format));
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->format));
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->format));
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->format));
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->format == 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   switch (devtype) {
1743 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1744     DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1745     DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1746     DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1747 #undef DEVTYPE_TO_STR
1748   default:
1749     FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1750     return "unrecognized";
1751   }
1752 }
1753
1754 const char *debug_d3dusage(DWORD usage)
1755 {
1756     char buf[333];
1757
1758     buf[0] = '\0';
1759 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1760     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1761     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1762     WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1763     WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1764     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1765     WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1766     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1767     WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1768     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1769     WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1770     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1771     WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1772     WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1773 #undef WINED3DUSAGE_TO_STR
1774     if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1775
1776     return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1777 }
1778
1779 const char *debug_d3dusagequery(DWORD usagequery)
1780 {
1781     char buf[238];
1782
1783     buf[0] = '\0';
1784 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1785     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1786     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1787     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1788     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1789     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1790     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1791     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1792 #undef WINED3DUSAGEQUERY_TO_STR
1793     if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1794
1795     return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1796 }
1797
1798 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1799     switch (method) {
1800 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1801         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1802         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1803         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1804         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1805         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1806         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1807         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1808 #undef WINED3DDECLMETHOD_TO_STR
1809         default:
1810             FIXME("Unrecognized %u declaration method!\n", method);
1811             return "unrecognized";
1812     }
1813 }
1814
1815 const char* debug_d3ddeclusage(BYTE usage) {
1816     switch (usage) {
1817 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1818         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1819         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1820         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1821         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1822         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1823         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1824         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1825         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1826         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1827         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1828         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1829         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1830         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1831         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1832 #undef WINED3DDECLUSAGE_TO_STR
1833         default:
1834             FIXME("Unrecognized %u declaration usage!\n", usage);
1835             return "unrecognized";
1836     }
1837 }
1838
1839 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1840   switch (res) {
1841 #define RES_TO_STR(res) case res: return #res
1842     RES_TO_STR(WINED3DRTYPE_SURFACE);
1843     RES_TO_STR(WINED3DRTYPE_VOLUME);
1844     RES_TO_STR(WINED3DRTYPE_TEXTURE);
1845     RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1846     RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1847     RES_TO_STR(WINED3DRTYPE_BUFFER);
1848 #undef  RES_TO_STR
1849   default:
1850     FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1851     return "unrecognized";
1852   }
1853 }
1854
1855 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1856   switch (PrimitiveType) {
1857 #define PRIM_TO_STR(prim) case prim: return #prim
1858     PRIM_TO_STR(WINED3DPT_UNDEFINED);
1859     PRIM_TO_STR(WINED3DPT_POINTLIST);
1860     PRIM_TO_STR(WINED3DPT_LINELIST);
1861     PRIM_TO_STR(WINED3DPT_LINESTRIP);
1862     PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1863     PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1864     PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1865     PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1866     PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1867     PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1868     PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1869 #undef  PRIM_TO_STR
1870   default:
1871     FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1872     return "unrecognized";
1873   }
1874 }
1875
1876 const char* debug_d3drenderstate(DWORD state) {
1877   switch (state) {
1878 #define D3DSTATE_TO_STR(u) case u: return #u
1879     D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS                 );
1880     D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE        );
1881     D3DSTATE_TO_STR(WINED3DRS_WRAPU                     );
1882     D3DSTATE_TO_STR(WINED3DRS_WRAPV                     );
1883     D3DSTATE_TO_STR(WINED3DRS_ZENABLE                   );
1884     D3DSTATE_TO_STR(WINED3DRS_FILLMODE                  );
1885     D3DSTATE_TO_STR(WINED3DRS_SHADEMODE                 );
1886     D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN               );
1887     D3DSTATE_TO_STR(WINED3DRS_MONOENABLE                );
1888     D3DSTATE_TO_STR(WINED3DRS_ROP2                      );
1889     D3DSTATE_TO_STR(WINED3DRS_PLANEMASK                 );
1890     D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE              );
1891     D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE           );
1892     D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL                 );
1893     D3DSTATE_TO_STR(WINED3DRS_SRCBLEND                  );
1894     D3DSTATE_TO_STR(WINED3DRS_DESTBLEND                 );
1895     D3DSTATE_TO_STR(WINED3DRS_CULLMODE                  );
1896     D3DSTATE_TO_STR(WINED3DRS_ZFUNC                     );
1897     D3DSTATE_TO_STR(WINED3DRS_ALPHAREF                  );
1898     D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC                 );
1899     D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE              );
1900     D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE          );
1901     D3DSTATE_TO_STR(WINED3DRS_FOGENABLE                 );
1902     D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE            );
1903     D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE                  );
1904     D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL                  );
1905     D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX                 );
1906     D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA             );
1907     D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR                  );
1908     D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE              );
1909     D3DSTATE_TO_STR(WINED3DRS_FOGSTART                  );
1910     D3DSTATE_TO_STR(WINED3DRS_FOGEND                    );
1911     D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY                );
1912     D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE             );
1913     D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS             );
1914     D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE            );
1915     D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS             );
1916     D3DSTATE_TO_STR(WINED3DRS_ZBIAS                     );
1917     D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE            );
1918     D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY                );
1919     D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH                );
1920     D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1921     D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE             );
1922     D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL               );
1923     D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL              );
1924     D3DSTATE_TO_STR(WINED3DRS_STENCILPASS               );
1925     D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC               );
1926     D3DSTATE_TO_STR(WINED3DRS_STENCILREF                );
1927     D3DSTATE_TO_STR(WINED3DRS_STENCILMASK               );
1928     D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK          );
1929     D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR             );
1930     D3DSTATE_TO_STR(WINED3DRS_WRAP0                     );
1931     D3DSTATE_TO_STR(WINED3DRS_WRAP1                     );
1932     D3DSTATE_TO_STR(WINED3DRS_WRAP2                     );
1933     D3DSTATE_TO_STR(WINED3DRS_WRAP3                     );
1934     D3DSTATE_TO_STR(WINED3DRS_WRAP4                     );
1935     D3DSTATE_TO_STR(WINED3DRS_WRAP5                     );
1936     D3DSTATE_TO_STR(WINED3DRS_WRAP6                     );
1937     D3DSTATE_TO_STR(WINED3DRS_WRAP7                     );
1938     D3DSTATE_TO_STR(WINED3DRS_CLIPPING                  );
1939     D3DSTATE_TO_STR(WINED3DRS_LIGHTING                  );
1940     D3DSTATE_TO_STR(WINED3DRS_EXTENTS                   );
1941     D3DSTATE_TO_STR(WINED3DRS_AMBIENT                   );
1942     D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE             );
1943     D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX               );
1944     D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER               );
1945     D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS          );
1946     D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE       );
1947     D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE     );
1948     D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE    );
1949     D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE     );
1950     D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE    );
1951     D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND               );
1952     D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE           );
1953     D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING  );
1954     D3DSTATE_TO_STR(WINED3DRS_POINTSIZE                 );
1955     D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN             );
1956     D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE         );
1957     D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE          );
1958     D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A              );
1959     D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B              );
1960     D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C              );
1961     D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS      );
1962     D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK           );
1963     D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE            );
1964     D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS             );
1965     D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN         );
1966     D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX             );
1967     D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE  );
1968     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE          );
1969     D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR               );
1970     D3DSTATE_TO_STR(WINED3DRS_BLENDOP                   );
1971     D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE            );
1972     D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE              );
1973     D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE         );
1974     D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS       );
1975     D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE     );
1976     D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL      );
1977     D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL      );
1978     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X            );
1979     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y            );
1980     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z            );
1981     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W            );
1982     D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1983     D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE       );
1984     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL           );
1985     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL          );
1986     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS           );
1987     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC           );
1988     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1         );
1989     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2         );
1990     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3         );
1991     D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR               );
1992     D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE           );
1993     D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS                 );
1994     D3DSTATE_TO_STR(WINED3DRS_WRAP8                     );
1995     D3DSTATE_TO_STR(WINED3DRS_WRAP9                     );
1996     D3DSTATE_TO_STR(WINED3DRS_WRAP10                    );
1997     D3DSTATE_TO_STR(WINED3DRS_WRAP11                    );
1998     D3DSTATE_TO_STR(WINED3DRS_WRAP12                    );
1999     D3DSTATE_TO_STR(WINED3DRS_WRAP13                    );
2000     D3DSTATE_TO_STR(WINED3DRS_WRAP14                    );
2001     D3DSTATE_TO_STR(WINED3DRS_WRAP15                    );
2002     D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE  );
2003     D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA             );
2004     D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA            );
2005     D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA              );
2006 #undef D3DSTATE_TO_STR
2007   default:
2008     FIXME("Unrecognized %u render state!\n", state);
2009     return "unrecognized";
2010   }
2011 }
2012
2013 const char* debug_d3dsamplerstate(DWORD state) {
2014   switch (state) {
2015 #define D3DSTATE_TO_STR(u) case u: return #u
2016     D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR  );
2017     D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU     );
2018     D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV     );
2019     D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW     );
2020     D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER    );
2021     D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER    );
2022     D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER    );
2023     D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
2024     D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL  );
2025     D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
2026     D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE  );
2027     D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
2028     D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET   );
2029 #undef D3DSTATE_TO_STR
2030   default:
2031     FIXME("Unrecognized %u sampler state!\n", state);
2032     return "unrecognized";
2033   }
2034 }
2035
2036 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2037     switch (filter_type) {
2038 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2039         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2040         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2041         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2042         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2043         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2044         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2045         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2046         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2047 #undef D3DTEXTUREFILTERTYPE_TO_STR
2048         default:
2049             FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2050             return "unrecognized";
2051     }
2052 }
2053
2054 const char* debug_d3dtexturestate(DWORD state) {
2055   switch (state) {
2056 #define D3DSTATE_TO_STR(u) case u: return #u
2057     D3DSTATE_TO_STR(WINED3DTSS_COLOROP               );
2058     D3DSTATE_TO_STR(WINED3DTSS_COLORARG1             );
2059     D3DSTATE_TO_STR(WINED3DTSS_COLORARG2             );
2060     D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP               );
2061     D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1             );
2062     D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2             );
2063     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00          );
2064     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01          );
2065     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10          );
2066     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11          );
2067     D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX         );
2068     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE         );
2069     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET        );
2070     D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
2071     D3DSTATE_TO_STR(WINED3DTSS_COLORARG0             );
2072     D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0             );
2073     D3DSTATE_TO_STR(WINED3DTSS_RESULTARG             );
2074     D3DSTATE_TO_STR(WINED3DTSS_CONSTANT              );
2075 #undef D3DSTATE_TO_STR
2076   default:
2077     FIXME("Unrecognized %u texture state!\n", state);
2078     return "unrecognized";
2079   }
2080 }
2081
2082 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2083     switch (d3dtop) {
2084 #define D3DTOP_TO_STR(u) case u: return #u
2085         D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2086         D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2087         D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2088         D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2089         D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2090         D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2091         D3DTOP_TO_STR(WINED3DTOP_ADD);
2092         D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2093         D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2094         D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2095         D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2096         D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2097         D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2098         D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2099         D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2100         D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2101         D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2102         D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2103         D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2104         D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2105         D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2106         D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2107         D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2108         D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2109         D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2110         D3DTOP_TO_STR(WINED3DTOP_LERP);
2111 #undef D3DTOP_TO_STR
2112         default:
2113             FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2114             return "unrecognized";
2115     }
2116 }
2117
2118 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2119     switch (tstype) {
2120 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2121     TSTYPE_TO_STR(WINED3DTS_VIEW);
2122     TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2123     TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2124     TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2125     TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2126     TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2127     TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2128     TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2129     TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2130     TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2131     TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2132 #undef TSTYPE_TO_STR
2133     default:
2134         if (tstype > 256 && tstype < 512) {
2135             FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2136             return ("WINED3DTS_WORLDMATRIX > 0");
2137         }
2138         FIXME("Unrecognized %u WINED3DTS\n", tstype);
2139         return "unrecognized";
2140     }
2141 }
2142
2143 const char *debug_d3dstate(DWORD state)
2144 {
2145     if (STATE_IS_RENDER(state))
2146         return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2147     if (STATE_IS_TEXTURESTAGE(state))
2148     {
2149         DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2150         DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2151         return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2152                 texture_stage, debug_d3dtexturestate(texture_state));
2153     }
2154     if (STATE_IS_SAMPLER(state))
2155         return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2156     if (STATE_IS_PIXELSHADER(state))
2157         return "STATE_PIXELSHADER";
2158     if (STATE_IS_TRANSFORM(state))
2159         return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2160     if (STATE_IS_STREAMSRC(state))
2161         return "STATE_STREAMSRC";
2162     if (STATE_IS_INDEXBUFFER(state))
2163         return "STATE_INDEXBUFFER";
2164     if (STATE_IS_VDECL(state))
2165         return "STATE_VDECL";
2166     if (STATE_IS_VSHADER(state))
2167         return "STATE_VSHADER";
2168     if (STATE_IS_VIEWPORT(state))
2169         return "STATE_VIEWPORT";
2170     if (STATE_IS_VERTEXSHADERCONSTANT(state))
2171         return "STATE_VERTEXSHADERCONSTANT";
2172     if (STATE_IS_PIXELSHADERCONSTANT(state))
2173         return "STATE_PIXELSHADERCONSTANT";
2174     if (STATE_IS_ACTIVELIGHT(state))
2175         return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2176     if (STATE_IS_SCISSORRECT(state))
2177         return "STATE_SCISSORRECT";
2178     if (STATE_IS_CLIPPLANE(state))
2179         return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2180     if (STATE_IS_MATERIAL(state))
2181         return "STATE_MATERIAL";
2182     if (STATE_IS_FRONTFACE(state))
2183         return "STATE_FRONTFACE";
2184
2185     return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2186 }
2187
2188 const char* debug_d3dpool(WINED3DPOOL Pool) {
2189   switch (Pool) {
2190 #define POOL_TO_STR(p) case p: return #p
2191     POOL_TO_STR(WINED3DPOOL_DEFAULT);
2192     POOL_TO_STR(WINED3DPOOL_MANAGED);
2193     POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2194     POOL_TO_STR(WINED3DPOOL_SCRATCH);
2195 #undef  POOL_TO_STR
2196   default:
2197     FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
2198     return "unrecognized";
2199   }
2200 }
2201
2202 const char *debug_fbostatus(GLenum status) {
2203     switch(status) {
2204 #define FBOSTATUS_TO_STR(u) case u: return #u
2205         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2206         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2207         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2208         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2209         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2210         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2211         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2212         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2213         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2214         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2215 #undef FBOSTATUS_TO_STR
2216         default:
2217             FIXME("Unrecognied FBO status 0x%08x\n", status);
2218             return "unrecognized";
2219     }
2220 }
2221
2222 const char *debug_glerror(GLenum error) {
2223     switch(error) {
2224 #define GLERROR_TO_STR(u) case u: return #u
2225         GLERROR_TO_STR(GL_NO_ERROR);
2226         GLERROR_TO_STR(GL_INVALID_ENUM);
2227         GLERROR_TO_STR(GL_INVALID_VALUE);
2228         GLERROR_TO_STR(GL_INVALID_OPERATION);
2229         GLERROR_TO_STR(GL_STACK_OVERFLOW);
2230         GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2231         GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2232         GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2233 #undef GLERROR_TO_STR
2234         default:
2235             FIXME("Unrecognied GL error 0x%08x\n", error);
2236             return "unrecognized";
2237     }
2238 }
2239
2240 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2241     switch(basis) {
2242         case WINED3DBASIS_BEZIER:       return "WINED3DBASIS_BEZIER";
2243         case WINED3DBASIS_BSPLINE:      return "WINED3DBASIS_BSPLINE";
2244         case WINED3DBASIS_INTERPOLATE:  return "WINED3DBASIS_INTERPOLATE";
2245         default:                        return "unrecognized";
2246     }
2247 }
2248
2249 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2250     switch(degree) {
2251         case WINED3DDEGREE_LINEAR:      return "WINED3DDEGREE_LINEAR";
2252         case WINED3DDEGREE_QUADRATIC:   return "WINED3DDEGREE_QUADRATIC";
2253         case WINED3DDEGREE_CUBIC:       return "WINED3DDEGREE_CUBIC";
2254         case WINED3DDEGREE_QUINTIC:     return "WINED3DDEGREE_QUINTIC";
2255         default:                        return "unrecognized";
2256     }
2257 }
2258
2259 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2260 {
2261     switch(source)
2262     {
2263 #define WINED3D_TO_STR(x) case x: return #x
2264         WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2265         WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2266         WINED3D_TO_STR(CHANNEL_SOURCE_X);
2267         WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2268         WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2269         WINED3D_TO_STR(CHANNEL_SOURCE_W);
2270         WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2271         WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2272 #undef WINED3D_TO_STR
2273         default:
2274             FIXME("Unrecognized fixup_channel_source %#x\n", source);
2275             return "unrecognized";
2276     }
2277 }
2278
2279 static const char *debug_complex_fixup(enum complex_fixup fixup)
2280 {
2281     switch(fixup)
2282     {
2283 #define WINED3D_TO_STR(x) case x: return #x
2284         WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2285         WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2286         WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2287         WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2288 #undef WINED3D_TO_STR
2289         default:
2290             FIXME("Unrecognized complex fixup %#x\n", fixup);
2291             return "unrecognized";
2292     }
2293 }
2294
2295 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2296 {
2297     if (is_complex_fixup(fixup))
2298     {
2299         TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2300         return;
2301     }
2302
2303     TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2304     TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2305     TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2306     TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2307 }
2308
2309 const char *debug_surflocation(DWORD flag) {
2310     char buf[128];
2311
2312     buf[0] = 0;
2313     if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2314     if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2315     if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2316     if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2317     return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2318 }
2319
2320 /*****************************************************************************
2321  * Useful functions mapping GL <-> D3D values
2322  */
2323 GLenum StencilOp(DWORD op) {
2324     switch(op) {
2325     case WINED3DSTENCILOP_KEEP    : return GL_KEEP;
2326     case WINED3DSTENCILOP_ZERO    : return GL_ZERO;
2327     case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2328     case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2329     case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2330     case WINED3DSTENCILOP_INVERT  : return GL_INVERT;
2331     case WINED3DSTENCILOP_INCR    : return GL_INCR_WRAP_EXT;
2332     case WINED3DSTENCILOP_DECR    : return GL_DECR_WRAP_EXT;
2333     default:
2334         FIXME("Unrecognized stencil op %d\n", op);
2335         return GL_KEEP;
2336     }
2337 }
2338
2339 GLenum CompareFunc(DWORD func) {
2340     switch ((WINED3DCMPFUNC)func) {
2341     case WINED3DCMP_NEVER        : return GL_NEVER;
2342     case WINED3DCMP_LESS         : return GL_LESS;
2343     case WINED3DCMP_EQUAL        : return GL_EQUAL;
2344     case WINED3DCMP_LESSEQUAL    : return GL_LEQUAL;
2345     case WINED3DCMP_GREATER      : return GL_GREATER;
2346     case WINED3DCMP_NOTEQUAL     : return GL_NOTEQUAL;
2347     case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2348     case WINED3DCMP_ALWAYS       : return GL_ALWAYS;
2349     default:
2350         FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2351         return 0;
2352     }
2353 }
2354
2355 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
2356     if (op == WINED3DTOP_DISABLE) return FALSE;
2357     if (This->stateBlock->textures[stage]) return FALSE;
2358
2359     if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2360             && op != WINED3DTOP_SELECTARG2) return TRUE;
2361     if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2362             && op != WINED3DTOP_SELECTARG1) return TRUE;
2363     if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2364             && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2365
2366     return FALSE;
2367 }
2368
2369 /* Setup this textures matrix according to the texture flags*/
2370 /* GL locking is done by the caller (state handler) */
2371 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2372         enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2373 {
2374     float mat[16];
2375
2376     glMatrixMode(GL_TEXTURE);
2377     checkGLcall("glMatrixMode(GL_TEXTURE)");
2378
2379     if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2380         glLoadIdentity();
2381         checkGLcall("glLoadIdentity()");
2382         return;
2383     }
2384
2385     if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2386         ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2387         return;
2388     }
2389
2390     memcpy(mat, smat, 16 * sizeof(float));
2391
2392     if (flags & WINED3DTTFF_PROJECTED) {
2393         if(!ffp_proj_control) {
2394             switch (flags & ~WINED3DTTFF_PROJECTED) {
2395             case WINED3DTTFF_COUNT2:
2396                 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2397                 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2398                 break;
2399             case WINED3DTTFF_COUNT3:
2400                 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2401                 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2402                 break;
2403             }
2404         }
2405     } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2406         if(!calculatedCoords) {
2407             switch(vtx_fmt)
2408             {
2409                 case WINED3DFMT_R32_FLOAT:
2410                     /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2411                      * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2412                      * the input value to the transformation will be 0, so the matrix value is irrelevant
2413                      */
2414                     mat[12] = mat[4];
2415                     mat[13] = mat[5];
2416                     mat[14] = mat[6];
2417                     mat[15] = mat[7];
2418                     break;
2419                 case WINED3DFMT_R32G32_FLOAT:
2420                     /* See above, just 3rd and 4th coord
2421                     */
2422                     mat[12] = mat[8];
2423                     mat[13] = mat[9];
2424                     mat[14] = mat[10];
2425                     mat[15] = mat[11];
2426                     break;
2427                 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2428                 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2429
2430                 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2431                  * into a bad place. The division elimination below will apply to make sure the
2432                  * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2433                  */
2434                 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2435                     break;
2436                 default:
2437                     FIXME("Unexpected fixed function texture coord input\n");
2438             }
2439         }
2440         if(!ffp_proj_control) {
2441             switch (flags & ~WINED3DTTFF_PROJECTED) {
2442                 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2443                 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2444                 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2445                 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2446                 * the 4th coord evaluates to 1.0 to eliminate that.
2447                 *
2448                 * If the fixed function pipeline is used, the 4th value remains unused,
2449                 * so there is no danger in doing this. With vertex shaders we have a
2450                 * problem. Should an app hit that problem, the code here would have to
2451                 * check for pixel shaders, and the shader has to undo the default gl divide.
2452                 *
2453                 * A more serious problem occurs if the app passes 4 coordinates in, and the
2454                 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2455                 * or a replacement shader
2456                 */
2457                 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2458             }
2459         }
2460     }
2461
2462     glLoadMatrixf(mat);
2463     checkGLcall("glLoadMatrixf(mat)");
2464 }
2465
2466 /* This small helper function is used to convert a bitmask into the number of masked bits */
2467 unsigned int count_bits(unsigned int mask)
2468 {
2469     unsigned int count;
2470     for (count = 0; mask; ++count)
2471     {
2472         mask &= mask - 1;
2473     }
2474     return count;
2475 }
2476
2477 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2478  * The later function requires individual color components. */
2479 BOOL getColorBits(const struct wined3d_format_desc *format_desc,
2480         short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2481 {
2482     TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2483     switch(format_desc->format)
2484     {
2485         case WINED3DFMT_B8G8R8X8_UNORM:
2486         case WINED3DFMT_B8G8R8_UNORM:
2487         case WINED3DFMT_B8G8R8A8_UNORM:
2488         case WINED3DFMT_R8G8B8A8_UNORM:
2489         case WINED3DFMT_B10G10R10A2_UNORM:
2490         case WINED3DFMT_B5G5R5X1_UNORM:
2491         case WINED3DFMT_B5G5R5A1_UNORM:
2492         case WINED3DFMT_B5G6R5_UNORM:
2493         case WINED3DFMT_B4G4R4X4_UNORM:
2494         case WINED3DFMT_B4G4R4A4_UNORM:
2495         case WINED3DFMT_B2G3R3_UNORM:
2496         case WINED3DFMT_P8_UINT_A8_UNORM:
2497         case WINED3DFMT_P8_UINT:
2498             break;
2499         default:
2500             ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
2501             return FALSE;
2502     }
2503
2504     *redSize = count_bits(format_desc->red_mask);
2505     *greenSize = count_bits(format_desc->green_mask);
2506     *blueSize = count_bits(format_desc->blue_mask);
2507     *alphaSize = count_bits(format_desc->alpha_mask);
2508     *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2509
2510     TRACE("Returning red:  %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
2511             *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
2512     return TRUE;
2513 }
2514
2515 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2516 BOOL getDepthStencilBits(const struct wined3d_format_desc *format_desc, short *depthSize, short *stencilSize)
2517 {
2518     TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2519     switch(format_desc->format)
2520     {
2521         case WINED3DFMT_D16_LOCKABLE:
2522         case WINED3DFMT_D16_UNORM:
2523         case WINED3DFMT_S1_UINT_D15_UNORM:
2524         case WINED3DFMT_X8D24_UNORM:
2525         case WINED3DFMT_S4X4_UINT_D24_UNORM:
2526         case WINED3DFMT_D24_UNORM_S8_UINT:
2527         case WINED3DFMT_S8_UINT_D24_FLOAT:
2528         case WINED3DFMT_D32_UNORM:
2529         case WINED3DFMT_D32_FLOAT:
2530             break;
2531         default:
2532             FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
2533             return FALSE;
2534     }
2535
2536     *depthSize = format_desc->depth_size;
2537     *stencilSize = format_desc->stencil_size;
2538
2539     TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
2540             *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
2541     return TRUE;
2542 }
2543
2544 DWORD wined3d_format_convert_from_float(const struct wined3d_format_desc *format, const WINED3DCOLORVALUE *color)
2545 {
2546     enum wined3d_format_id destfmt = format->format;
2547     unsigned int r, g, b, a;
2548     DWORD ret;
2549
2550     TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2551             color->r, color->g, color->b, color->a, debug_d3dformat(destfmt));
2552
2553     r = (DWORD)((color->r * 255.0f) + 0.5f);
2554     g = (DWORD)((color->g * 255.0f) + 0.5f);
2555     b = (DWORD)((color->b * 255.0f) + 0.5f);
2556     a = (DWORD)((color->a * 255.0f) + 0.5f);
2557
2558     switch(destfmt)
2559     {
2560         case WINED3DFMT_B8G8R8A8_UNORM:
2561         case WINED3DFMT_B8G8R8X8_UNORM:
2562         case WINED3DFMT_B8G8R8_UNORM:
2563             ret = b;
2564             ret |= g << 8;
2565             ret |= r << 16;
2566             ret |= a << 24;
2567             TRACE("Returning 0x%08x.\n", ret);
2568             return ret;
2569
2570
2571         case WINED3DFMT_B5G6R5_UNORM:
2572             if(r == 0xff && g == 0xff && b == 0xff) return 0xffff;
2573             r = (r * 32) / 256;
2574             g = (g * 64) / 256;
2575             b = (b * 32) / 256;
2576             ret  = r << 11;
2577             ret |= g << 5;
2578             ret |= b;
2579             TRACE("Returning %08x\n", ret);
2580             return ret;
2581
2582         case WINED3DFMT_B5G5R5X1_UNORM:
2583         case WINED3DFMT_B5G5R5A1_UNORM:
2584             a = (a *  2) / 256;
2585             r = (r * 32) / 256;
2586             g = (g * 32) / 256;
2587             b = (b * 32) / 256;
2588             ret  = a << 15;
2589             ret |= r << 10;
2590             ret |= g <<  5;
2591             ret |= b <<  0;
2592             TRACE("Returning %08x\n", ret);
2593             return ret;
2594
2595         case WINED3DFMT_A8_UNORM:
2596             TRACE("Returning %08x\n", a);
2597             return a;
2598
2599         case WINED3DFMT_B4G4R4X4_UNORM:
2600         case WINED3DFMT_B4G4R4A4_UNORM:
2601             a = (a * 16) / 256;
2602             r = (r * 16) / 256;
2603             g = (g * 16) / 256;
2604             b = (b * 16) / 256;
2605             ret  = a << 12;
2606             ret |= r <<  8;
2607             ret |= g <<  4;
2608             ret |= b <<  0;
2609             TRACE("Returning %08x\n", ret);
2610             return ret;
2611
2612         case WINED3DFMT_B2G3R3_UNORM:
2613             r = (r * 8) / 256;
2614             g = (g * 8) / 256;
2615             b = (b * 4) / 256;
2616             ret  = r <<  5;
2617             ret |= g <<  2;
2618             ret |= b <<  0;
2619             TRACE("Returning %08x\n", ret);
2620             return ret;
2621
2622         case WINED3DFMT_R8G8B8X8_UNORM:
2623         case WINED3DFMT_R8G8B8A8_UNORM:
2624             ret  = a << 24;
2625             ret |= b << 16;
2626             ret |= g <<  8;
2627             ret |= r <<  0;
2628             TRACE("Returning %08x\n", ret);
2629             return ret;
2630
2631         case WINED3DFMT_B10G10R10A2_UNORM:
2632             a = (a *    4) / 256;
2633             r = (r * 1024) / 256;
2634             g = (g * 1024) / 256;
2635             b = (b * 1024) / 256;
2636             ret  = a << 30;
2637             ret |= r << 20;
2638             ret |= g << 10;
2639             ret |= b <<  0;
2640             TRACE("Returning %08x\n", ret);
2641             return ret;
2642
2643         case WINED3DFMT_R10G10B10A2_UNORM:
2644             a = (a *    4) / 256;
2645             r = (r * 1024) / 256;
2646             g = (g * 1024) / 256;
2647             b = (b * 1024) / 256;
2648             ret  = a << 30;
2649             ret |= b << 20;
2650             ret |= g << 10;
2651             ret |= r <<  0;
2652             TRACE("Returning %08x\n", ret);
2653             return ret;
2654
2655         default:
2656             FIXME("Add a COLORFILL conversion for format %s\n", debug_d3dformat(destfmt));
2657             return 0;
2658     }
2659 }
2660
2661 /* DirectDraw stuff */
2662 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2663 {
2664     switch (depth)
2665     {
2666         case 8:  return WINED3DFMT_P8_UINT;
2667         case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2668         case 16: return WINED3DFMT_B5G6R5_UNORM;
2669         case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2670         case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2671         default: return WINED3DFMT_UNKNOWN;
2672     }
2673 }
2674
2675 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2676     WINED3DMATRIX temp;
2677
2678     /* Now do the multiplication 'by hand'.
2679        I know that all this could be optimised, but this will be done later :-) */
2680     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);
2681     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);
2682     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);
2683     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);
2684
2685     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);
2686     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);
2687     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);
2688     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);
2689
2690     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);
2691     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);
2692     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);
2693     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);
2694
2695     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);
2696     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);
2697     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);
2698     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);
2699
2700     /* And copy the new matrix in the good storage.. */
2701     memcpy(dest, &temp, 16 * sizeof(float));
2702 }
2703
2704 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2705     DWORD size = 0;
2706     int i;
2707     int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2708
2709     if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2710     if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2711     if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2712     if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2713     switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2714         case WINED3DFVF_XYZ:    size += 3 * sizeof(float); break;
2715         case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2716         case WINED3DFVF_XYZB1:  size += 4 * sizeof(float); break;
2717         case WINED3DFVF_XYZB2:  size += 5 * sizeof(float); break;
2718         case WINED3DFVF_XYZB3:  size += 6 * sizeof(float); break;
2719         case WINED3DFVF_XYZB4:  size += 7 * sizeof(float); break;
2720         case WINED3DFVF_XYZB5:  size += 8 * sizeof(float); break;
2721         case WINED3DFVF_XYZW:   size += 4 * sizeof(float); break;
2722         default: ERR("Unexpected position mask\n");
2723     }
2724     for (i = 0; i < numTextures; i++) {
2725         size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2726     }
2727
2728     return size;
2729 }
2730
2731 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2732 #define ARG1 0x01
2733 #define ARG2 0x02
2734 #define ARG0 0x04
2735     static const unsigned char args[WINED3DTOP_LERP + 1] = {
2736         /* undefined                        */  0,
2737         /* D3DTOP_DISABLE                   */  0,
2738         /* D3DTOP_SELECTARG1                */  ARG1,
2739         /* D3DTOP_SELECTARG2                */  ARG2,
2740         /* D3DTOP_MODULATE                  */  ARG1 | ARG2,
2741         /* D3DTOP_MODULATE2X                */  ARG1 | ARG2,
2742         /* D3DTOP_MODULATE4X                */  ARG1 | ARG2,
2743         /* D3DTOP_ADD                       */  ARG1 | ARG2,
2744         /* D3DTOP_ADDSIGNED                 */  ARG1 | ARG2,
2745         /* D3DTOP_ADDSIGNED2X               */  ARG1 | ARG2,
2746         /* D3DTOP_SUBTRACT                  */  ARG1 | ARG2,
2747         /* D3DTOP_ADDSMOOTH                 */  ARG1 | ARG2,
2748         /* D3DTOP_BLENDDIFFUSEALPHA         */  ARG1 | ARG2,
2749         /* D3DTOP_BLENDTEXTUREALPHA         */  ARG1 | ARG2,
2750         /* D3DTOP_BLENDFACTORALPHA          */  ARG1 | ARG2,
2751         /* D3DTOP_BLENDTEXTUREALPHAPM       */  ARG1 | ARG2,
2752         /* D3DTOP_BLENDCURRENTALPHA         */  ARG1 | ARG2,
2753         /* D3DTOP_PREMODULATE               */  ARG1 | ARG2,
2754         /* D3DTOP_MODULATEALPHA_ADDCOLOR    */  ARG1 | ARG2,
2755         /* D3DTOP_MODULATECOLOR_ADDALPHA    */  ARG1 | ARG2,
2756         /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */  ARG1 | ARG2,
2757         /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */  ARG1 | ARG2,
2758         /* D3DTOP_BUMPENVMAP                */  ARG1 | ARG2,
2759         /* D3DTOP_BUMPENVMAPLUMINANCE       */  ARG1 | ARG2,
2760         /* D3DTOP_DOTPRODUCT3               */  ARG1 | ARG2,
2761         /* D3DTOP_MULTIPLYADD               */  ARG1 | ARG2 | ARG0,
2762         /* D3DTOP_LERP                      */  ARG1 | ARG2 | ARG0
2763     };
2764     unsigned int i;
2765     DWORD ttff;
2766     DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2767     IWineD3DDeviceImpl *device = stateblock->device;
2768     IWineD3DSurfaceImpl *rt = device->render_targets[0];
2769     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2770
2771     for (i = 0; i < gl_info->limits.texture_stages; ++i)
2772     {
2773         IWineD3DBaseTextureImpl *texture;
2774         settings->op[i].padding = 0;
2775         if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2776             settings->op[i].cop = WINED3DTOP_DISABLE;
2777             settings->op[i].aop = WINED3DTOP_DISABLE;
2778             settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2779             settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2780             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2781             settings->op[i].dst = resultreg;
2782             settings->op[i].tex_type = tex_1d;
2783             settings->op[i].projected = proj_none;
2784             i++;
2785             break;
2786         }
2787
2788         texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2789         if(texture) {
2790             settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2791             if(ignore_textype) {
2792                 settings->op[i].tex_type = tex_1d;
2793             } else {
2794                 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2795                     case GL_TEXTURE_1D:
2796                         settings->op[i].tex_type = tex_1d;
2797                         break;
2798                     case GL_TEXTURE_2D:
2799                         settings->op[i].tex_type = tex_2d;
2800                         break;
2801                     case GL_TEXTURE_3D:
2802                         settings->op[i].tex_type = tex_3d;
2803                         break;
2804                     case GL_TEXTURE_CUBE_MAP_ARB:
2805                         settings->op[i].tex_type = tex_cube;
2806                         break;
2807                     case GL_TEXTURE_RECTANGLE_ARB:
2808                         settings->op[i].tex_type = tex_rect;
2809                         break;
2810                 }
2811             }
2812         } else {
2813             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2814             settings->op[i].tex_type = tex_1d;
2815         }
2816
2817         cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2818         aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2819
2820         carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2821         carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2822         carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2823
2824         if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2825             carg0 = ARG_UNUSED;
2826             carg2 = ARG_UNUSED;
2827             carg1 = WINED3DTA_CURRENT;
2828             cop = WINED3DTOP_SELECTARG1;
2829         }
2830
2831         if(cop == WINED3DTOP_DOTPRODUCT3) {
2832             /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2833              * the color result to the alpha component of the destination
2834              */
2835             aop = cop;
2836             aarg1 = carg1;
2837             aarg2 = carg2;
2838             aarg0 = carg0;
2839         } else {
2840             aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2841             aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2842             aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2843         }
2844
2845         if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2846         {
2847             UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2848
2849             if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2850             {
2851                 IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)stateblock->textures[0];
2852                 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
2853
2854                 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2855                 {
2856                     if (aop == WINED3DTOP_DISABLE)
2857                     {
2858                        aarg1 = WINED3DTA_TEXTURE;
2859                        aop = WINED3DTOP_SELECTARG1;
2860                     }
2861                     else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2862                     {
2863                         if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2864                         {
2865                             aarg2 = WINED3DTA_TEXTURE;
2866                             aop = WINED3DTOP_MODULATE;
2867                         }
2868                         else aarg1 = WINED3DTA_TEXTURE;
2869                     }
2870                     else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2871                     {
2872                         if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2873                         {
2874                             aarg1 = WINED3DTA_TEXTURE;
2875                             aop = WINED3DTOP_MODULATE;
2876                         }
2877                         else aarg2 = WINED3DTA_TEXTURE;
2878                     }
2879                 }
2880             }
2881         }
2882
2883         if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2884                aarg0 = ARG_UNUSED;
2885                aarg2 = ARG_UNUSED;
2886                aarg1 = WINED3DTA_CURRENT;
2887                aop = WINED3DTOP_SELECTARG1;
2888         }
2889
2890         if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2891            aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2892             ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2893             if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2894                 settings->op[i].projected = proj_count3;
2895             } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2896                 settings->op[i].projected = proj_count4;
2897             } else {
2898                 settings->op[i].projected = proj_none;
2899             }
2900         } else {
2901             settings->op[i].projected = proj_none;
2902         }
2903
2904         settings->op[i].cop = cop;
2905         settings->op[i].aop = aop;
2906         settings->op[i].carg0 = carg0;
2907         settings->op[i].carg1 = carg1;
2908         settings->op[i].carg2 = carg2;
2909         settings->op[i].aarg0 = aarg0;
2910         settings->op[i].aarg1 = aarg1;
2911         settings->op[i].aarg2 = aarg2;
2912
2913         if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2914             settings->op[i].dst = tempreg;
2915         } else {
2916             settings->op[i].dst = resultreg;
2917         }
2918     }
2919
2920     /* Clear unsupported stages */
2921     for(; i < MAX_TEXTURES; i++) {
2922         memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2923     }
2924
2925     if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2926         settings->fog = FOG_OFF;
2927     } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2928         if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2929             settings->fog = FOG_LINEAR;
2930         } else {
2931             switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2932                 case WINED3DFOG_NONE:
2933                 case WINED3DFOG_LINEAR:
2934                     settings->fog = FOG_LINEAR;
2935                     break;
2936                 case WINED3DFOG_EXP:
2937                     settings->fog = FOG_EXP;
2938                     break;
2939                 case WINED3DFOG_EXP2:
2940                     settings->fog = FOG_EXP2;
2941                     break;
2942             }
2943         }
2944     } else {
2945         switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2946             case WINED3DFOG_LINEAR:
2947                 settings->fog = FOG_LINEAR;
2948                 break;
2949             case WINED3DFOG_EXP:
2950                 settings->fog = FOG_EXP;
2951                 break;
2952             case WINED3DFOG_EXP2:
2953                 settings->fog = FOG_EXP2;
2954                 break;
2955         }
2956     }
2957     if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE] &&
2958        rt->resource.format_desc->Flags & WINED3DFMT_FLAG_SRGB_WRITE) {
2959         settings->sRGB_write = 1;
2960     } else {
2961         settings->sRGB_write = 0;
2962     }
2963     if(device->vs_clipping || !use_vs(stateblock) || !stateblock->renderState[WINED3DRS_CLIPPING] ||
2964        !stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
2965         /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2966          * the fixed function vertex pipeline is used(which always supports clipplanes), or
2967          * if no clipplane is enabled
2968          */
2969         settings->emul_clipplanes = 0;
2970     } else {
2971         settings->emul_clipplanes = 1;
2972     }
2973 }
2974
2975 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2976         const struct ffp_frag_settings *settings)
2977 {
2978     struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2979     return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2980 }
2981
2982 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2983 {
2984     /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2985      * whereas desc points to an extended structure with implementation specific parts. */
2986     if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2987     {
2988         ERR("Failed to insert ffp frag shader.\n");
2989     }
2990 }
2991
2992 /* Activates the texture dimension according to the bound D3D texture.
2993  * Does not care for the colorop or correct gl texture unit(when using nvrc)
2994  * Requires the caller to activate the correct unit before
2995  */
2996 /* GL locking is done by the caller (state handler) */
2997 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2998 {
2999     const struct wined3d_gl_info *gl_info = context->gl_info;
3000
3001     if (stateblock->textures[stage])
3002     {
3003         switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
3004             case GL_TEXTURE_2D:
3005                 glDisable(GL_TEXTURE_3D);
3006                 checkGLcall("glDisable(GL_TEXTURE_3D)");
3007                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3008                 {
3009                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3010                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3011                 }
3012                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3013                 {
3014                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
3015                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3016                 }
3017                 glEnable(GL_TEXTURE_2D);
3018                 checkGLcall("glEnable(GL_TEXTURE_2D)");
3019                 break;
3020             case GL_TEXTURE_RECTANGLE_ARB:
3021                 glDisable(GL_TEXTURE_2D);
3022                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3023                 glDisable(GL_TEXTURE_3D);
3024                 checkGLcall("glDisable(GL_TEXTURE_3D)");
3025                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3026                 {
3027                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3028                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3029                 }
3030                 glEnable(GL_TEXTURE_RECTANGLE_ARB);
3031                 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3032                 break;
3033             case GL_TEXTURE_3D:
3034                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3035                 {
3036                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3037                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3038                 }
3039                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3040                 {
3041                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
3042                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3043                 }
3044                 glDisable(GL_TEXTURE_2D);
3045                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3046                 glEnable(GL_TEXTURE_3D);
3047                 checkGLcall("glEnable(GL_TEXTURE_3D)");
3048                 break;
3049             case GL_TEXTURE_CUBE_MAP_ARB:
3050                 glDisable(GL_TEXTURE_2D);
3051                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3052                 glDisable(GL_TEXTURE_3D);
3053                 checkGLcall("glDisable(GL_TEXTURE_3D)");
3054                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3055                 {
3056                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
3057                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3058                 }
3059                 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3060                 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3061               break;
3062         }
3063     } else {
3064         glEnable(GL_TEXTURE_2D);
3065         checkGLcall("glEnable(GL_TEXTURE_2D)");
3066         glDisable(GL_TEXTURE_3D);
3067         checkGLcall("glDisable(GL_TEXTURE_3D)");
3068         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3069         {
3070             glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3071             checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3072         }
3073         if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3074         {
3075             glDisable(GL_TEXTURE_RECTANGLE_ARB);
3076             checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3077         }
3078         /* Binding textures is done by samplers. A dummy texture will be bound */
3079     }
3080 }
3081
3082 /* GL locking is done by the caller (state handler) */
3083 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3084 {
3085     DWORD sampler = state - STATE_SAMPLER(0);
3086     DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3087
3088     /* No need to enable / disable anything here for unused samplers. The tex_colorop
3089     * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3090     * will take care of this business
3091     */
3092     if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3093     if(sampler >= stateblock->lowest_disabled_stage) return;
3094     if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3095
3096     texture_activate_dimensions(sampler, stateblock, context);
3097 }
3098
3099 void *wined3d_rb_alloc(size_t size)
3100 {
3101     return HeapAlloc(GetProcessHeap(), 0, size);
3102 }
3103
3104 void *wined3d_rb_realloc(void *ptr, size_t size)
3105 {
3106     return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3107 }
3108
3109 void wined3d_rb_free(void *ptr)
3110 {
3111     HeapFree(GetProcessHeap(), 0, ptr);
3112 }
3113
3114 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3115 {
3116     const struct ffp_frag_settings *ka = key;
3117     const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3118
3119     return memcmp(ka, kb, sizeof(*ka));
3120 }
3121
3122 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3123 {
3124     wined3d_rb_alloc,
3125     wined3d_rb_realloc,
3126     wined3d_rb_free,
3127     ffp_frag_program_key_compare,
3128 };
3129
3130 UINT wined3d_log2i(UINT32 x)
3131 {
3132     static const UINT l[] =
3133     {
3134         ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3135           4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3136           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3137           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3138           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3139           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3140           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3141           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3142           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3143           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3144           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3145           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3146           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3147           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3148           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3149           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3150     };
3151     UINT32 i;
3152
3153     return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3154 }
3155
3156 /* Set the shader type for this device, depending on the given capabilities
3157  * and the user preferences in wined3d_settings. */
3158 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3159 {
3160     BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3161
3162     if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3163     else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3164     {
3165         /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3166          * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3167          * shaders only on this card. */
3168         if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3169         else *vs_selected = SHADER_GLSL;
3170     }
3171     else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3172     else *vs_selected = SHADER_NONE;
3173
3174     if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3175     else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3176     else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3177     else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3178     else *ps_selected = SHADER_NONE;
3179 }