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