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