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