wined3d: Recognize the SM4 frc opcode.
[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(const struct wined3d_state *state, int stage,
2370         WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
2371 {
2372     if (op == WINED3DTOP_DISABLE) return FALSE;
2373     if (state->textures[stage]) return FALSE;
2374
2375     if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2376             && op != WINED3DTOP_SELECTARG2) return TRUE;
2377     if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2378             && op != WINED3DTOP_SELECTARG1) return TRUE;
2379     if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2380             && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2381
2382     return FALSE;
2383 }
2384
2385 /* Setup this textures matrix according to the texture flags*/
2386 /* GL locking is done by the caller (state handler) */
2387 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2388         enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2389 {
2390     float mat[16];
2391
2392     glMatrixMode(GL_TEXTURE);
2393     checkGLcall("glMatrixMode(GL_TEXTURE)");
2394
2395     if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2396         glLoadIdentity();
2397         checkGLcall("glLoadIdentity()");
2398         return;
2399     }
2400
2401     if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2402         ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2403         return;
2404     }
2405
2406     memcpy(mat, smat, 16 * sizeof(float));
2407
2408     if (flags & WINED3DTTFF_PROJECTED) {
2409         if(!ffp_proj_control) {
2410             switch (flags & ~WINED3DTTFF_PROJECTED) {
2411             case WINED3DTTFF_COUNT2:
2412                 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2413                 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2414                 break;
2415             case WINED3DTTFF_COUNT3:
2416                 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2417                 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2418                 break;
2419             }
2420         }
2421     } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2422         if(!calculatedCoords) {
2423             switch(vtx_fmt)
2424             {
2425                 case WINED3DFMT_R32_FLOAT:
2426                     /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2427                      * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2428                      * the input value to the transformation will be 0, so the matrix value is irrelevant
2429                      */
2430                     mat[12] = mat[4];
2431                     mat[13] = mat[5];
2432                     mat[14] = mat[6];
2433                     mat[15] = mat[7];
2434                     break;
2435                 case WINED3DFMT_R32G32_FLOAT:
2436                     /* See above, just 3rd and 4th coord
2437                     */
2438                     mat[12] = mat[8];
2439                     mat[13] = mat[9];
2440                     mat[14] = mat[10];
2441                     mat[15] = mat[11];
2442                     break;
2443                 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2444                 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2445
2446                 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2447                  * into a bad place. The division elimination below will apply to make sure the
2448                  * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2449                  */
2450                 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2451                     break;
2452                 default:
2453                     FIXME("Unexpected fixed function texture coord input\n");
2454             }
2455         }
2456         if(!ffp_proj_control) {
2457             switch (flags & ~WINED3DTTFF_PROJECTED) {
2458                 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2459                 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2460                 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2461                 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2462                 * the 4th coord evaluates to 1.0 to eliminate that.
2463                 *
2464                 * If the fixed function pipeline is used, the 4th value remains unused,
2465                 * so there is no danger in doing this. With vertex shaders we have a
2466                 * problem. Should an app hit that problem, the code here would have to
2467                 * check for pixel shaders, and the shader has to undo the default gl divide.
2468                 *
2469                 * A more serious problem occurs if the app passes 4 coordinates in, and the
2470                 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2471                 * or a replacement shader
2472                 */
2473                 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2474             }
2475         }
2476     }
2477
2478     glLoadMatrixf(mat);
2479     checkGLcall("glLoadMatrixf(mat)");
2480 }
2481
2482 /* This small helper function is used to convert a bitmask into the number of masked bits */
2483 unsigned int count_bits(unsigned int mask)
2484 {
2485     unsigned int count;
2486     for (count = 0; mask; ++count)
2487     {
2488         mask &= mask - 1;
2489     }
2490     return count;
2491 }
2492
2493 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2494  * The later function requires individual color components. */
2495 BOOL getColorBits(const struct wined3d_format *format,
2496         short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2497 {
2498     TRACE("format %s.\n", debug_d3dformat(format->id));
2499
2500     switch (format->id)
2501     {
2502         case WINED3DFMT_B8G8R8X8_UNORM:
2503         case WINED3DFMT_B8G8R8_UNORM:
2504         case WINED3DFMT_B8G8R8A8_UNORM:
2505         case WINED3DFMT_R8G8B8A8_UNORM:
2506         case WINED3DFMT_B10G10R10A2_UNORM:
2507         case WINED3DFMT_B5G5R5X1_UNORM:
2508         case WINED3DFMT_B5G5R5A1_UNORM:
2509         case WINED3DFMT_B5G6R5_UNORM:
2510         case WINED3DFMT_B4G4R4X4_UNORM:
2511         case WINED3DFMT_B4G4R4A4_UNORM:
2512         case WINED3DFMT_B2G3R3_UNORM:
2513         case WINED3DFMT_P8_UINT_A8_UNORM:
2514         case WINED3DFMT_P8_UINT:
2515             break;
2516         default:
2517             FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2518             return FALSE;
2519     }
2520
2521     *redSize = count_bits(format->red_mask);
2522     *greenSize = count_bits(format->green_mask);
2523     *blueSize = count_bits(format->blue_mask);
2524     *alphaSize = count_bits(format->alpha_mask);
2525     *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2526
2527     TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2528             *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2529     return TRUE;
2530 }
2531
2532 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2533 BOOL getDepthStencilBits(const struct wined3d_format *format, short *depthSize, short *stencilSize)
2534 {
2535     TRACE("format %s.\n", debug_d3dformat(format->id));
2536
2537     switch (format->id)
2538     {
2539         case WINED3DFMT_D16_LOCKABLE:
2540         case WINED3DFMT_D16_UNORM:
2541         case WINED3DFMT_S1_UINT_D15_UNORM:
2542         case WINED3DFMT_X8D24_UNORM:
2543         case WINED3DFMT_S4X4_UINT_D24_UNORM:
2544         case WINED3DFMT_D24_UNORM_S8_UINT:
2545         case WINED3DFMT_S8_UINT_D24_FLOAT:
2546         case WINED3DFMT_D32_UNORM:
2547         case WINED3DFMT_D32_FLOAT:
2548             break;
2549         default:
2550             FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2551             return FALSE;
2552     }
2553
2554     *depthSize = format->depth_size;
2555     *stencilSize = format->stencil_size;
2556
2557     TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2558             *depthSize, *stencilSize, debug_d3dformat(format->id));
2559     return TRUE;
2560 }
2561
2562 /* Note: It's the caller's responsibility to ensure values can be expressed
2563  * in the requested format. UNORM formats for example can only express values
2564  * in the range 0.0f -> 1.0f. */
2565 DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, const WINED3DCOLORVALUE *color)
2566 {
2567     static const struct
2568     {
2569         enum wined3d_format_id format_id;
2570         float r_mul;
2571         float g_mul;
2572         float b_mul;
2573         float a_mul;
2574         BYTE r_shift;
2575         BYTE g_shift;
2576         BYTE b_shift;
2577         BYTE a_shift;
2578     }
2579     conv[] =
2580     {
2581         {WINED3DFMT_B8G8R8A8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
2582         {WINED3DFMT_B8G8R8X8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
2583         {WINED3DFMT_B8G8R8_UNORM,       255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
2584         {WINED3DFMT_B5G6R5_UNORM,        31.0f,   63.0f,   31.0f,    0.0f, 11,  5,  0,  0},
2585         {WINED3DFMT_B5G5R5A1_UNORM,      31.0f,   31.0f,   31.0f,    1.0f, 10,  5,  0, 15},
2586         {WINED3DFMT_B5G5R5X1_UNORM,      31.0f,   31.0f,   31.0f,    1.0f, 10,  5,  0, 15},
2587         {WINED3DFMT_A8_UNORM,             0.0f,    0.0f,    0.0f,  255.0f,  0,  0,  0,  0},
2588         {WINED3DFMT_B4G4R4A4_UNORM,      15.0f,   15.0f,   15.0f,   15.0f,  8,  4,  0, 12},
2589         {WINED3DFMT_B4G4R4X4_UNORM,      15.0f,   15.0f,   15.0f,   15.0f,  8,  4,  0, 12},
2590         {WINED3DFMT_B2G3R3_UNORM,         7.0f,    7.0f,    3.0f,    0.0f,  5,  2,  0,  0},
2591         {WINED3DFMT_R8G8B8A8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f,  0,  8, 16, 24},
2592         {WINED3DFMT_R8G8B8X8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f,  0,  8, 16, 24},
2593         {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f,    3.0f, 20, 10,  0, 30},
2594         {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f,    3.0f,  0, 10, 20, 30},
2595     };
2596     unsigned int i;
2597
2598     TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2599             color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2600
2601     for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2602     {
2603         DWORD ret;
2604
2605         if (format->id != conv[i].format_id) continue;
2606
2607         ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2608         ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2609         ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2610         ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2611
2612         TRACE("Returning 0x%08x.\n", ret);
2613
2614         return ret;
2615     }
2616
2617     FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2618
2619     return 0;
2620 }
2621
2622 /* DirectDraw stuff */
2623 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2624 {
2625     switch (depth)
2626     {
2627         case 8:  return WINED3DFMT_P8_UINT;
2628         case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2629         case 16: return WINED3DFMT_B5G6R5_UNORM;
2630         case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2631         case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2632         default: return WINED3DFMT_UNKNOWN;
2633     }
2634 }
2635
2636 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2637     WINED3DMATRIX temp;
2638
2639     /* Now do the multiplication 'by hand'.
2640        I know that all this could be optimised, but this will be done later :-) */
2641     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);
2642     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);
2643     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);
2644     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);
2645
2646     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);
2647     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);
2648     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);
2649     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);
2650
2651     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);
2652     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);
2653     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);
2654     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);
2655
2656     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);
2657     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);
2658     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);
2659     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);
2660
2661     /* And copy the new matrix in the good storage.. */
2662     memcpy(dest, &temp, 16 * sizeof(float));
2663 }
2664
2665 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2666     DWORD size = 0;
2667     int i;
2668     int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2669
2670     if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2671     if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2672     if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2673     if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2674     switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2675         case WINED3DFVF_XYZ:    size += 3 * sizeof(float); break;
2676         case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2677         case WINED3DFVF_XYZB1:  size += 4 * sizeof(float); break;
2678         case WINED3DFVF_XYZB2:  size += 5 * sizeof(float); break;
2679         case WINED3DFVF_XYZB3:  size += 6 * sizeof(float); break;
2680         case WINED3DFVF_XYZB4:  size += 7 * sizeof(float); break;
2681         case WINED3DFVF_XYZB5:  size += 8 * sizeof(float); break;
2682         case WINED3DFVF_XYZW:   size += 4 * sizeof(float); break;
2683         default: ERR("Unexpected position mask\n");
2684     }
2685     for (i = 0; i < numTextures; i++) {
2686         size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2687     }
2688
2689     return size;
2690 }
2691
2692 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2693 #define ARG1 0x01
2694 #define ARG2 0x02
2695 #define ARG0 0x04
2696     static const unsigned char args[WINED3DTOP_LERP + 1] = {
2697         /* undefined                        */  0,
2698         /* D3DTOP_DISABLE                   */  0,
2699         /* D3DTOP_SELECTARG1                */  ARG1,
2700         /* D3DTOP_SELECTARG2                */  ARG2,
2701         /* D3DTOP_MODULATE                  */  ARG1 | ARG2,
2702         /* D3DTOP_MODULATE2X                */  ARG1 | ARG2,
2703         /* D3DTOP_MODULATE4X                */  ARG1 | ARG2,
2704         /* D3DTOP_ADD                       */  ARG1 | ARG2,
2705         /* D3DTOP_ADDSIGNED                 */  ARG1 | ARG2,
2706         /* D3DTOP_ADDSIGNED2X               */  ARG1 | ARG2,
2707         /* D3DTOP_SUBTRACT                  */  ARG1 | ARG2,
2708         /* D3DTOP_ADDSMOOTH                 */  ARG1 | ARG2,
2709         /* D3DTOP_BLENDDIFFUSEALPHA         */  ARG1 | ARG2,
2710         /* D3DTOP_BLENDTEXTUREALPHA         */  ARG1 | ARG2,
2711         /* D3DTOP_BLENDFACTORALPHA          */  ARG1 | ARG2,
2712         /* D3DTOP_BLENDTEXTUREALPHAPM       */  ARG1 | ARG2,
2713         /* D3DTOP_BLENDCURRENTALPHA         */  ARG1 | ARG2,
2714         /* D3DTOP_PREMODULATE               */  ARG1 | ARG2,
2715         /* D3DTOP_MODULATEALPHA_ADDCOLOR    */  ARG1 | ARG2,
2716         /* D3DTOP_MODULATECOLOR_ADDALPHA    */  ARG1 | ARG2,
2717         /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */  ARG1 | ARG2,
2718         /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */  ARG1 | ARG2,
2719         /* D3DTOP_BUMPENVMAP                */  ARG1 | ARG2,
2720         /* D3DTOP_BUMPENVMAPLUMINANCE       */  ARG1 | ARG2,
2721         /* D3DTOP_DOTPRODUCT3               */  ARG1 | ARG2,
2722         /* D3DTOP_MULTIPLYADD               */  ARG1 | ARG2 | ARG0,
2723         /* D3DTOP_LERP                      */  ARG1 | ARG2 | ARG0
2724     };
2725     unsigned int i;
2726     DWORD ttff;
2727     DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2728     IWineD3DDeviceImpl *device = stateblock->device;
2729     IWineD3DSurfaceImpl *rt = device->render_targets[0];
2730     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2731
2732     for (i = 0; i < gl_info->limits.texture_stages; ++i)
2733     {
2734         IWineD3DBaseTextureImpl *texture;
2735         settings->op[i].padding = 0;
2736         if (stateblock->state.texture_states[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE)
2737         {
2738             settings->op[i].cop = WINED3DTOP_DISABLE;
2739             settings->op[i].aop = WINED3DTOP_DISABLE;
2740             settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2741             settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2742             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2743             settings->op[i].dst = resultreg;
2744             settings->op[i].tex_type = tex_1d;
2745             settings->op[i].projected = proj_none;
2746             i++;
2747             break;
2748         }
2749
2750         if ((texture = stateblock->state.textures[i]))
2751         {
2752             settings->op[i].color_fixup = texture->resource.format->color_fixup;
2753             if (ignore_textype)
2754             {
2755                 settings->op[i].tex_type = tex_1d;
2756             }
2757             else
2758             {
2759                 switch (texture->baseTexture.target)
2760                 {
2761                     case GL_TEXTURE_1D:
2762                         settings->op[i].tex_type = tex_1d;
2763                         break;
2764                     case GL_TEXTURE_2D:
2765                         settings->op[i].tex_type = tex_2d;
2766                         break;
2767                     case GL_TEXTURE_3D:
2768                         settings->op[i].tex_type = tex_3d;
2769                         break;
2770                     case GL_TEXTURE_CUBE_MAP_ARB:
2771                         settings->op[i].tex_type = tex_cube;
2772                         break;
2773                     case GL_TEXTURE_RECTANGLE_ARB:
2774                         settings->op[i].tex_type = tex_rect;
2775                         break;
2776                 }
2777             }
2778         } else {
2779             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2780             settings->op[i].tex_type = tex_1d;
2781         }
2782
2783         cop = stateblock->state.texture_states[i][WINED3DTSS_COLOROP];
2784         aop = stateblock->state.texture_states[i][WINED3DTSS_ALPHAOP];
2785
2786         carg1 = (args[cop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2787         carg2 = (args[cop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2788         carg0 = (args[cop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2789
2790         if (is_invalid_op(&stateblock->state, i, cop, carg1, carg2, carg0))
2791         {
2792             carg0 = ARG_UNUSED;
2793             carg2 = ARG_UNUSED;
2794             carg1 = WINED3DTA_CURRENT;
2795             cop = WINED3DTOP_SELECTARG1;
2796         }
2797
2798         if(cop == WINED3DTOP_DOTPRODUCT3) {
2799             /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2800              * the color result to the alpha component of the destination
2801              */
2802             aop = cop;
2803             aarg1 = carg1;
2804             aarg2 = carg2;
2805             aarg0 = carg0;
2806         }
2807         else
2808         {
2809             aarg1 = (args[aop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2810             aarg2 = (args[aop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2811             aarg0 = (args[aop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2812         }
2813
2814         if (!i && stateblock->state.textures[0] && stateblock->state.render_states[WINED3DRS_COLORKEYENABLE])
2815         {
2816             IWineD3DBaseTextureImpl *texture = stateblock->state.textures[0];
2817             GLenum texture_dimensions = texture->baseTexture.target;
2818
2819             if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2820             {
2821                 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
2822
2823                 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
2824                 {
2825                     if (aop == WINED3DTOP_DISABLE)
2826                     {
2827                        aarg1 = WINED3DTA_TEXTURE;
2828                        aop = WINED3DTOP_SELECTARG1;
2829                     }
2830                     else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2831                     {
2832                         if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2833                         {
2834                             aarg2 = WINED3DTA_TEXTURE;
2835                             aop = WINED3DTOP_MODULATE;
2836                         }
2837                         else aarg1 = WINED3DTA_TEXTURE;
2838                     }
2839                     else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2840                     {
2841                         if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2842                         {
2843                             aarg1 = WINED3DTA_TEXTURE;
2844                             aop = WINED3DTOP_MODULATE;
2845                         }
2846                         else aarg2 = WINED3DTA_TEXTURE;
2847                     }
2848                 }
2849             }
2850         }
2851
2852         if (is_invalid_op(&stateblock->state, i, aop, aarg1, aarg2, aarg0))
2853         {
2854                aarg0 = ARG_UNUSED;
2855                aarg2 = ARG_UNUSED;
2856                aarg1 = WINED3DTA_CURRENT;
2857                aop = WINED3DTOP_SELECTARG1;
2858         }
2859
2860         if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
2861                 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
2862         {
2863             ttff = stateblock->state.texture_states[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2864             if (ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3))
2865             {
2866                 settings->op[i].projected = proj_count3;
2867             } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2868                 settings->op[i].projected = proj_count4;
2869             } else {
2870                 settings->op[i].projected = proj_none;
2871             }
2872         } else {
2873             settings->op[i].projected = proj_none;
2874         }
2875
2876         settings->op[i].cop = cop;
2877         settings->op[i].aop = aop;
2878         settings->op[i].carg0 = carg0;
2879         settings->op[i].carg1 = carg1;
2880         settings->op[i].carg2 = carg2;
2881         settings->op[i].aarg0 = aarg0;
2882         settings->op[i].aarg1 = aarg1;
2883         settings->op[i].aarg2 = aarg2;
2884
2885         if (stateblock->state.texture_states[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP)
2886         {
2887             settings->op[i].dst = tempreg;
2888         } else {
2889             settings->op[i].dst = resultreg;
2890         }
2891     }
2892
2893     /* Clear unsupported stages */
2894     for(; i < MAX_TEXTURES; i++) {
2895         memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2896     }
2897
2898     if (!stateblock->state.render_states[WINED3DRS_FOGENABLE])
2899     {
2900         settings->fog = FOG_OFF;
2901     }
2902     else if (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
2903     {
2904         if (use_vs(&stateblock->state) || stateblock->state.vertex_declaration->position_transformed)
2905         {
2906             settings->fog = FOG_LINEAR;
2907         }
2908         else
2909         {
2910             switch (stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE])
2911             {
2912                 case WINED3DFOG_NONE:
2913                 case WINED3DFOG_LINEAR:
2914                     settings->fog = FOG_LINEAR;
2915                     break;
2916                 case WINED3DFOG_EXP:
2917                     settings->fog = FOG_EXP;
2918                     break;
2919                 case WINED3DFOG_EXP2:
2920                     settings->fog = FOG_EXP2;
2921                     break;
2922             }
2923         }
2924     }
2925     else
2926     {
2927         switch (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE])
2928         {
2929             case WINED3DFOG_LINEAR:
2930                 settings->fog = FOG_LINEAR;
2931                 break;
2932             case WINED3DFOG_EXP:
2933                 settings->fog = FOG_EXP;
2934                 break;
2935             case WINED3DFOG_EXP2:
2936                 settings->fog = FOG_EXP2;
2937                 break;
2938         }
2939     }
2940     if (stateblock->state.render_states[WINED3DRS_SRGBWRITEENABLE]
2941             && rt->resource.format->Flags & WINED3DFMT_FLAG_SRGB_WRITE)
2942     {
2943         settings->sRGB_write = 1;
2944     } else {
2945         settings->sRGB_write = 0;
2946     }
2947     if (device->vs_clipping || !use_vs(&stateblock->state) || !stateblock->state.render_states[WINED3DRS_CLIPPING]
2948             || !stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE])
2949     {
2950         /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2951          * the fixed function vertex pipeline is used(which always supports clipplanes), or
2952          * if no clipplane is enabled
2953          */
2954         settings->emul_clipplanes = 0;
2955     } else {
2956         settings->emul_clipplanes = 1;
2957     }
2958 }
2959
2960 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2961         const struct ffp_frag_settings *settings)
2962 {
2963     struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2964     return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2965 }
2966
2967 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2968 {
2969     /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2970      * whereas desc points to an extended structure with implementation specific parts. */
2971     if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2972     {
2973         ERR("Failed to insert ffp frag shader.\n");
2974     }
2975 }
2976
2977 /* Activates the texture dimension according to the bound D3D texture.
2978  * Does not care for the colorop or correct gl texture unit(when using nvrc)
2979  * Requires the caller to activate the correct unit before
2980  */
2981 /* GL locking is done by the caller (state handler) */
2982 void texture_activate_dimensions(IWineD3DBaseTextureImpl *texture, const struct wined3d_gl_info *gl_info)
2983 {
2984     if (texture)
2985     {
2986         switch (texture->baseTexture.target)
2987         {
2988             case GL_TEXTURE_2D:
2989                 glDisable(GL_TEXTURE_3D);
2990                 checkGLcall("glDisable(GL_TEXTURE_3D)");
2991                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2992                 {
2993                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2994                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2995                 }
2996                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2997                 {
2998                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
2999                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3000                 }
3001                 glEnable(GL_TEXTURE_2D);
3002                 checkGLcall("glEnable(GL_TEXTURE_2D)");
3003                 break;
3004             case GL_TEXTURE_RECTANGLE_ARB:
3005                 glDisable(GL_TEXTURE_2D);
3006                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3007                 glDisable(GL_TEXTURE_3D);
3008                 checkGLcall("glDisable(GL_TEXTURE_3D)");
3009                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3010                 {
3011                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3012                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3013                 }
3014                 glEnable(GL_TEXTURE_RECTANGLE_ARB);
3015                 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3016                 break;
3017             case GL_TEXTURE_3D:
3018                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3019                 {
3020                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3021                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3022                 }
3023                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3024                 {
3025                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
3026                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3027                 }
3028                 glDisable(GL_TEXTURE_2D);
3029                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3030                 glEnable(GL_TEXTURE_3D);
3031                 checkGLcall("glEnable(GL_TEXTURE_3D)");
3032                 break;
3033             case GL_TEXTURE_CUBE_MAP_ARB:
3034                 glDisable(GL_TEXTURE_2D);
3035                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3036                 glDisable(GL_TEXTURE_3D);
3037                 checkGLcall("glDisable(GL_TEXTURE_3D)");
3038                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3039                 {
3040                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
3041                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3042                 }
3043                 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3044                 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3045               break;
3046         }
3047     } else {
3048         glEnable(GL_TEXTURE_2D);
3049         checkGLcall("glEnable(GL_TEXTURE_2D)");
3050         glDisable(GL_TEXTURE_3D);
3051         checkGLcall("glDisable(GL_TEXTURE_3D)");
3052         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3053         {
3054             glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3055             checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3056         }
3057         if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3058         {
3059             glDisable(GL_TEXTURE_RECTANGLE_ARB);
3060             checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3061         }
3062         /* Binding textures is done by samplers. A dummy texture will be bound */
3063     }
3064 }
3065
3066 /* GL locking is done by the caller (state handler) */
3067 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3068 {
3069     DWORD sampler = state - STATE_SAMPLER(0);
3070     DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3071
3072     /* No need to enable / disable anything here for unused samplers. The tex_colorop
3073     * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3074     * will take care of this business
3075     */
3076     if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3077     if (sampler >= stateblock->state.lowest_disabled_stage) return;
3078     if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3079
3080     texture_activate_dimensions(stateblock->state.textures[sampler], context->gl_info);
3081 }
3082
3083 void *wined3d_rb_alloc(size_t size)
3084 {
3085     return HeapAlloc(GetProcessHeap(), 0, size);
3086 }
3087
3088 void *wined3d_rb_realloc(void *ptr, size_t size)
3089 {
3090     return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3091 }
3092
3093 void wined3d_rb_free(void *ptr)
3094 {
3095     HeapFree(GetProcessHeap(), 0, ptr);
3096 }
3097
3098 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3099 {
3100     const struct ffp_frag_settings *ka = key;
3101     const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3102
3103     return memcmp(ka, kb, sizeof(*ka));
3104 }
3105
3106 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3107 {
3108     wined3d_rb_alloc,
3109     wined3d_rb_realloc,
3110     wined3d_rb_free,
3111     ffp_frag_program_key_compare,
3112 };
3113
3114 UINT wined3d_log2i(UINT32 x)
3115 {
3116     static const UINT l[] =
3117     {
3118         ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3119           4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3120           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3121           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
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           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3125           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
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           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3133           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3134     };
3135     UINT32 i;
3136
3137     return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3138 }
3139
3140 /* Set the shader type for this device, depending on the given capabilities
3141  * and the user preferences in wined3d_settings. */
3142 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3143 {
3144     BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3145
3146     if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3147     else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3148     {
3149         /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3150          * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3151          * shaders only on this card. */
3152         if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3153         else *vs_selected = SHADER_GLSL;
3154     }
3155     else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3156     else *vs_selected = SHADER_NONE;
3157
3158     if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3159     else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3160     else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3161     else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3162     else *ps_selected = SHADER_NONE;
3163 }
3164
3165 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
3166         const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format *src_format,
3167         const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format *dst_format)
3168 {
3169     static const struct blit_shader * const blitters[] =
3170     {
3171         &arbfp_blit,
3172         &ffp_blit,
3173         &cpu_blit,
3174     };
3175     unsigned int i;
3176
3177     for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3178     {
3179         if (blitters[i]->blit_supported(gl_info, blit_op,
3180                 src_rect, src_usage, src_pool, src_format,
3181                 dst_rect, dst_usage, dst_pool, dst_format))
3182             return blitters[i];
3183     }
3184
3185     return NULL;
3186 }