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