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