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