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