mshtml: Use lazy allocation for connection points.
[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 "wine/port.h"
29
30 #include "wined3d_private.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
33
34 struct wined3d_format_channels
35 {
36     enum wined3d_format_id id;
37     DWORD red_size, green_size, blue_size, alpha_size;
38     DWORD red_offset, green_offset, blue_offset, alpha_offset;
39     UINT bpp;
40     BYTE depth_size, stencil_size;
41 };
42
43 static const struct wined3d_format_channels formats[] =
44 {
45     /*                                          size            offset
46      *  format id                           r   g   b   a    r   g   b   a    bpp depth stencil */
47     {WINED3DFMT_UNKNOWN,                    0,  0,  0,  0,   0,  0,  0,  0,    0,   0,     0},
48     /* FourCC formats */
49     {WINED3DFMT_UYVY,                       0,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
50     {WINED3DFMT_YUY2,                       0,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
51     {WINED3DFMT_YV12,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
52     {WINED3DFMT_DXT1,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
53     {WINED3DFMT_DXT2,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
54     {WINED3DFMT_DXT3,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
55     {WINED3DFMT_DXT4,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
56     {WINED3DFMT_DXT5,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
57     {WINED3DFMT_MULTI2_ARGB8,               0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
58     {WINED3DFMT_G8R8_G8B8,                  0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
59     {WINED3DFMT_R8G8_B8G8,                  0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
60     /* IEEE formats */
61     {WINED3DFMT_R32_FLOAT,                 32,  0,  0,  0,   0,  0,  0,  0,    4,   0,     0},
62     {WINED3DFMT_R32G32_FLOAT,              32, 32,  0,  0,   0, 32,  0,  0,    8,   0,     0},
63     {WINED3DFMT_R32G32B32_FLOAT,           32, 32, 32,  0,   0, 32, 64,  0,   12,   0,     0},
64     {WINED3DFMT_R32G32B32A32_FLOAT,        32, 32, 32, 32,   0, 32, 64, 96,   16,   0,     0},
65     /* Hmm? */
66     {WINED3DFMT_R8G8_SNORM_Cx,              0,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
67     /* Float */
68     {WINED3DFMT_R16_FLOAT,                 16,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
69     {WINED3DFMT_R16G16_FLOAT,              16, 16,  0,  0,   0, 16,  0,  0,    4,   0,     0},
70     {WINED3DFMT_R16G16_SINT,               16, 16,  0,  0,   0, 16,  0,  0,    4,   0,     0},
71     {WINED3DFMT_R16G16B16A16_FLOAT,        16, 16, 16, 16,   0, 16, 32, 48,    8,   0,     0},
72     {WINED3DFMT_R16G16B16A16_SINT,         16, 16, 16, 16,   0, 16, 32, 48,    8,   0,     0},
73     /* Palettized formats */
74     {WINED3DFMT_P8_UINT_A8_UNORM,           0,  0,  0,  8,   0,  0,  0,  8,    2,   0,     0},
75     {WINED3DFMT_P8_UINT,                    0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
76     /* Standard ARGB formats. */
77     {WINED3DFMT_B8G8R8_UNORM,               8,  8,  8,  0,  16,  8,  0,  0,    3,   0,     0},
78     {WINED3DFMT_B8G8R8A8_UNORM,             8,  8,  8,  8,  16,  8,  0, 24,    4,   0,     0},
79     {WINED3DFMT_B8G8R8X8_UNORM,             8,  8,  8,  0,  16,  8,  0,  0,    4,   0,     0},
80     {WINED3DFMT_B5G6R5_UNORM,               5,  6,  5,  0,  11,  5,  0,  0,    2,   0,     0},
81     {WINED3DFMT_B5G5R5X1_UNORM,             5,  5,  5,  0,  10,  5,  0,  0,    2,   0,     0},
82     {WINED3DFMT_B5G5R5A1_UNORM,             5,  5,  5,  1,  10,  5,  0, 15,    2,   0,     0},
83     {WINED3DFMT_B4G4R4A4_UNORM,             4,  4,  4,  4,   8,  4,  0, 12,    2,   0,     0},
84     {WINED3DFMT_B2G3R3_UNORM,               3,  3,  2,  0,   5,  2,  0,  0,    1,   0,     0},
85     {WINED3DFMT_A8_UNORM,                   0,  0,  0,  8,   0,  0,  0,  0,    1,   0,     0},
86     {WINED3DFMT_B2G3R3A8_UNORM,             3,  3,  2,  8,   5,  2,  0,  8,    2,   0,     0},
87     {WINED3DFMT_B4G4R4X4_UNORM,             4,  4,  4,  0,   8,  4,  0,  0,    2,   0,     0},
88     {WINED3DFMT_R10G10B10A2_UNORM,         10, 10, 10,  2,   0, 10, 20, 30,    4,   0,     0},
89     {WINED3DFMT_R10G10B10A2_UINT,          10, 10, 10,  2,   0, 10, 20, 30,    4,   0,     0},
90     {WINED3DFMT_R10G10B10A2_SNORM,         10, 10, 10,  2,   0, 10, 20, 30,    4,   0,     0},
91     {WINED3DFMT_R8G8B8A8_UNORM,             8,  8,  8,  8,   0,  8, 16, 24,    4,   0,     0},
92     {WINED3DFMT_R8G8B8A8_UINT,              8,  8,  8,  8,   0,  8, 16, 24,    4,   0,     0},
93     {WINED3DFMT_R8G8B8X8_UNORM,             8,  8,  8,  0,   0,  8, 16,  0,    4,   0,     0},
94     {WINED3DFMT_R16G16_UNORM,              16, 16,  0,  0,   0, 16,  0,  0,    4,   0,     0},
95     {WINED3DFMT_B10G10R10A2_UNORM,         10, 10, 10,  2,  20, 10,  0, 30,    4,   0,     0},
96     {WINED3DFMT_R16G16B16A16_UNORM,        16, 16, 16, 16,   0, 16, 32, 48,    8,   0,     0},
97     /* Luminance */
98     {WINED3DFMT_L8_UNORM,                   0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
99     {WINED3DFMT_L8A8_UNORM,                 0,  0,  0,  8,   0,  0,  0,  8,    2,   0,     0},
100     {WINED3DFMT_L4A4_UNORM,                 0,  0,  0,  4,   0,  0,  0,  4,    1,   0,     0},
101     {WINED3DFMT_L16_UNORM,                  0,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
102     /* Bump mapping stuff */
103     {WINED3DFMT_R8G8_SNORM,                 8,  8,  0,  0,   0,  8,  0,  0,    2,   0,     0},
104     {WINED3DFMT_R5G5_SNORM_L6_UNORM,        5,  5,  0,  0,   0,  5,  0,  0,    2,   0,     0},
105     {WINED3DFMT_R8G8_SNORM_L8X8_UNORM,      8,  8,  0,  0,   0,  8,  0,  0,    4,   0,     0},
106     {WINED3DFMT_R8G8B8A8_SNORM,             8,  8,  8,  8,   0,  8, 16, 24,    4,   0,     0},
107     {WINED3DFMT_R16G16_SNORM,              16, 16,  0,  0,   0, 16,  0,  0,    4,   0,     0},
108     {WINED3DFMT_R10G11B11_SNORM,           10, 11, 11,  0,   0, 10, 21,  0,    4,   0,     0},
109     {WINED3DFMT_R10G10B10_SNORM_A2_UNORM,  10, 10, 10,  2,   0, 10, 20, 30,    4,   0,     0},
110     /* Depth stencil formats */
111     {WINED3DFMT_D16_LOCKABLE,               0,  0,  0,  0,   0,  0,  0,  0,    2,  16,     0},
112     {WINED3DFMT_D32_UNORM,                  0,  0,  0,  0,   0,  0,  0,  0,    4,  32,     0},
113     {WINED3DFMT_S1_UINT_D15_UNORM,          0,  0,  0,  0,   0,  0,  0,  0,    2,  15,     1},
114     {WINED3DFMT_D24_UNORM_S8_UINT,          0,  0,  0,  0,   0,  0,  0,  0,    4,  24,     8},
115     {WINED3DFMT_X8D24_UNORM,                0,  0,  0,  0,   0,  0,  0,  0,    4,  24,     0},
116     {WINED3DFMT_S4X4_UINT_D24_UNORM,        0,  0,  0,  0,   0,  0,  0,  0,    4,  24,     4},
117     {WINED3DFMT_D16_UNORM,                  0,  0,  0,  0,   0,  0,  0,  0,    2,  16,     0},
118     {WINED3DFMT_D32_FLOAT,                  0,  0,  0,  0,   0,  0,  0,  0,    4,  32,     0},
119     {WINED3DFMT_S8_UINT_D24_FLOAT,          0,  0,  0,  0,   0,  0,  0,  0,    4,  24,     8},
120     {WINED3DFMT_VERTEXDATA,                 0,  0,  0,  0,   0,  0,  0,  0,    0,   0,     0},
121     {WINED3DFMT_R16_UINT,                  16,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
122     {WINED3DFMT_R32_UINT,                  32,  0,  0,  0,   0,  0,  0,  0,    4,   0,     0},
123     {WINED3DFMT_R16G16B16A16_SNORM,        16, 16, 16, 16,   0, 16, 32, 48,    8,   0,     0},
124     /* Vendor-specific formats */
125     {WINED3DFMT_ATI2N,                      0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
126     {WINED3DFMT_NVDB,                       0,  0,  0,  0,   0,  0,  0,  0,    0,   0,     0},
127     {WINED3DFMT_INST,                       0,  0,  0,  0,   0,  0,  0,  0,    0,   0,     0},
128     {WINED3DFMT_INTZ,                       0,  0,  0,  0,   0,  0,  0,  0,    4,  24,     8},
129     {WINED3DFMT_RESZ,                       0,  0,  0,  0,   0,  0,  0,  0,    0,   0,     0},
130     {WINED3DFMT_NVHU,                       0,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
131     {WINED3DFMT_NVHS,                       0,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
132     {WINED3DFMT_NULL,                       8,  8,  8,  8,   0,  8, 16, 24,    4,   0,     0},
133     /* Unsure about them, could not find a Windows driver that supports them */
134     {WINED3DFMT_R16,                       16,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
135     {WINED3DFMT_AL16,                       0,  0,  0, 16,   0,  0,  0, 16,    4,   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_INTZ,               WINED3DFMT_FLAG_FOURCC},
161     {WINED3DFMT_NULL,               WINED3DFMT_FLAG_FOURCC},
162     {WINED3DFMT_P8_UINT,            WINED3DFMT_FLAG_GETDC},
163     {WINED3DFMT_B8G8R8_UNORM,       WINED3DFMT_FLAG_GETDC},
164     {WINED3DFMT_B8G8R8A8_UNORM,     WINED3DFMT_FLAG_GETDC},
165     {WINED3DFMT_B8G8R8X8_UNORM,     WINED3DFMT_FLAG_GETDC},
166     {WINED3DFMT_B5G6R5_UNORM,       WINED3DFMT_FLAG_GETDC},
167     {WINED3DFMT_B5G5R5X1_UNORM,     WINED3DFMT_FLAG_GETDC},
168     {WINED3DFMT_B5G5R5A1_UNORM,     WINED3DFMT_FLAG_GETDC},
169     {WINED3DFMT_B4G4R4A4_UNORM,     WINED3DFMT_FLAG_GETDC},
170     {WINED3DFMT_B4G4R4X4_UNORM,     WINED3DFMT_FLAG_GETDC},
171     {WINED3DFMT_R8G8B8A8_UNORM,     WINED3DFMT_FLAG_GETDC},
172     {WINED3DFMT_R8G8B8X8_UNORM,     WINED3DFMT_FLAG_GETDC},
173     {WINED3DFMT_ATI2N,              WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
174     {WINED3DFMT_NVDB,               WINED3DFMT_FLAG_FOURCC},
175     {WINED3DFMT_NVHU,               WINED3DFMT_FLAG_FOURCC},
176     {WINED3DFMT_NVHS,               WINED3DFMT_FLAG_FOURCC},
177     {WINED3DFMT_R32_FLOAT,          WINED3DFMT_FLAG_FLOAT},
178     {WINED3DFMT_R32G32_FLOAT,       WINED3DFMT_FLAG_FLOAT},
179     {WINED3DFMT_R32G32B32_FLOAT,    WINED3DFMT_FLAG_FLOAT},
180     {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
181     {WINED3DFMT_R16_FLOAT,          WINED3DFMT_FLAG_FLOAT},
182     {WINED3DFMT_R16G16_FLOAT,       WINED3DFMT_FLAG_FLOAT},
183     {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
184     {WINED3DFMT_D32_FLOAT,          WINED3DFMT_FLAG_FLOAT},
185     {WINED3DFMT_S8_UINT_D24_FLOAT,  WINED3DFMT_FLAG_FLOAT},
186 };
187
188 struct wined3d_format_block_info
189 {
190     enum wined3d_format_id id;
191     UINT block_width;
192     UINT block_height;
193     UINT block_byte_count;
194 };
195
196 static const struct wined3d_format_block_info format_block_info[] =
197 {
198     {WINED3DFMT_DXT1,   4,  4,  8},
199     {WINED3DFMT_DXT2,   4,  4,  16},
200     {WINED3DFMT_DXT3,   4,  4,  16},
201     {WINED3DFMT_DXT4,   4,  4,  16},
202     {WINED3DFMT_DXT5,   4,  4,  16},
203     {WINED3DFMT_ATI2N,  4,  4,  16},
204     {WINED3DFMT_YUY2,   2,  1,  4},
205     {WINED3DFMT_UYVY,   2,  1,  4},
206 };
207
208 struct wined3d_format_vertex_info
209 {
210     enum wined3d_format_id id;
211     enum wined3d_ffp_emit_idx emit_idx;
212     GLint component_count;
213     GLenum gl_vtx_type;
214     GLint gl_vtx_format;
215     GLboolean gl_normalized;
216     unsigned int component_size;
217 };
218
219 static const struct wined3d_format_vertex_info format_vertex_info[] =
220 {
221     {WINED3DFMT_R32_FLOAT,          WINED3D_FFP_EMIT_FLOAT1,    1, GL_FLOAT,          1, GL_FALSE, sizeof(float)},
222     {WINED3DFMT_R32G32_FLOAT,       WINED3D_FFP_EMIT_FLOAT2,    2, GL_FLOAT,          2, GL_FALSE, sizeof(float)},
223     {WINED3DFMT_R32G32B32_FLOAT,    WINED3D_FFP_EMIT_FLOAT3,    3, GL_FLOAT,          3, GL_FALSE, sizeof(float)},
224     {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4,    4, GL_FLOAT,          4, GL_FALSE, sizeof(float)},
225     {WINED3DFMT_B8G8R8A8_UNORM,     WINED3D_FFP_EMIT_D3DCOLOR,  4, GL_UNSIGNED_BYTE,  4, GL_TRUE,  sizeof(BYTE)},
226     {WINED3DFMT_R8G8B8A8_UINT,      WINED3D_FFP_EMIT_UBYTE4,    4, GL_UNSIGNED_BYTE,  4, GL_FALSE, sizeof(BYTE)},
227     {WINED3DFMT_R16G16_SINT,        WINED3D_FFP_EMIT_SHORT2,    2, GL_SHORT,          2, GL_FALSE, sizeof(short int)},
228     {WINED3DFMT_R16G16B16A16_SINT,  WINED3D_FFP_EMIT_SHORT4,    4, GL_SHORT,          4, GL_FALSE, sizeof(short int)},
229     {WINED3DFMT_R8G8B8A8_UNORM,     WINED3D_FFP_EMIT_UBYTE4N,   4, GL_UNSIGNED_BYTE,  4, GL_TRUE,  sizeof(BYTE)},
230     {WINED3DFMT_R16G16_SNORM,       WINED3D_FFP_EMIT_SHORT2N,   2, GL_SHORT,          2, GL_TRUE,  sizeof(short int)},
231     {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N,   4, GL_SHORT,          4, GL_TRUE,  sizeof(short int)},
232     {WINED3DFMT_R16G16_UNORM,       WINED3D_FFP_EMIT_USHORT2N,  2, GL_UNSIGNED_SHORT, 2, GL_TRUE,  sizeof(short int)},
233     {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N,  4, GL_UNSIGNED_SHORT, 4, GL_TRUE,  sizeof(short int)},
234     {WINED3DFMT_R10G10B10A2_UINT,   WINED3D_FFP_EMIT_UDEC3,     3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
235     {WINED3DFMT_R10G10B10A2_SNORM,  WINED3D_FFP_EMIT_DEC3N,     3, GL_SHORT,          3, GL_TRUE,  sizeof(short int)},
236     {WINED3DFMT_R16G16_FLOAT,       WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT,          2, GL_FALSE, sizeof(GLhalfNV)},
237     {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT,          4, GL_FALSE, sizeof(GLhalfNV)}
238 };
239
240 struct wined3d_format_texture_info
241 {
242     enum wined3d_format_id id;
243     GLint gl_internal;
244     GLint gl_srgb_internal;
245     GLint gl_rt_internal;
246     GLint gl_format;
247     GLint gl_type;
248     unsigned int conv_byte_count;
249     unsigned int flags;
250     enum wined3d_gl_extension extension;
251     void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
252 };
253
254 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
255 {
256     /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
257      * format+type combination to load it. Thus convert it to A8L8, then load it
258      * with A4L4 internal, but A8L8 format+type
259      */
260     unsigned int x, y;
261     const unsigned char *Source;
262     unsigned char *Dest;
263     UINT outpitch = pitch * 2;
264
265     for(y = 0; y < height; y++) {
266         Source = src + y * pitch;
267         Dest = dst + y * outpitch;
268         for (x = 0; x < width; x++ ) {
269             unsigned char color = (*Source++);
270             /* A */ Dest[1] = (color & 0xf0) << 0;
271             /* L */ Dest[0] = (color & 0x0f) << 4;
272             Dest += 2;
273         }
274     }
275 }
276
277 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
278 {
279     unsigned int x, y;
280     const WORD *Source;
281
282     for(y = 0; y < height; y++)
283     {
284         unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
285         Source = (const WORD *)(src + y * pitch);
286         for (x = 0; x < width; x++ )
287         {
288             short color = (*Source++);
289             unsigned char l = ((color >> 10) & 0xfc);
290                     short v = ((color >>  5) & 0x3e);
291                     short u = ((color      ) & 0x1f);
292             short v_conv = v + 16;
293             short u_conv = u + 16;
294
295             *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
296             Dest_s += 1;
297         }
298     }
299 }
300
301 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
302 {
303     unsigned int x, y;
304     const WORD *Source;
305     unsigned char *Dest;
306     UINT outpitch = (pitch * 3)/2;
307
308     /* This makes the gl surface bigger(24 bit instead of 16), but it works with
309      * fixed function and shaders without further conversion once the surface is
310      * loaded
311      */
312     for(y = 0; y < height; y++) {
313         Source = (const WORD *)(src + y * pitch);
314         Dest = dst + y * outpitch;
315         for (x = 0; x < width; x++ ) {
316             short color = (*Source++);
317             unsigned char l = ((color >> 10) & 0xfc);
318                      char v = ((color >>  5) & 0x3e);
319                      char u = ((color      ) & 0x1f);
320
321             /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
322              * and doubles the positive range. Thus shift left only once, gl does the 2nd
323              * shift. GL reads a signed value and converts it into an unsigned value.
324              */
325             /* M */ Dest[2] = l << 1;
326
327             /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
328              * from 5 bit values to 8 bit values.
329              */
330             /* V */ Dest[1] = v << 3;
331             /* U */ Dest[0] = u << 3;
332             Dest += 3;
333         }
334     }
335 }
336
337 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
338 {
339     unsigned int x, y;
340     const short *Source;
341     unsigned char *Dest;
342     UINT outpitch = (pitch * 3)/2;
343
344     for(y = 0; y < height; y++)
345     {
346         Source = (const short *)(src + y * pitch);
347         Dest = dst + y * outpitch;
348         for (x = 0; x < width; x++ )
349         {
350             const short color = (*Source++);
351             /* B */ Dest[0] = 0xff;
352             /* G */ Dest[1] = (color >> 8) + 128; /* V */
353             /* R */ Dest[2] = (color & 0xff) + 128;      /* U */
354             Dest += 3;
355         }
356     }
357 }
358
359 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
360 {
361     unsigned int x, y;
362     const DWORD *Source;
363     unsigned char *Dest;
364
365     /* Doesn't work correctly with the fixed function pipeline, but can work in
366      * shaders if the shader is adjusted. (There's no use for this format in gl's
367      * standard fixed function pipeline anyway).
368      */
369     for(y = 0; y < height; y++)
370     {
371         Source = (const DWORD *)(src + y * pitch);
372         Dest = dst + y * pitch;
373         for (x = 0; x < width; x++ )
374         {
375             LONG color = (*Source++);
376             /* B */ Dest[0] = ((color >> 16) & 0xff);       /* L */
377             /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
378             /* R */ Dest[2] = (color         & 0xff) + 128; /* U */
379             Dest += 4;
380         }
381     }
382 }
383
384 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
385 {
386     unsigned int x, y;
387     const DWORD *Source;
388     unsigned char *Dest;
389
390     /* This implementation works with the fixed function pipeline and shaders
391      * without further modification after converting the surface.
392      */
393     for(y = 0; y < height; y++)
394     {
395         Source = (const DWORD *)(src + y * pitch);
396         Dest = dst + y * pitch;
397         for (x = 0; x < width; x++ )
398         {
399             LONG color = (*Source++);
400             /* L */ Dest[2] = ((color >> 16) & 0xff);   /* L */
401             /* V */ Dest[1] = ((color >> 8 ) & 0xff);   /* V */
402             /* U */ Dest[0] = (color         & 0xff);   /* U */
403             /* I */ Dest[3] = 255;                      /* X */
404             Dest += 4;
405         }
406     }
407 }
408
409 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
410 {
411     unsigned int x, y;
412     const DWORD *Source;
413     unsigned char *Dest;
414
415     for(y = 0; y < height; y++)
416     {
417         Source = (const DWORD *)(src + y * pitch);
418         Dest = dst + y * pitch;
419         for (x = 0; x < width; x++ )
420         {
421             LONG color = (*Source++);
422             /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
423             /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
424             /* R */ Dest[2] = (color         & 0xff) + 128; /* U */
425             /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
426             Dest += 4;
427         }
428     }
429 }
430
431 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
432 {
433     unsigned int x, y;
434     const DWORD *Source;
435     unsigned short *Dest;
436     UINT outpitch = (pitch * 3)/2;
437
438     for(y = 0; y < height; y++)
439     {
440         Source = (const DWORD *)(src + y * pitch);
441         Dest = (unsigned short *) (dst + y * outpitch);
442         for (x = 0; x < width; x++ )
443         {
444             const DWORD color = (*Source++);
445             /* B */ Dest[0] = 0xffff;
446             /* G */ Dest[1] = (color >> 16) + 32768; /* V */
447             /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */
448             Dest += 3;
449         }
450     }
451 }
452
453 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
454 {
455     unsigned int x, y;
456     const WORD *Source;
457     WORD *Dest;
458     UINT outpitch = (pitch * 3)/2;
459
460     for(y = 0; y < height; y++)
461     {
462         Source = (const WORD *)(src + y * pitch);
463         Dest = (WORD *) (dst + y * outpitch);
464         for (x = 0; x < width; x++ )
465         {
466             WORD green = (*Source++);
467             WORD red = (*Source++);
468             Dest[0] = green;
469             Dest[1] = red;
470             /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
471              * shader overwrites it anyway
472              */
473             Dest[2] = 0xffff;
474             Dest += 3;
475         }
476     }
477 }
478
479 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
480 {
481     unsigned int x, y;
482     const float *Source;
483     float *Dest;
484     UINT outpitch = (pitch * 3)/2;
485
486     for(y = 0; y < height; y++)
487     {
488         Source = (const float *)(src + y * pitch);
489         Dest = (float *) (dst + y * outpitch);
490         for (x = 0; x < width; x++ )
491         {
492             float green = (*Source++);
493             float red = (*Source++);
494             Dest[0] = green;
495             Dest[1] = red;
496             Dest[2] = 1.0f;
497             Dest += 3;
498         }
499     }
500 }
501
502 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
503 {
504     unsigned int x, y;
505     UINT outpitch = pitch * 2;
506
507     for (y = 0; y < height; ++y)
508     {
509         const WORD *source = (const WORD *)(src + y * pitch);
510         DWORD *dest = (DWORD *)(dst + y * outpitch);
511
512         for (x = 0; x < width; ++x)
513         {
514             /* The depth data is normalized, so needs to be scaled,
515              * the stencil data isn't.  Scale depth data by
516              *      (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
517             WORD d15 = source[x] >> 1;
518             DWORD d24 = (d15 << 9) + (d15 >> 6);
519             dest[x] = (d24 << 8) | (source[x] & 0x1);
520         }
521     }
522 }
523
524 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
525 {
526     unsigned int x, y;
527
528     for (y = 0; y < height; ++y)
529     {
530         const DWORD *source = (const DWORD *)(src + y * pitch);
531         DWORD *dest = (DWORD *)(dst + y * pitch);
532
533         for (x = 0; x < width; ++x)
534         {
535             /* Just need to clear out the X4 part. */
536             dest[x] = source[x] & ~0xf0;
537         }
538     }
539 }
540
541 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
542 {
543     unsigned int x, y;
544     UINT outpitch = pitch * 2;
545
546     for (y = 0; y < height; ++y)
547     {
548         const DWORD *source = (const DWORD *)(src + y * pitch);
549         float *dest_f = (float *)(dst + y * outpitch);
550         DWORD *dest_s = (DWORD *)(dst + y * outpitch);
551
552         for (x = 0; x < width; ++x)
553         {
554             dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
555             dest_s[x * 2 + 1] = source[x] & 0xff;
556         }
557     }
558 }
559
560 /* The following formats explicitly don't have WINED3DFMT_FLAG_TEXTURE set:
561  *
562  * These are never supported on native.
563  *     WINED3DFMT_B8G8R8_UNORM
564  *     WINED3DFMT_B2G3R3_UNORM
565  *     WINED3DFMT_L4A4_UNORM
566  *     WINED3DFMT_S1_UINT_D15_UNORM
567  *     WINED3DFMT_S4X4_UINT_D24_UNORM
568  *
569  * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of ddraw.
570  * Since it is not widely available, don't offer it. Further no Windows driver
571  * offers WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either.
572  *     WINED3DFMT_P8_UINT
573  *     WINED3DFMT_P8_UINT_A8_UNORM
574  *
575  * These formats seem to be similar to the HILO formats in
576  * GL_NV_texture_shader. NVHU is said to be GL_UNSIGNED_HILO16,
577  * NVHS GL_SIGNED_HILO16. Rumours say that D3D computes a 3rd channel
578  * similarly to D3DFMT_CxV8U8 (So NVHS could be called D3DFMT_CxV16U16). ATI
579  * refused to support formats which can easily be emulated with pixel shaders,
580  * so applications have to deal with not having NVHS and NVHU.
581  *     WINED3DFMT_NVHU
582  *     WINED3DFMT_NVHS */
583 static const struct wined3d_format_texture_info format_texture_info[] =
584 {
585     /* format id                        internal                          srgbInternal                       rtInternal
586             format                      type
587             flags
588             extension */
589     /* FourCC formats */
590     /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
591      * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
592      * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
593      * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
594      * endian machine
595      */
596     {WINED3DFMT_UYVY,                   GL_LUMINANCE_ALPHA,               GL_LUMINANCE_ALPHA,                     0,
597             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
598             WINED3DFMT_FLAG_FILTERING,
599             WINED3D_GL_EXT_NONE,        NULL},
600     {WINED3DFMT_UYVY,                   GL_RGB,                           GL_RGB,                                 0,
601             GL_YCBCR_422_APPLE,         GL_UNSIGNED_SHORT_8_8_APPLE,      0,
602             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
603             APPLE_YCBCR_422,            NULL},
604     {WINED3DFMT_YUY2,                   GL_LUMINANCE_ALPHA,               GL_LUMINANCE_ALPHA,                     0,
605             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
606             WINED3DFMT_FLAG_FILTERING,
607             WINED3D_GL_EXT_NONE,        NULL},
608     {WINED3DFMT_YUY2,                   GL_RGB,                           GL_RGB,                                 0,
609             GL_YCBCR_422_APPLE,         GL_UNSIGNED_SHORT_8_8_REV_APPLE,  0,
610             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
611             APPLE_YCBCR_422,            NULL},
612     {WINED3DFMT_YV12,                   GL_ALPHA,                         GL_ALPHA,                               0,
613             GL_ALPHA,                   GL_UNSIGNED_BYTE,                 0,
614             WINED3DFMT_FLAG_FILTERING,
615             WINED3D_GL_EXT_NONE,        NULL},
616     {WINED3DFMT_DXT1,                   GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
617             GL_RGBA,                    GL_UNSIGNED_BYTE,                 0,
618             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
619             | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
620             EXT_TEXTURE_COMPRESSION_S3TC, NULL},
621     {WINED3DFMT_DXT2,                   GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
622             GL_RGBA,                    GL_UNSIGNED_BYTE,                 0,
623             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
624             | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
625             EXT_TEXTURE_COMPRESSION_S3TC, NULL},
626     {WINED3DFMT_DXT3,                   GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
627             GL_RGBA,                    GL_UNSIGNED_BYTE,                 0,
628             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
629             | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
630             EXT_TEXTURE_COMPRESSION_S3TC, NULL},
631     {WINED3DFMT_DXT4,                   GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
632             GL_RGBA,                    GL_UNSIGNED_BYTE,                 0,
633             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
634             | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
635             EXT_TEXTURE_COMPRESSION_S3TC, NULL},
636     {WINED3DFMT_DXT5,                   GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
637             GL_RGBA,                    GL_UNSIGNED_BYTE,                 0,
638             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
639             | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
640             EXT_TEXTURE_COMPRESSION_S3TC, NULL},
641     /* IEEE formats */
642     {WINED3DFMT_R32_FLOAT,              GL_RGB32F_ARB,                    GL_RGB32F_ARB,                          0,
643             GL_RED,                     GL_FLOAT,                         0,
644             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
645             ARB_TEXTURE_FLOAT,          NULL},
646     {WINED3DFMT_R32_FLOAT,              GL_R32F,                          GL_R32F,                                0,
647             GL_RED,                     GL_FLOAT,                         0,
648             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
649             ARB_TEXTURE_RG,             NULL},
650     {WINED3DFMT_R32G32_FLOAT,           GL_RGB32F_ARB,                    GL_RGB32F_ARB,                          0,
651             GL_RGB,                     GL_FLOAT,                         12,
652             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
653             ARB_TEXTURE_FLOAT,          convert_r32g32_float},
654     {WINED3DFMT_R32G32_FLOAT,           GL_RG32F,                         GL_RG32F,                               0,
655             GL_RG,                      GL_FLOAT,                         0,
656             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
657             ARB_TEXTURE_RG,             NULL},
658     {WINED3DFMT_R32G32B32A32_FLOAT,     GL_RGBA32F_ARB,                   GL_RGBA32F_ARB,                         0,
659             GL_RGBA,                    GL_FLOAT,                         0,
660             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
661             ARB_TEXTURE_FLOAT,          NULL},
662     /* Float */
663     {WINED3DFMT_R16_FLOAT,              GL_RGB16F_ARB,                    GL_RGB16F_ARB,                          0,
664             GL_RED,                     GL_HALF_FLOAT_ARB,                0,
665             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
666             ARB_TEXTURE_FLOAT,          NULL},
667     {WINED3DFMT_R16_FLOAT,              GL_R16F,                          GL_R16F,                                0,
668             GL_RED,                     GL_HALF_FLOAT_ARB,                0,
669             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
670             ARB_TEXTURE_RG,             NULL},
671     {WINED3DFMT_R16G16_FLOAT,           GL_RGB16F_ARB,                    GL_RGB16F_ARB,                          0,
672             GL_RGB,                     GL_HALF_FLOAT_ARB,                6,
673             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
674             ARB_TEXTURE_FLOAT,          convert_r16g16},
675     {WINED3DFMT_R16G16_FLOAT,           GL_RG16F,                         GL_RG16F,                               0,
676             GL_RG,                      GL_HALF_FLOAT_ARB,                0,
677             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
678             ARB_TEXTURE_RG,             NULL},
679     {WINED3DFMT_R16G16B16A16_FLOAT,     GL_RGBA16F_ARB,                   GL_RGBA16F_ARB,                         0,
680             GL_RGBA,                    GL_HALF_FLOAT_ARB,                0,
681             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET
682             | WINED3DFMT_FLAG_VTF,
683             ARB_TEXTURE_FLOAT,          NULL},
684     /* Palettized formats */
685     {WINED3DFMT_P8_UINT,                GL_RGBA,                          GL_RGBA,                                0,
686             GL_ALPHA,                   GL_UNSIGNED_BYTE,                 0,
687             0,
688             ARB_FRAGMENT_PROGRAM,       NULL},
689     {WINED3DFMT_P8_UINT,                GL_COLOR_INDEX8_EXT,              GL_COLOR_INDEX8_EXT,                    0,
690             GL_COLOR_INDEX,             GL_UNSIGNED_BYTE,                 0,
691             0,
692             EXT_PALETTED_TEXTURE,       NULL},
693     /* Standard ARGB formats */
694     {WINED3DFMT_B8G8R8_UNORM,           GL_RGB8,                          GL_RGB8,                                0,
695             GL_BGR,                     GL_UNSIGNED_BYTE,                 0,
696             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
697             WINED3D_GL_EXT_NONE,        NULL},
698     {WINED3DFMT_B8G8R8A8_UNORM,         GL_RGBA8,                         GL_SRGB8_ALPHA8_EXT,                    0,
699             GL_BGRA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      0,
700             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
701             | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE
702             | WINED3DFMT_FLAG_VTF,
703             WINED3D_GL_EXT_NONE,        NULL},
704     {WINED3DFMT_B8G8R8X8_UNORM,         GL_RGB8,                          GL_SRGB8_EXT,                           0,
705             GL_BGRA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      0,
706             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
707             | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
708             WINED3D_GL_EXT_NONE,        NULL},
709     {WINED3DFMT_B5G6R5_UNORM,           GL_RGB5,                          GL_RGB5,                          GL_RGB8,
710             GL_RGB,                     GL_UNSIGNED_SHORT_5_6_5,          0,
711             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
712             | WINED3DFMT_FLAG_RENDERTARGET,
713             WINED3D_GL_EXT_NONE,        NULL},
714     {WINED3DFMT_B5G5R5X1_UNORM,         GL_RGB5,                          GL_RGB5_A1,                             0,
715             GL_BGRA,                    GL_UNSIGNED_SHORT_1_5_5_5_REV,    0,
716             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
717             WINED3D_GL_EXT_NONE,        NULL},
718     {WINED3DFMT_B5G5R5A1_UNORM,         GL_RGB5_A1,                       GL_RGB5_A1,                             0,
719             GL_BGRA,                    GL_UNSIGNED_SHORT_1_5_5_5_REV,    0,
720             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
721             WINED3D_GL_EXT_NONE,        NULL},
722     {WINED3DFMT_B4G4R4A4_UNORM,         GL_RGBA4,                         GL_SRGB8_ALPHA8_EXT,                    0,
723             GL_BGRA,                    GL_UNSIGNED_SHORT_4_4_4_4_REV,    0,
724             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
725             | WINED3DFMT_FLAG_SRGB_READ,
726             WINED3D_GL_EXT_NONE,        NULL},
727     {WINED3DFMT_B2G3R3_UNORM,           GL_R3_G3_B2,                      GL_R3_G3_B2,                            0,
728             GL_RGB,                     GL_UNSIGNED_BYTE_3_3_2,           0,
729             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
730             WINED3D_GL_EXT_NONE,        NULL},
731     {WINED3DFMT_A8_UNORM,               GL_ALPHA8,                        GL_ALPHA8,                              0,
732             GL_ALPHA,                   GL_UNSIGNED_BYTE,                 0,
733             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
734             WINED3D_GL_EXT_NONE,        NULL},
735     {WINED3DFMT_B4G4R4X4_UNORM,         GL_RGB4,                          GL_RGB4,                                0,
736             GL_BGRA,                    GL_UNSIGNED_SHORT_4_4_4_4_REV,    0,
737             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
738             WINED3D_GL_EXT_NONE,        NULL},
739     {WINED3DFMT_R10G10B10A2_UNORM,      GL_RGB10_A2,                      GL_RGB10_A2,                            0,
740             GL_RGBA,                    GL_UNSIGNED_INT_2_10_10_10_REV,   0,
741             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
742             | WINED3DFMT_FLAG_RENDERTARGET,
743             WINED3D_GL_EXT_NONE,        NULL},
744     {WINED3DFMT_R8G8B8A8_UNORM,         GL_RGBA8,                         GL_RGBA8,                               0,
745             GL_RGBA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      0,
746             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
747             WINED3D_GL_EXT_NONE,        NULL},
748     {WINED3DFMT_R8G8B8X8_UNORM,         GL_RGB8,                          GL_RGB8,                                0,
749             GL_RGBA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      0,
750             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
751             WINED3D_GL_EXT_NONE,        NULL},
752     {WINED3DFMT_R16G16_UNORM,           GL_RGB16,                         GL_RGB16,                       GL_RGBA16,
753             GL_RGB,                     GL_UNSIGNED_SHORT,                6,
754             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
755             WINED3D_GL_EXT_NONE,        convert_r16g16},
756     {WINED3DFMT_R16G16_UNORM,           GL_RG16,                          GL_RG16,                                0,
757             GL_RG,                      GL_UNSIGNED_SHORT,                0,
758             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
759             | WINED3DFMT_FLAG_RENDERTARGET,
760             ARB_TEXTURE_RG,             NULL},
761     {WINED3DFMT_B10G10R10A2_UNORM,      GL_RGB10_A2,                      GL_RGB10_A2,                            0,
762             GL_BGRA,                    GL_UNSIGNED_INT_2_10_10_10_REV,   0,
763             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
764             | WINED3DFMT_FLAG_RENDERTARGET,
765             WINED3D_GL_EXT_NONE,        NULL},
766     {WINED3DFMT_R16G16B16A16_UNORM,     GL_RGBA16,                        GL_RGBA16,                              0,
767             GL_RGBA,                    GL_UNSIGNED_SHORT,                0,
768             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
769             | WINED3DFMT_FLAG_RENDERTARGET,
770             WINED3D_GL_EXT_NONE,        NULL},
771     /* Luminance */
772     {WINED3DFMT_L8_UNORM,               GL_LUMINANCE8,                    GL_SLUMINANCE8_EXT,                     0,
773             GL_LUMINANCE,               GL_UNSIGNED_BYTE,                 0,
774             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
775             | WINED3DFMT_FLAG_SRGB_READ,
776             WINED3D_GL_EXT_NONE,        NULL},
777     {WINED3DFMT_L8A8_UNORM,             GL_LUMINANCE8_ALPHA8,             GL_SLUMINANCE8_ALPHA8_EXT,              0,
778             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
779             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
780             | WINED3DFMT_FLAG_SRGB_READ,
781             WINED3D_GL_EXT_NONE,        NULL},
782     {WINED3DFMT_L4A4_UNORM,             GL_LUMINANCE4_ALPHA4,             GL_LUMINANCE4_ALPHA4,                   0,
783             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 2,
784             WINED3DFMT_FLAG_FILTERING,
785             WINED3D_GL_EXT_NONE,        convert_l4a4_unorm},
786     /* Bump mapping stuff */
787     {WINED3DFMT_R8G8_SNORM,             GL_RGB8,                          GL_RGB8,                                0,
788             GL_BGR,                     GL_UNSIGNED_BYTE,                 3,
789             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
790             | WINED3DFMT_FLAG_BUMPMAP,
791             WINED3D_GL_EXT_NONE,        convert_r8g8_snorm},
792     {WINED3DFMT_R8G8_SNORM,             GL_DSDT8_NV,                      GL_DSDT8_NV,                            0,
793             GL_DSDT_NV,                 GL_BYTE,                          0,
794             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
795             | WINED3DFMT_FLAG_BUMPMAP,
796             NV_TEXTURE_SHADER,          NULL},
797     {WINED3DFMT_R5G5_SNORM_L6_UNORM,    GL_RGB5,                          GL_RGB5,                                0,
798             GL_RGB,                     GL_UNSIGNED_SHORT_5_6_5,          2,
799             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
800             | WINED3DFMT_FLAG_BUMPMAP,
801             WINED3D_GL_EXT_NONE,        convert_r5g5_snorm_l6_unorm},
802     {WINED3DFMT_R5G5_SNORM_L6_UNORM,    GL_DSDT8_MAG8_NV,                 GL_DSDT8_MAG8_NV,                       0,
803             GL_DSDT_MAG_NV,             GL_BYTE,                          3,
804             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
805             | WINED3DFMT_FLAG_BUMPMAP,
806             NV_TEXTURE_SHADER,          convert_r5g5_snorm_l6_unorm_nv},
807     {WINED3DFMT_R8G8_SNORM_L8X8_UNORM,  GL_RGB8,                          GL_RGB8,                                0,
808             GL_BGRA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      4,
809             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
810             | WINED3DFMT_FLAG_BUMPMAP,
811             WINED3D_GL_EXT_NONE,        convert_r8g8_snorm_l8x8_unorm},
812     {WINED3DFMT_R8G8_SNORM_L8X8_UNORM,  GL_DSDT8_MAG8_INTENSITY8_NV,      GL_DSDT8_MAG8_INTENSITY8_NV,            0,
813             GL_DSDT_MAG_VIB_NV,         GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
814             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
815             | WINED3DFMT_FLAG_BUMPMAP,
816             NV_TEXTURE_SHADER,          convert_r8g8_snorm_l8x8_unorm_nv},
817     {WINED3DFMT_R8G8B8A8_SNORM,         GL_RGBA8,                         GL_RGBA8,                               0,
818             GL_BGRA,                    GL_UNSIGNED_BYTE,                 4,
819             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
820             | WINED3DFMT_FLAG_BUMPMAP,
821             WINED3D_GL_EXT_NONE,        convert_r8g8b8a8_snorm},
822     {WINED3DFMT_R8G8B8A8_SNORM,         GL_SIGNED_RGBA8_NV,               GL_SIGNED_RGBA8_NV,                     0,
823             GL_RGBA,                    GL_BYTE,                          0,
824             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
825             | WINED3DFMT_FLAG_BUMPMAP,
826             NV_TEXTURE_SHADER,          NULL},
827     {WINED3DFMT_R16G16_SNORM,           GL_RGB16,                         GL_RGB16,                               0,
828             GL_BGR,                     GL_UNSIGNED_SHORT,                6,
829             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
830             | WINED3DFMT_FLAG_BUMPMAP,
831             WINED3D_GL_EXT_NONE,        convert_r16g16_snorm},
832     {WINED3DFMT_R16G16_SNORM,           GL_SIGNED_HILO16_NV,              GL_SIGNED_HILO16_NV,                    0,
833             GL_HILO_NV,                 GL_SHORT,                         0,
834             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
835             | WINED3DFMT_FLAG_BUMPMAP,
836             NV_TEXTURE_SHADER,          NULL},
837     /* Depth stencil formats */
838     {WINED3DFMT_D16_LOCKABLE,           GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
839             GL_DEPTH_COMPONENT,         GL_UNSIGNED_SHORT,                0,
840             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
841             ARB_DEPTH_TEXTURE,          NULL},
842     {WINED3DFMT_D32_UNORM,              GL_DEPTH_COMPONENT32_ARB,         GL_DEPTH_COMPONENT32_ARB,               0,
843             GL_DEPTH_COMPONENT,         GL_UNSIGNED_INT,                  0,
844             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
845             ARB_DEPTH_TEXTURE,          NULL},
846     {WINED3DFMT_S1_UINT_D15_UNORM,      GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
847             GL_DEPTH_COMPONENT,         GL_UNSIGNED_SHORT,                0,
848             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
849             ARB_DEPTH_TEXTURE,          NULL},
850     {WINED3DFMT_S1_UINT_D15_UNORM,      GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
851             GL_DEPTH_STENCIL_EXT,       GL_UNSIGNED_INT_24_8_EXT,         4,
852             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
853             EXT_PACKED_DEPTH_STENCIL,   convert_s1_uint_d15_unorm},
854     {WINED3DFMT_S1_UINT_D15_UNORM,      GL_DEPTH24_STENCIL8,              GL_DEPTH24_STENCIL8,                    0,
855             GL_DEPTH_STENCIL,           GL_UNSIGNED_INT_24_8,             4,
856             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
857             ARB_FRAMEBUFFER_OBJECT,     convert_s1_uint_d15_unorm},
858     {WINED3DFMT_D24_UNORM_S8_UINT,      GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
859             GL_DEPTH_COMPONENT,         GL_UNSIGNED_INT,                  0,
860             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
861             | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
862             ARB_DEPTH_TEXTURE,          NULL},
863     {WINED3DFMT_D24_UNORM_S8_UINT,      GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
864             GL_DEPTH_STENCIL_EXT,       GL_UNSIGNED_INT_24_8_EXT,         0,
865             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
866             | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
867             EXT_PACKED_DEPTH_STENCIL,   NULL},
868     {WINED3DFMT_D24_UNORM_S8_UINT,      GL_DEPTH24_STENCIL8,              GL_DEPTH24_STENCIL8,                    0,
869             GL_DEPTH_STENCIL,           GL_UNSIGNED_INT_24_8,             0,
870             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
871             | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
872             ARB_FRAMEBUFFER_OBJECT,     NULL},
873     {WINED3DFMT_X8D24_UNORM,            GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
874             GL_DEPTH_COMPONENT,         GL_UNSIGNED_INT,                  0,
875             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
876             | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
877             ARB_DEPTH_TEXTURE,          NULL},
878     {WINED3DFMT_S4X4_UINT_D24_UNORM,    GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
879             GL_DEPTH_COMPONENT,         GL_UNSIGNED_INT,                  0,
880             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
881             ARB_DEPTH_TEXTURE,          NULL},
882     {WINED3DFMT_S4X4_UINT_D24_UNORM,    GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
883             GL_DEPTH_STENCIL_EXT,       GL_UNSIGNED_INT_24_8_EXT,         4,
884             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
885             EXT_PACKED_DEPTH_STENCIL,   convert_s4x4_uint_d24_unorm},
886     {WINED3DFMT_S4X4_UINT_D24_UNORM,    GL_DEPTH24_STENCIL8,              GL_DEPTH24_STENCIL8,                    0,
887             GL_DEPTH_STENCIL,           GL_UNSIGNED_INT_24_8,             4,
888             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
889             ARB_FRAMEBUFFER_OBJECT,     convert_s4x4_uint_d24_unorm},
890     {WINED3DFMT_D16_UNORM,              GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
891             GL_DEPTH_COMPONENT,         GL_UNSIGNED_SHORT,                0,
892             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
893             | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
894             ARB_DEPTH_TEXTURE,          NULL},
895     {WINED3DFMT_L16_UNORM,              GL_LUMINANCE16,                   GL_LUMINANCE16,                         0,
896             GL_LUMINANCE,               GL_UNSIGNED_SHORT,                0,
897             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
898             WINED3D_GL_EXT_NONE,        NULL},
899     {WINED3DFMT_D32_FLOAT,              GL_DEPTH_COMPONENT32F,            GL_DEPTH_COMPONENT32F,                  0,
900             GL_DEPTH_COMPONENT,         GL_FLOAT,                         0,
901             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
902             ARB_DEPTH_BUFFER_FLOAT,     NULL},
903     {WINED3DFMT_S8_UINT_D24_FLOAT,      GL_DEPTH32F_STENCIL8,             GL_DEPTH32F_STENCIL8,                   0,
904             GL_DEPTH_STENCIL,           GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
905             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
906             ARB_DEPTH_BUFFER_FLOAT,     convert_s8_uint_d24_float},
907     /* Vendor-specific formats */
908     {WINED3DFMT_ATI2N,                  GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
909             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
910             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
911             | WINED3DFMT_FLAG_COMPRESSED,
912             ATI_TEXTURE_COMPRESSION_3DC, NULL},
913     {WINED3DFMT_ATI2N,                  GL_COMPRESSED_RG_RGTC2,           GL_COMPRESSED_RG_RGTC2,                 0,
914             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
915             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
916             | WINED3DFMT_FLAG_COMPRESSED,
917             ARB_TEXTURE_COMPRESSION_RGTC, NULL},
918     {WINED3DFMT_INTZ,                   GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
919             GL_DEPTH_STENCIL_EXT,       GL_UNSIGNED_INT_24_8_EXT,         0,
920             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
921             | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
922             EXT_PACKED_DEPTH_STENCIL,   NULL},
923     {WINED3DFMT_INTZ,                   GL_DEPTH24_STENCIL8,              GL_DEPTH24_STENCIL8,                    0,
924             GL_DEPTH_STENCIL,           GL_UNSIGNED_INT_24_8,             0,
925             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
926             | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
927             ARB_FRAMEBUFFER_OBJECT,     NULL},
928     {WINED3DFMT_NULL,                   GL_RGBA8,                         GL_RGBA8,                               0,
929             GL_RGBA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      0,
930             WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET,
931             ARB_FRAMEBUFFER_OBJECT,     NULL},
932 };
933
934 static inline int getFmtIdx(enum wined3d_format_id format_id)
935 {
936     /* First check if the format is at the position of its value.
937      * This will catch the argb formats before the loop is entered. */
938     if (format_id < (sizeof(formats) / sizeof(*formats))
939             && formats[format_id].id == format_id)
940     {
941         return format_id;
942     }
943     else
944     {
945         unsigned int i;
946
947         for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
948         {
949             if (formats[i].id == format_id) return i;
950         }
951     }
952     return -1;
953 }
954
955 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
956 {
957     UINT format_count = sizeof(formats) / sizeof(*formats);
958     UINT i;
959
960     gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
961     if (!gl_info->formats)
962     {
963         ERR("Failed to allocate memory.\n");
964         return FALSE;
965     }
966
967     for (i = 0; i < format_count; ++i)
968     {
969         struct wined3d_format *format = &gl_info->formats[i];
970         format->id = formats[i].id;
971         format->red_size = formats[i].red_size;
972         format->green_size = formats[i].green_size;
973         format->blue_size = formats[i].blue_size;
974         format->alpha_size = formats[i].alpha_size;
975         format->red_offset = formats[i].red_offset;
976         format->green_offset = formats[i].green_offset;
977         format->blue_offset = formats[i].blue_offset;
978         format->alpha_offset = formats[i].alpha_offset;
979         format->byte_count = formats[i].bpp;
980         format->depth_size = formats[i].depth_size;
981         format->stencil_size = formats[i].stencil_size;
982         format->block_width = 1;
983         format->block_height = 1;
984         format->block_byte_count = formats[i].bpp;
985     }
986
987     for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
988     {
989         int fmt_idx = getFmtIdx(format_base_flags[i].id);
990
991         if (fmt_idx == -1)
992         {
993             ERR("Format %s (%#x) not found.\n",
994                     debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
995             HeapFree(GetProcessHeap(), 0, gl_info->formats);
996             return FALSE;
997         }
998
999         gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
1000     }
1001
1002     return TRUE;
1003 }
1004
1005 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
1006 {
1007     unsigned int i;
1008
1009     for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i)
1010     {
1011         struct wined3d_format *format;
1012         int fmt_idx = getFmtIdx(format_block_info[i].id);
1013
1014         if (fmt_idx == -1)
1015         {
1016             ERR("Format %s (%#x) not found.\n",
1017                     debug_d3dformat(format_block_info[i].id), format_block_info[i].id);
1018             return FALSE;
1019         }
1020
1021         format = &gl_info->formats[fmt_idx];
1022         format->block_width = format_block_info[i].block_width;
1023         format->block_height = format_block_info[i].block_height;
1024         format->block_byte_count = format_block_info[i].block_byte_count;
1025         format->flags |= WINED3DFMT_FLAG_BLOCKS;
1026     }
1027
1028     return TRUE;
1029 }
1030
1031 /* Context activation is done by the caller. */
1032 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
1033 {
1034     /* Check if the default internal format is supported as a frame buffer
1035      * target, otherwise fall back to the render target internal.
1036      *
1037      * Try to stick to the standard format if possible, this limits precision differences. */
1038     GLenum status;
1039     GLuint tex;
1040
1041     while (gl_info->gl_ops.gl.p_glGetError());
1042     gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1043
1044     gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1045     gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1046
1047     gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0,
1048             format->glFormat, format->glType, NULL);
1049     gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1050     gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1051
1052     gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1053
1054     status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1055     checkGLcall("Framebuffer format check");
1056
1057     if (status == GL_FRAMEBUFFER_COMPLETE)
1058     {
1059         TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1060         format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1061         format->rtInternal = format->glInternal;
1062     }
1063     else
1064     {
1065         if (!format->rtInternal)
1066         {
1067             if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1068             {
1069                 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1070                         " and no fallback specified.\n", debug_d3dformat(format->id));
1071                 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1072             }
1073             else
1074             {
1075                 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1076             }
1077             format->rtInternal = format->glInternal;
1078         }
1079         else
1080         {
1081             TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1082                     debug_d3dformat(format->id));
1083
1084             while (gl_info->gl_ops.gl.p_glGetError());
1085
1086             gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1087
1088             gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0,
1089                     format->glFormat, format->glType, NULL);
1090             gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1091             gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1092
1093             gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1094
1095             status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1096             checkGLcall("Framebuffer format check");
1097
1098             if (status == GL_FRAMEBUFFER_COMPLETE)
1099             {
1100                 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1101                         debug_d3dformat(format->id));
1102             }
1103             else
1104             {
1105                 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1106                         debug_d3dformat(format->id));
1107                 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1108             }
1109         }
1110     }
1111
1112     if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1113             || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1114             && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
1115             && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA
1116             && (format->red_size || format->alpha_size))
1117     {
1118         DWORD readback[16 * 16], color, r_range, a_range;
1119         BYTE r, a;
1120         BOOL match = TRUE;
1121         GLuint rb;
1122
1123         if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1124                 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1125         {
1126             gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1127             gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1128             gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1129             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1130             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1131             checkGLcall("RB attachment");
1132         }
1133
1134         gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1135         gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1136         gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1137         if (gl_info->gl_ops.gl.p_glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1138         {
1139             while (gl_info->gl_ops.gl.p_glGetError());
1140             TRACE("Format doesn't support post-pixelshader blending.\n");
1141             format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1142         }
1143         else
1144         {
1145             gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1146             gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16);
1147             gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1148             gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1149             gl_info->gl_ops.gl.p_glLoadIdentity();
1150             gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1151             gl_info->gl_ops.gl.p_glLoadIdentity();
1152
1153             gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1154
1155             /* Draw a full-black quad */
1156             gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1157             gl_info->gl_ops.gl.p_glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
1158             gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1159             gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1160             gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1161             gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1162             gl_info->gl_ops.gl.p_glEnd();
1163
1164             gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1165             /* Draw a half-transparent red quad */
1166             gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1167             gl_info->gl_ops.gl.p_glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
1168             gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1169             gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1170             gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1171             gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1172             gl_info->gl_ops.gl.p_glEnd();
1173
1174             gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1175
1176             /* Rebinding texture to workaround a fglrx bug. */
1177             gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1178             gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1179             checkGLcall("Post-pixelshader blending check");
1180
1181             color = readback[7 * 16 + 7];
1182             a = color >> 24;
1183             r = (color & 0x00ff0000) >> 16;
1184
1185             r_range = format->red_size < 8 ? 1 << (8 - format->red_size) : 1;
1186             a_range = format->alpha_size < 8 ? 1 << (8 - format->alpha_size) : 1;
1187             if (format->red_size && (r < 0x7f - r_range || r > 0x7f + r_range))
1188                 match = FALSE;
1189             else if (format->alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range))
1190                 match = FALSE;
1191             if (!match)
1192             {
1193                 TRACE("Format doesn't support post-pixelshader blending.\n");
1194                 TRACE("Color output: %#x\n", color);
1195                 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1196             }
1197             else
1198             {
1199                 TRACE("Format supports post-pixelshader blending.\n");
1200                 TRACE("Color output: %#x\n", color);
1201                 format->flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1202             }
1203         }
1204
1205         if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1206                 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1207         {
1208             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1209             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1210             gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1211             checkGLcall("RB cleanup");
1212         }
1213     }
1214
1215     if (format->glInternal != format->glGammaInternal)
1216     {
1217         gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0,
1218                 format->glFormat, format->glType, NULL);
1219         gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1220
1221         status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1222         checkGLcall("Framebuffer format check");
1223
1224         if (status == GL_FRAMEBUFFER_COMPLETE)
1225         {
1226             TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1227             format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1228         }
1229         else
1230         {
1231             WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1232         }
1233     }
1234     else if (status == GL_FRAMEBUFFER_COMPLETE)
1235         format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1236
1237     gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1238 }
1239
1240 /* Context activation is done by the caller. */
1241 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1242 {
1243     unsigned int i;
1244     GLuint fbo;
1245
1246     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1247     {
1248         gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1249         gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1250         gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1251         gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0);
1252     }
1253
1254     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1255     {
1256         struct wined3d_format *format = &gl_info->formats[i];
1257
1258         if (!format->glInternal) continue;
1259
1260         if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1261         {
1262             TRACE("Skipping format %s because it's a depth/stencil format.\n",
1263                     debug_d3dformat(format->id));
1264             continue;
1265         }
1266
1267         if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1268         {
1269             TRACE("Skipping format %s because it's a compressed format.\n",
1270                     debug_d3dformat(format->id));
1271             continue;
1272         }
1273
1274         if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1275         {
1276             TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1277             check_fbo_compat(gl_info, format);
1278         }
1279         else
1280         {
1281             format->rtInternal = format->glInternal;
1282         }
1283     }
1284
1285     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1286         gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1287 }
1288
1289 static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1290 {
1291     struct fragment_caps fragment_caps;
1292     struct shader_caps shader_caps;
1293     BOOL srgb_write;
1294     unsigned int i;
1295
1296     adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
1297     adapter->shader_backend->shader_get_caps(gl_info, &shader_caps);
1298     srgb_write = (fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_SRGB_WRITE)
1299             && (shader_caps.wined3d_caps & WINED3D_SHADER_CAP_SRGB_WRITE);
1300
1301     for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1302     {
1303         int fmt_idx = getFmtIdx(format_texture_info[i].id);
1304         struct wined3d_format *format;
1305
1306         if (fmt_idx == -1)
1307         {
1308             ERR("Format %s (%#x) not found.\n",
1309                     debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1310             return FALSE;
1311         }
1312
1313         if (!gl_info->supported[format_texture_info[i].extension]) continue;
1314
1315         format = &gl_info->formats[fmt_idx];
1316
1317         /* ARB_texture_rg defines floating point formats, but only if
1318          * ARB_texture_float is also supported. */
1319         if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1320                 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1321             continue;
1322
1323         format->glInternal = format_texture_info[i].gl_internal;
1324         format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1325         format->rtInternal = format_texture_info[i].gl_rt_internal;
1326         format->glFormat = format_texture_info[i].gl_format;
1327         format->glType = format_texture_info[i].gl_type;
1328         format->color_fixup = COLOR_FIXUP_IDENTITY;
1329         format->flags |= format_texture_info[i].flags;
1330         format->height_scale.numerator = 1;
1331         format->height_scale.denominator = 1;
1332
1333         if (!gl_info->limits.vertex_samplers)
1334             format->flags &= ~WINED3DFMT_FLAG_VTF;
1335
1336         if (!(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1337             format->flags |= WINED3DFMT_FLAG_FILTERING;
1338         else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT)
1339             format->flags &= ~WINED3DFMT_FLAG_VTF;
1340
1341         if (format->glGammaInternal != format->glInternal)
1342         {
1343             /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1344             if (!gl_info->supported[EXT_TEXTURE_SRGB])
1345             {
1346                 format->glGammaInternal = format->glInternal;
1347                 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1348             }
1349             else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1350             {
1351                 format->glInternal = format->glGammaInternal;
1352             }
1353         }
1354
1355         if ((format->flags & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write)
1356             format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
1357
1358         /* Texture conversion stuff */
1359         format->convert = format_texture_info[i].convert;
1360         format->conv_byte_count = format_texture_info[i].conv_byte_count;
1361     }
1362
1363     return TRUE;
1364 }
1365
1366 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1367 {
1368     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1369     c1 >>= 8; c2 >>= 8;
1370     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1371     c1 >>= 8; c2 >>= 8;
1372     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1373     c1 >>= 8; c2 >>= 8;
1374     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1375     return TRUE;
1376 }
1377
1378 /* A context is provided by the caller */
1379 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1380 {
1381     static const DWORD data[] = {0x00000000, 0xffffffff};
1382     GLuint tex, fbo, buffer;
1383     DWORD readback[16 * 1];
1384     BOOL ret = FALSE;
1385
1386     /* Render a filtered texture and see what happens. This is intended to detect the lack of
1387      * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1388      * falling back to software. If this changes in the future this code will get fooled and
1389      * apps might hit the software path due to incorrectly advertised caps.
1390      *
1391      * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1392      * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1393      * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1394      */
1395
1396     while (gl_info->gl_ops.gl.p_glGetError());
1397
1398     gl_info->gl_ops.gl.p_glGenTextures(1, &buffer);
1399     gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1400     memset(readback, 0x7e, sizeof(readback));
1401     gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0,
1402             GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1403     gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1404     gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1405     gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1406     gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1407     gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1408
1409     gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1410     gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1411     gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0,
1412             GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1413     gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1414     gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1415     gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1416     gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1417     gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1418     gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
1419
1420     gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1421     gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1422     gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1423     gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1424
1425     gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1);
1426     gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1427     gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1428     gl_info->gl_ops.gl.p_glLoadIdentity();
1429     gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1430     gl_info->gl_ops.gl.p_glLoadIdentity();
1431
1432     gl_info->gl_ops.gl.p_glClearColor(0, 1, 0, 0);
1433     gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1434
1435     gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1436     gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 0.0);
1437     gl_info->gl_ops.gl.p_glVertex2f(-1.0f, -1.0f);
1438     gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 0.0);
1439     gl_info->gl_ops.gl.p_glVertex2f(1.0f, -1.0f);
1440     gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 1.0);
1441     gl_info->gl_ops.gl.p_glVertex2f(-1.0f, 1.0f);
1442     gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 1.0);
1443     gl_info->gl_ops.gl.p_glVertex2f(1.0f, 1.0f);
1444     gl_info->gl_ops.gl.p_glEnd();
1445
1446     gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1447     memset(readback, 0x7f, sizeof(readback));
1448     gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1449     if (color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5)
1450             || color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1451     {
1452         TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, assuming no filtering\n",
1453               readback[6], readback[9]);
1454         ret = FALSE;
1455     }
1456     else
1457     {
1458         TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1459               readback[6], readback[9]);
1460         ret = TRUE;
1461     }
1462
1463     gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1464     gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1465     gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1466     gl_info->gl_ops.gl.p_glDeleteTextures(1, &buffer);
1467
1468     if (gl_info->gl_ops.gl.p_glGetError())
1469     {
1470         FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1471         ret = FALSE;
1472     }
1473
1474     return ret;
1475 }
1476
1477 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1478 {
1479     struct wined3d_format *format;
1480     unsigned int fmt_idx, i;
1481     static const enum wined3d_format_id fmts16[] =
1482     {
1483         WINED3DFMT_R16_FLOAT,
1484         WINED3DFMT_R16G16_FLOAT,
1485         WINED3DFMT_R16G16B16A16_FLOAT,
1486     };
1487     BOOL filtered;
1488
1489     if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1490     {
1491         WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1492         if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1493         {
1494             TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1495             filtered = TRUE;
1496         }
1497         else if (gl_info->limits.glsl_varyings > 44)
1498         {
1499             TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1500             filtered = TRUE;
1501         }
1502         else
1503         {
1504             TRACE("Assuming no float16 blending\n");
1505             filtered = FALSE;
1506         }
1507
1508         if(filtered)
1509         {
1510             for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1511             {
1512                 fmt_idx = getFmtIdx(fmts16[i]);
1513                 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1514             }
1515         }
1516         return;
1517     }
1518
1519     for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1520     {
1521         fmt_idx = getFmtIdx(fmts16[i]);
1522         format = &gl_info->formats[fmt_idx];
1523         if (!format->glInternal) continue; /* Not supported by GL */
1524
1525         filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1526         if(filtered)
1527         {
1528             TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1529             format->flags |= WINED3DFMT_FLAG_FILTERING;
1530         }
1531         else
1532         {
1533             TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1534         }
1535     }
1536 }
1537
1538 static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1539 {
1540     unsigned int i;
1541     int idx;
1542
1543     idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1544     gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1545             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1546
1547     idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1548     gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1549             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1550
1551     idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1552     gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1553             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1554
1555     idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1556     gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1557             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1558
1559     idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1560     gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1561             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1562
1563     /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1564      * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1565      * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1566      * the only driver that implements it(fglrx) has a buggy implementation.
1567      *
1568      * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1569      * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1570      * conversion for this format.
1571      */
1572     if (!gl_info->supported[NV_TEXTURE_SHADER])
1573     {
1574         idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1575         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1576                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1577         idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1578         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1579                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1580     }
1581     else
1582     {
1583         idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1584         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1585                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1586
1587         idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1588         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1589                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1590     }
1591
1592     if (!gl_info->supported[NV_TEXTURE_SHADER])
1593     {
1594         /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1595          * with each other
1596          */
1597         idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1598         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1599                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1600         idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1601         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1602                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1603         idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1604         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1605                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1606     }
1607     else
1608     {
1609         /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1610          * are converted at surface loading time, but they do not need any modification in
1611          * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1612          * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1613          */
1614     }
1615
1616     if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1617     {
1618         idx = getFmtIdx(WINED3DFMT_ATI2N);
1619         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1620                 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1621     }
1622     else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1623     {
1624         idx = getFmtIdx(WINED3DFMT_ATI2N);
1625         gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1626                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1627     }
1628
1629     if (!gl_info->supported[APPLE_YCBCR_422])
1630     {
1631         idx = getFmtIdx(WINED3DFMT_YUY2);
1632         gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1633
1634         idx = getFmtIdx(WINED3DFMT_UYVY);
1635         gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1636     }
1637
1638     idx = getFmtIdx(WINED3DFMT_YV12);
1639     gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
1640     gl_info->formats[idx].height_scale.numerator = 3;
1641     gl_info->formats[idx].height_scale.denominator = 2;
1642     gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1643
1644     if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1645     {
1646         idx = getFmtIdx(WINED3DFMT_P8_UINT);
1647         gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1648     }
1649
1650     if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1651     {
1652         idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1653         gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1654     }
1655
1656     if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1657     {
1658         /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1659          * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1660         idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1661         gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1662
1663         idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1664         gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1665     }
1666
1667     if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
1668     {
1669         idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1670         gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1671
1672         idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1673         gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1674
1675         idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1676         gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1677     }
1678
1679     if (gl_info->quirks & WINED3D_QUIRK_BROKEN_RGBA16)
1680     {
1681         idx = getFmtIdx(WINED3DFMT_R16G16B16A16_UNORM);
1682         gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1683     }
1684
1685     /* ATI instancing hack: Although ATI cards do not support Shader Model
1686      * 3.0, they support instancing. To query if the card supports instancing
1687      * CheckDeviceFormat() with the special format MAKEFOURCC('I','N','S','T')
1688      * is used. Should an application check for this, provide a proper return
1689      * value. We can do instancing with all shader versions, but we need
1690      * vertex shaders.
1691      *
1692      * Additionally applications have to set the D3DRS_POINTSIZE render state
1693      * to MAKEFOURCC('I','N','S','T') once to enable instancing. Wined3d
1694      * doesn't need that and just ignores it.
1695      *
1696      * With Shader Model 3.0 capable cards Instancing 'just works' in Windows. */
1697     /* FIXME: This should just check the shader backend caps. */
1698     if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
1699     {
1700         idx = getFmtIdx(WINED3DFMT_INST);
1701         gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
1702     }
1703
1704     /* Depth bound test. To query if the card supports it CheckDeviceFormat()
1705      * with the special format MAKEFOURCC('N','V','D','B') is used. It is
1706      * enabled by setting D3DRS_ADAPTIVETESS_X render state to
1707      * MAKEFOURCC('N','V','D','B') and then controlled by setting
1708      * D3DRS_ADAPTIVETESS_Z (zMin) and D3DRS_ADAPTIVETESS_W (zMax) to test
1709      * value. */
1710     if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST])
1711     {
1712         idx = getFmtIdx(WINED3DFMT_NVDB);
1713         gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
1714     }
1715
1716     /* RESZ aka AMD DX9-level hack for multisampled depth buffer resolve. You query for RESZ
1717      * support by checking for availability of MAKEFOURCC('R','E','S','Z') surfaces with
1718      * RENDERTARGET usage. */
1719     if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
1720     {
1721         idx = getFmtIdx(WINED3DFMT_RESZ);
1722         gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET;
1723     }
1724
1725     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1726     {
1727         struct wined3d_format *format = &gl_info->formats[idx];
1728
1729         if (!(format->flags & WINED3DFMT_FLAG_TEXTURE))
1730             continue;
1731
1732         if (!adapter->shader_backend->shader_color_fixup_supported(format->color_fixup)
1733                 || !adapter->fragment_pipe->color_fixup_supported(format->color_fixup))
1734             format->flags &= ~WINED3DFMT_FLAG_TEXTURE;
1735     }
1736 }
1737
1738 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1739 {
1740     unsigned int i;
1741
1742     for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1743     {
1744         struct wined3d_format *format;
1745         int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1746
1747         if (fmt_idx == -1)
1748         {
1749             ERR("Format %s (%#x) not found.\n",
1750                     debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1751             return FALSE;
1752         }
1753
1754         format = &gl_info->formats[fmt_idx];
1755         format->emit_idx = format_vertex_info[i].emit_idx;
1756         format->component_count = format_vertex_info[i].component_count;
1757         format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1758         format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1759         format->gl_normalized = format_vertex_info[i].gl_normalized;
1760         format->component_size = format_vertex_info[i].component_size;
1761     }
1762
1763     return TRUE;
1764 }
1765
1766 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1767 {
1768     if (!init_format_base_info(gl_info)) return FALSE;
1769
1770     if (!init_format_block_info(gl_info))
1771     {
1772         HeapFree(GetProcessHeap(), 0, gl_info->formats);
1773         gl_info->formats = NULL;
1774         return FALSE;
1775     }
1776
1777     return TRUE;
1778 }
1779
1780 /* Context activation is done by the caller. */
1781 BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter)
1782 {
1783     struct wined3d_gl_info *gl_info = &adapter->gl_info;
1784
1785     if (!init_format_base_info(gl_info)) return FALSE;
1786
1787     if (!init_format_block_info(gl_info)) goto fail;
1788     if (!init_format_texture_info(adapter, gl_info)) goto fail;
1789     if (!init_format_vertex_info(gl_info)) goto fail;
1790
1791     apply_format_fixups(adapter, gl_info);
1792     init_format_fbo_compat_info(gl_info);
1793     init_format_filter_info(gl_info, adapter->driver_info.vendor);
1794
1795     return TRUE;
1796
1797 fail:
1798     HeapFree(GetProcessHeap(), 0, gl_info->formats);
1799     gl_info->formats = NULL;
1800     return FALSE;
1801 }
1802
1803 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1804         enum wined3d_format_id format_id)
1805 {
1806     int idx = getFmtIdx(format_id);
1807
1808     if (idx == -1)
1809     {
1810         FIXME("Can't find format %s (%#x) in the format lookup table\n",
1811                 debug_d3dformat(format_id), format_id);
1812         /* Get the caller a valid pointer */
1813         idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1814     }
1815
1816     return &gl_info->formats[idx];
1817 }
1818
1819 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1820 {
1821     UINT size;
1822
1823     if (format->id == WINED3DFMT_UNKNOWN)
1824     {
1825         size = 0;
1826     }
1827     else if (format->flags & WINED3DFMT_FLAG_BLOCKS)
1828     {
1829         UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1830         UINT row_count = (height + format->block_height - 1) / format->block_height;
1831         size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1832     }
1833     else
1834     {
1835         size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1836     }
1837
1838     if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
1839     {
1840         /* The D3D format requirements make sure that the resulting format is an integer again */
1841         size *= format->height_scale.numerator;
1842         size /= format->height_scale.denominator;
1843     }
1844
1845     return size;
1846 }
1847
1848 /*****************************************************************************
1849  * Trace formatting of useful values
1850  */
1851 const char *debug_d3dformat(enum wined3d_format_id format_id)
1852 {
1853     switch (format_id)
1854     {
1855 #define FMT_TO_STR(format_id) case format_id: return #format_id
1856         FMT_TO_STR(WINED3DFMT_UNKNOWN);
1857         FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1858         FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1859         FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1860         FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1861         FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1862         FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1863         FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1864         FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1865         FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1866         FMT_TO_STR(WINED3DFMT_P8_UINT);
1867         FMT_TO_STR(WINED3DFMT_L8_UNORM);
1868         FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1869         FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1870         FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1871         FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1872         FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1873         FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1874         FMT_TO_STR(WINED3DFMT_UYVY);
1875         FMT_TO_STR(WINED3DFMT_YUY2);
1876         FMT_TO_STR(WINED3DFMT_YV12);
1877         FMT_TO_STR(WINED3DFMT_DXT1);
1878         FMT_TO_STR(WINED3DFMT_DXT2);
1879         FMT_TO_STR(WINED3DFMT_DXT3);
1880         FMT_TO_STR(WINED3DFMT_DXT4);
1881         FMT_TO_STR(WINED3DFMT_DXT5);
1882         FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1883         FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1884         FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1885         FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1886         FMT_TO_STR(WINED3DFMT_D32_UNORM);
1887         FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1888         FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1889         FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1890         FMT_TO_STR(WINED3DFMT_L16_UNORM);
1891         FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1892         FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1893         FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1894         FMT_TO_STR(WINED3DFMT_ATI2N);
1895         FMT_TO_STR(WINED3DFMT_NVDB);
1896         FMT_TO_STR(WINED3DFMT_NVHU);
1897         FMT_TO_STR(WINED3DFMT_NVHS);
1898         FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1899         FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1900         FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1901         FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1902         FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1903         FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1904         FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1905         FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1906         FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1907         FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1908         FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1909         FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1910         FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1911         FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1912         FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1913         FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1914         FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1915         FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1916         FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1917         FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1918         FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1919         FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1920         FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1921         FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1922         FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1923         FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1924         FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1925         FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1926         FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1927         FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1928         FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1929         FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1930         FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1931         FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1932         FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1933         FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1934         FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1935         FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1936         FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1937         FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1938         FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1939         FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1940         FMT_TO_STR(WINED3DFMT_R32_UINT);
1941         FMT_TO_STR(WINED3DFMT_R32_SINT);
1942         FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1943         FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1944         FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1945         FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1946         FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1947         FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1948         FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1949         FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1950         FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1951         FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1952         FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1953         FMT_TO_STR(WINED3DFMT_D16_UNORM);
1954         FMT_TO_STR(WINED3DFMT_R16_UNORM);
1955         FMT_TO_STR(WINED3DFMT_R16_UINT);
1956         FMT_TO_STR(WINED3DFMT_R16_SNORM);
1957         FMT_TO_STR(WINED3DFMT_R16_SINT);
1958         FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1959         FMT_TO_STR(WINED3DFMT_R8_UNORM);
1960         FMT_TO_STR(WINED3DFMT_R8_UINT);
1961         FMT_TO_STR(WINED3DFMT_R8_SNORM);
1962         FMT_TO_STR(WINED3DFMT_R8_SINT);
1963         FMT_TO_STR(WINED3DFMT_A8_UNORM);
1964         FMT_TO_STR(WINED3DFMT_R1_UNORM);
1965         FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1966         FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1967         FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1968         FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1969         FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1970         FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1971         FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1972         FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1973         FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1974         FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1975         FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1976         FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1977         FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1978         FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1979         FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1980         FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1981         FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1982         FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1983         FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1984         FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1985         FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1986         FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1987         FMT_TO_STR(WINED3DFMT_INTZ);
1988         FMT_TO_STR(WINED3DFMT_RESZ);
1989         FMT_TO_STR(WINED3DFMT_NULL);
1990         FMT_TO_STR(WINED3DFMT_R16);
1991         FMT_TO_STR(WINED3DFMT_AL16);
1992 #undef FMT_TO_STR
1993         default:
1994         {
1995             char fourcc[5];
1996             fourcc[0] = (char)(format_id);
1997             fourcc[1] = (char)(format_id >> 8);
1998             fourcc[2] = (char)(format_id >> 16);
1999             fourcc[3] = (char)(format_id >> 24);
2000             fourcc[4] = 0;
2001             if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
2002                 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
2003             else
2004                 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
2005         }
2006         return "unrecognized";
2007     }
2008 }
2009
2010 const char *debug_d3ddevicetype(enum wined3d_device_type device_type)
2011 {
2012     switch (device_type)
2013     {
2014 #define DEVTYPE_TO_STR(dev) case dev: return #dev
2015         DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_HAL);
2016         DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_REF);
2017         DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_SW);
2018 #undef DEVTYPE_TO_STR
2019         default:
2020             FIXME("Unrecognized device type %#x.\n", device_type);
2021             return "unrecognized";
2022     }
2023 }
2024
2025 const char *debug_d3dusage(DWORD usage)
2026 {
2027     char buf[333];
2028
2029     buf[0] = '\0';
2030 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
2031     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
2032     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
2033     WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
2034     WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
2035     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
2036     WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
2037     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
2038     WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
2039     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
2040     WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
2041     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
2042     WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
2043     WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
2044 #undef WINED3DUSAGE_TO_STR
2045     if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
2046
2047     return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2048 }
2049
2050 const char *debug_d3dusagequery(DWORD usagequery)
2051 {
2052     char buf[238];
2053
2054     buf[0] = '\0';
2055 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
2056     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
2057     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
2058     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
2059     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
2060     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
2061     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
2062     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
2063 #undef WINED3DUSAGEQUERY_TO_STR
2064     if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
2065
2066     return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2067 }
2068
2069 const char *debug_d3ddeclmethod(enum wined3d_decl_method method)
2070 {
2071     switch (method)
2072     {
2073 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
2074         WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_DEFAULT);
2075         WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_U);
2076         WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_V);
2077         WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_CROSS_UV);
2078         WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_UV);
2079         WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP);
2080         WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP_PRESAMPLED);
2081 #undef WINED3DDECLMETHOD_TO_STR
2082         default:
2083             FIXME("Unrecognized declaration method %#x.\n", method);
2084             return "unrecognized";
2085     }
2086 }
2087
2088 const char *debug_d3ddeclusage(enum wined3d_decl_usage usage)
2089 {
2090     switch (usage)
2091     {
2092 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
2093         WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITION);
2094         WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_WEIGHT);
2095         WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_INDICES);
2096         WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_NORMAL);
2097         WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_PSIZE);
2098         WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TEXCOORD);
2099         WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TANGENT);
2100         WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BINORMAL);
2101         WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TESS_FACTOR);
2102         WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITIONT);
2103         WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_COLOR);
2104         WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_FOG);
2105         WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_DEPTH);
2106         WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_SAMPLE);
2107 #undef WINED3DDECLUSAGE_TO_STR
2108         default:
2109             FIXME("Unrecognized %u declaration usage!\n", usage);
2110             return "unrecognized";
2111     }
2112 }
2113
2114 const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
2115 {
2116     switch (resource_type)
2117     {
2118 #define RES_TO_STR(res) case res: return #res
2119         RES_TO_STR(WINED3D_RTYPE_SURFACE);
2120         RES_TO_STR(WINED3D_RTYPE_VOLUME);
2121         RES_TO_STR(WINED3D_RTYPE_TEXTURE);
2122         RES_TO_STR(WINED3D_RTYPE_VOLUME_TEXTURE);
2123         RES_TO_STR(WINED3D_RTYPE_CUBE_TEXTURE);
2124         RES_TO_STR(WINED3D_RTYPE_BUFFER);
2125 #undef  RES_TO_STR
2126         default:
2127             FIXME("Unrecognized resource type %#x.\n", resource_type);
2128             return "unrecognized";
2129     }
2130 }
2131
2132 const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type)
2133 {
2134     switch (primitive_type)
2135     {
2136 #define PRIM_TO_STR(prim) case prim: return #prim
2137         PRIM_TO_STR(WINED3D_PT_UNDEFINED);
2138         PRIM_TO_STR(WINED3D_PT_POINTLIST);
2139         PRIM_TO_STR(WINED3D_PT_LINELIST);
2140         PRIM_TO_STR(WINED3D_PT_LINESTRIP);
2141         PRIM_TO_STR(WINED3D_PT_TRIANGLELIST);
2142         PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP);
2143         PRIM_TO_STR(WINED3D_PT_TRIANGLEFAN);
2144         PRIM_TO_STR(WINED3D_PT_LINELIST_ADJ);
2145         PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ);
2146         PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ);
2147         PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ);
2148 #undef  PRIM_TO_STR
2149         default:
2150             FIXME("Unrecognized %u primitive type!\n", primitive_type);
2151             return "unrecognized";
2152     }
2153 }
2154
2155 const char *debug_d3drenderstate(enum wined3d_render_state state)
2156 {
2157     switch (state)
2158     {
2159 #define D3DSTATE_TO_STR(u) case u: return #u
2160         D3DSTATE_TO_STR(WINED3D_RS_ANTIALIAS);
2161         D3DSTATE_TO_STR(WINED3D_RS_TEXTUREPERSPECTIVE);
2162         D3DSTATE_TO_STR(WINED3D_RS_WRAPU);
2163         D3DSTATE_TO_STR(WINED3D_RS_WRAPV);
2164         D3DSTATE_TO_STR(WINED3D_RS_ZENABLE);
2165         D3DSTATE_TO_STR(WINED3D_RS_FILLMODE);
2166         D3DSTATE_TO_STR(WINED3D_RS_SHADEMODE);
2167         D3DSTATE_TO_STR(WINED3D_RS_LINEPATTERN);
2168         D3DSTATE_TO_STR(WINED3D_RS_MONOENABLE);
2169         D3DSTATE_TO_STR(WINED3D_RS_ROP2);
2170         D3DSTATE_TO_STR(WINED3D_RS_PLANEMASK);
2171         D3DSTATE_TO_STR(WINED3D_RS_ZWRITEENABLE);
2172         D3DSTATE_TO_STR(WINED3D_RS_ALPHATESTENABLE);
2173         D3DSTATE_TO_STR(WINED3D_RS_LASTPIXEL);
2174         D3DSTATE_TO_STR(WINED3D_RS_SRCBLEND);
2175         D3DSTATE_TO_STR(WINED3D_RS_DESTBLEND);
2176         D3DSTATE_TO_STR(WINED3D_RS_CULLMODE);
2177         D3DSTATE_TO_STR(WINED3D_RS_ZFUNC);
2178         D3DSTATE_TO_STR(WINED3D_RS_ALPHAREF);
2179         D3DSTATE_TO_STR(WINED3D_RS_ALPHAFUNC);
2180         D3DSTATE_TO_STR(WINED3D_RS_DITHERENABLE);
2181         D3DSTATE_TO_STR(WINED3D_RS_ALPHABLENDENABLE);
2182         D3DSTATE_TO_STR(WINED3D_RS_FOGENABLE);
2183         D3DSTATE_TO_STR(WINED3D_RS_SPECULARENABLE);
2184         D3DSTATE_TO_STR(WINED3D_RS_ZVISIBLE);
2185         D3DSTATE_TO_STR(WINED3D_RS_SUBPIXEL);
2186         D3DSTATE_TO_STR(WINED3D_RS_SUBPIXELX);
2187         D3DSTATE_TO_STR(WINED3D_RS_STIPPLEDALPHA);
2188         D3DSTATE_TO_STR(WINED3D_RS_FOGCOLOR);
2189         D3DSTATE_TO_STR(WINED3D_RS_FOGTABLEMODE);
2190         D3DSTATE_TO_STR(WINED3D_RS_FOGSTART);
2191         D3DSTATE_TO_STR(WINED3D_RS_FOGEND);
2192         D3DSTATE_TO_STR(WINED3D_RS_FOGDENSITY);
2193         D3DSTATE_TO_STR(WINED3D_RS_STIPPLEENABLE);
2194         D3DSTATE_TO_STR(WINED3D_RS_EDGEANTIALIAS);
2195         D3DSTATE_TO_STR(WINED3D_RS_COLORKEYENABLE);
2196         D3DSTATE_TO_STR(WINED3D_RS_MIPMAPLODBIAS);
2197         D3DSTATE_TO_STR(WINED3D_RS_RANGEFOGENABLE);
2198         D3DSTATE_TO_STR(WINED3D_RS_ANISOTROPY);
2199         D3DSTATE_TO_STR(WINED3D_RS_FLUSHBATCH);
2200         D3DSTATE_TO_STR(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT);
2201         D3DSTATE_TO_STR(WINED3D_RS_STENCILENABLE);
2202         D3DSTATE_TO_STR(WINED3D_RS_STENCILFAIL);
2203         D3DSTATE_TO_STR(WINED3D_RS_STENCILZFAIL);
2204         D3DSTATE_TO_STR(WINED3D_RS_STENCILPASS);
2205         D3DSTATE_TO_STR(WINED3D_RS_STENCILFUNC);
2206         D3DSTATE_TO_STR(WINED3D_RS_STENCILREF);
2207         D3DSTATE_TO_STR(WINED3D_RS_STENCILMASK);
2208         D3DSTATE_TO_STR(WINED3D_RS_STENCILWRITEMASK);
2209         D3DSTATE_TO_STR(WINED3D_RS_TEXTUREFACTOR);
2210         D3DSTATE_TO_STR(WINED3D_RS_WRAP0);
2211         D3DSTATE_TO_STR(WINED3D_RS_WRAP1);
2212         D3DSTATE_TO_STR(WINED3D_RS_WRAP2);
2213         D3DSTATE_TO_STR(WINED3D_RS_WRAP3);
2214         D3DSTATE_TO_STR(WINED3D_RS_WRAP4);
2215         D3DSTATE_TO_STR(WINED3D_RS_WRAP5);
2216         D3DSTATE_TO_STR(WINED3D_RS_WRAP6);
2217         D3DSTATE_TO_STR(WINED3D_RS_WRAP7);
2218         D3DSTATE_TO_STR(WINED3D_RS_CLIPPING);
2219         D3DSTATE_TO_STR(WINED3D_RS_LIGHTING);
2220         D3DSTATE_TO_STR(WINED3D_RS_EXTENTS);
2221         D3DSTATE_TO_STR(WINED3D_RS_AMBIENT);
2222         D3DSTATE_TO_STR(WINED3D_RS_FOGVERTEXMODE);
2223         D3DSTATE_TO_STR(WINED3D_RS_COLORVERTEX);
2224         D3DSTATE_TO_STR(WINED3D_RS_LOCALVIEWER);
2225         D3DSTATE_TO_STR(WINED3D_RS_NORMALIZENORMALS);
2226         D3DSTATE_TO_STR(WINED3D_RS_COLORKEYBLENDENABLE);
2227         D3DSTATE_TO_STR(WINED3D_RS_DIFFUSEMATERIALSOURCE);
2228         D3DSTATE_TO_STR(WINED3D_RS_SPECULARMATERIALSOURCE);
2229         D3DSTATE_TO_STR(WINED3D_RS_AMBIENTMATERIALSOURCE);
2230         D3DSTATE_TO_STR(WINED3D_RS_EMISSIVEMATERIALSOURCE);
2231         D3DSTATE_TO_STR(WINED3D_RS_VERTEXBLEND);
2232         D3DSTATE_TO_STR(WINED3D_RS_CLIPPLANEENABLE);
2233         D3DSTATE_TO_STR(WINED3D_RS_SOFTWAREVERTEXPROCESSING);
2234         D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE);
2235         D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MIN);
2236         D3DSTATE_TO_STR(WINED3D_RS_POINTSPRITEENABLE);
2237         D3DSTATE_TO_STR(WINED3D_RS_POINTSCALEENABLE);
2238         D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_A);
2239         D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_B);
2240         D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_C);
2241         D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEANTIALIAS);
2242         D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEMASK);
2243         D3DSTATE_TO_STR(WINED3D_RS_PATCHEDGESTYLE);
2244         D3DSTATE_TO_STR(WINED3D_RS_PATCHSEGMENTS);
2245         D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN);
2246         D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX);
2247         D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE);
2248         D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
2249         D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR);
2250         D3DSTATE_TO_STR(WINED3D_RS_BLENDOP);
2251         D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE);
2252         D3DSTATE_TO_STR(WINED3D_RS_NORMALDEGREE);
2253         D3DSTATE_TO_STR(WINED3D_RS_SCISSORTESTENABLE);
2254         D3DSTATE_TO_STR(WINED3D_RS_SLOPESCALEDEPTHBIAS);
2255         D3DSTATE_TO_STR(WINED3D_RS_ANTIALIASEDLINEENABLE);
2256         D3DSTATE_TO_STR(WINED3D_RS_MINTESSELLATIONLEVEL);
2257         D3DSTATE_TO_STR(WINED3D_RS_MAXTESSELLATIONLEVEL);
2258         D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_X);
2259         D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Y);
2260         D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Z);
2261         D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_W);
2262         D3DSTATE_TO_STR(WINED3D_RS_ENABLEADAPTIVETESSELLATION);
2263         D3DSTATE_TO_STR(WINED3D_RS_TWOSIDEDSTENCILMODE);
2264         D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFAIL);
2265         D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILZFAIL);
2266         D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILPASS);
2267         D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFUNC);
2268         D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1);
2269         D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2);
2270         D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3);
2271         D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR);
2272         D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE);
2273         D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS);
2274         D3DSTATE_TO_STR(WINED3D_RS_WRAP8);
2275         D3DSTATE_TO_STR(WINED3D_RS_WRAP9);
2276         D3DSTATE_TO_STR(WINED3D_RS_WRAP10);
2277         D3DSTATE_TO_STR(WINED3D_RS_WRAP11);
2278         D3DSTATE_TO_STR(WINED3D_RS_WRAP12);
2279         D3DSTATE_TO_STR(WINED3D_RS_WRAP13);
2280         D3DSTATE_TO_STR(WINED3D_RS_WRAP14);
2281         D3DSTATE_TO_STR(WINED3D_RS_WRAP15);
2282         D3DSTATE_TO_STR(WINED3D_RS_SEPARATEALPHABLENDENABLE);
2283         D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
2284         D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
2285         D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
2286 #undef D3DSTATE_TO_STR
2287         default:
2288             FIXME("Unrecognized %u render state!\n", state);
2289             return "unrecognized";
2290     }
2291 }
2292
2293 const char *debug_d3dsamplerstate(enum wined3d_sampler_state state)
2294 {
2295     switch (state)
2296     {
2297 #define D3DSTATE_TO_STR(u) case u: return #u
2298         D3DSTATE_TO_STR(WINED3D_SAMP_BORDER_COLOR);
2299         D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_U);
2300         D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_V);
2301         D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_W);
2302         D3DSTATE_TO_STR(WINED3D_SAMP_MAG_FILTER);
2303         D3DSTATE_TO_STR(WINED3D_SAMP_MIN_FILTER);
2304         D3DSTATE_TO_STR(WINED3D_SAMP_MIP_FILTER);
2305         D3DSTATE_TO_STR(WINED3D_SAMP_MIPMAP_LOD_BIAS);
2306         D3DSTATE_TO_STR(WINED3D_SAMP_MAX_MIP_LEVEL);
2307         D3DSTATE_TO_STR(WINED3D_SAMP_MAX_ANISOTROPY);
2308         D3DSTATE_TO_STR(WINED3D_SAMP_SRGB_TEXTURE);
2309         D3DSTATE_TO_STR(WINED3D_SAMP_ELEMENT_INDEX);
2310         D3DSTATE_TO_STR(WINED3D_SAMP_DMAP_OFFSET);
2311 #undef D3DSTATE_TO_STR
2312         default:
2313             FIXME("Unrecognized %u sampler state!\n", state);
2314             return "unrecognized";
2315     }
2316 }
2317
2318 const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type)
2319 {
2320     switch (filter_type)
2321     {
2322 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2323         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_NONE);
2324         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_POINT);
2325         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_LINEAR);
2326         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_ANISOTROPIC);
2327         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_FLAT_CUBIC);
2328         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_CUBIC);
2329         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_PYRAMIDAL_QUAD);
2330         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_QUAD);
2331 #undef D3DTEXTUREFILTERTYPE_TO_STR
2332         default:
2333             FIXME("Unrecognied texture filter type 0x%08x.\n", filter_type);
2334             return "unrecognized";
2335     }
2336 }
2337
2338 const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state)
2339 {
2340     switch (state)
2341     {
2342 #define D3DSTATE_TO_STR(u) case u: return #u
2343         D3DSTATE_TO_STR(WINED3D_TSS_COLOR_OP);
2344         D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG1);
2345         D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG2);
2346         D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_OP);
2347         D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG1);
2348         D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG2);
2349         D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT00);
2350         D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT01);
2351         D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT10);
2352         D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT11);
2353         D3DSTATE_TO_STR(WINED3D_TSS_TEXCOORD_INDEX);
2354         D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LSCALE);
2355         D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LOFFSET);
2356         D3DSTATE_TO_STR(WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS);
2357         D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG0);
2358         D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG0);
2359         D3DSTATE_TO_STR(WINED3D_TSS_RESULT_ARG);
2360         D3DSTATE_TO_STR(WINED3D_TSS_CONSTANT);
2361 #undef D3DSTATE_TO_STR
2362         default:
2363             FIXME("Unrecognized %u texture state!\n", state);
2364             return "unrecognized";
2365     }
2366 }
2367
2368 const char *debug_d3dtop(enum wined3d_texture_op d3dtop)
2369 {
2370     switch (d3dtop)
2371     {
2372 #define D3DTOP_TO_STR(u) case u: return #u
2373         D3DTOP_TO_STR(WINED3D_TOP_DISABLE);
2374         D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG1);
2375         D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG2);
2376         D3DTOP_TO_STR(WINED3D_TOP_MODULATE);
2377         D3DTOP_TO_STR(WINED3D_TOP_MODULATE_2X);
2378         D3DTOP_TO_STR(WINED3D_TOP_MODULATE_4X);
2379         D3DTOP_TO_STR(WINED3D_TOP_ADD);
2380         D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED);
2381         D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED_2X);
2382         D3DTOP_TO_STR(WINED3D_TOP_SUBTRACT);
2383         D3DTOP_TO_STR(WINED3D_TOP_ADD_SMOOTH);
2384         D3DTOP_TO_STR(WINED3D_TOP_BLEND_DIFFUSE_ALPHA);
2385         D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA);
2386         D3DTOP_TO_STR(WINED3D_TOP_BLEND_FACTOR_ALPHA);
2387         D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM);
2388         D3DTOP_TO_STR(WINED3D_TOP_BLEND_CURRENT_ALPHA);
2389         D3DTOP_TO_STR(WINED3D_TOP_PREMODULATE);
2390         D3DTOP_TO_STR(WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR);
2391         D3DTOP_TO_STR(WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA);
2392         D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR);
2393         D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA);
2394         D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP);
2395         D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP_LUMINANCE);
2396         D3DTOP_TO_STR(WINED3D_TOP_DOTPRODUCT3);
2397         D3DTOP_TO_STR(WINED3D_TOP_MULTIPLY_ADD);
2398         D3DTOP_TO_STR(WINED3D_TOP_LERP);
2399 #undef D3DTOP_TO_STR
2400         default:
2401             FIXME("Unrecognized texture op %#x.\n", d3dtop);
2402             return "unrecognized";
2403     }
2404 }
2405
2406 const char *debug_d3dtstype(enum wined3d_transform_state tstype)
2407 {
2408     switch (tstype)
2409     {
2410 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2411     TSTYPE_TO_STR(WINED3D_TS_VIEW);
2412     TSTYPE_TO_STR(WINED3D_TS_PROJECTION);
2413     TSTYPE_TO_STR(WINED3D_TS_TEXTURE0);
2414     TSTYPE_TO_STR(WINED3D_TS_TEXTURE1);
2415     TSTYPE_TO_STR(WINED3D_TS_TEXTURE2);
2416     TSTYPE_TO_STR(WINED3D_TS_TEXTURE3);
2417     TSTYPE_TO_STR(WINED3D_TS_TEXTURE4);
2418     TSTYPE_TO_STR(WINED3D_TS_TEXTURE5);
2419     TSTYPE_TO_STR(WINED3D_TS_TEXTURE6);
2420     TSTYPE_TO_STR(WINED3D_TS_TEXTURE7);
2421     TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(0));
2422 #undef TSTYPE_TO_STR
2423     default:
2424         if (tstype > 256 && tstype < 512)
2425         {
2426             FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype);
2427             return ("WINED3D_TS_WORLD_MATRIX > 0");
2428         }
2429         FIXME("Unrecognized transform state %#x.\n", tstype);
2430         return "unrecognized";
2431     }
2432 }
2433
2434 const char *debug_d3dstate(DWORD state)
2435 {
2436     if (STATE_IS_RENDER(state))
2437         return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2438     if (STATE_IS_TEXTURESTAGE(state))
2439     {
2440         DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2441         DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2442         return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2443                 texture_stage, debug_d3dtexturestate(texture_state));
2444     }
2445     if (STATE_IS_SAMPLER(state))
2446         return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2447     if (STATE_IS_PIXELSHADER(state))
2448         return "STATE_PIXELSHADER";
2449     if (STATE_IS_TRANSFORM(state))
2450         return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2451     if (STATE_IS_STREAMSRC(state))
2452         return "STATE_STREAMSRC";
2453     if (STATE_IS_INDEXBUFFER(state))
2454         return "STATE_INDEXBUFFER";
2455     if (STATE_IS_VDECL(state))
2456         return "STATE_VDECL";
2457     if (STATE_IS_VSHADER(state))
2458         return "STATE_VSHADER";
2459     if (STATE_IS_GEOMETRY_SHADER(state))
2460         return "STATE_GEOMETRY_SHADER";
2461     if (STATE_IS_VIEWPORT(state))
2462         return "STATE_VIEWPORT";
2463     if (STATE_IS_VERTEXSHADERCONSTANT(state))
2464         return "STATE_VERTEXSHADERCONSTANT";
2465     if (STATE_IS_PIXELSHADERCONSTANT(state))
2466         return "STATE_PIXELSHADERCONSTANT";
2467     if (STATE_IS_ACTIVELIGHT(state))
2468         return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2469     if (STATE_IS_SCISSORRECT(state))
2470         return "STATE_SCISSORRECT";
2471     if (STATE_IS_CLIPPLANE(state))
2472         return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2473     if (STATE_IS_MATERIAL(state))
2474         return "STATE_MATERIAL";
2475     if (STATE_IS_FRONTFACE(state))
2476         return "STATE_FRONTFACE";
2477     if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2478         return "STATE_POINTSPRITECOORDORIGIN";
2479     if (STATE_IS_BASEVERTEXINDEX(state))
2480         return "STATE_BASEVERTEXINDEX";
2481     if (STATE_IS_FRAMEBUFFER(state))
2482         return "STATE_FRAMEBUFFER";
2483
2484     return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2485 }
2486
2487 const char *debug_d3dpool(enum wined3d_pool pool)
2488 {
2489     switch (pool)
2490     {
2491 #define POOL_TO_STR(p) case p: return #p
2492         POOL_TO_STR(WINED3D_POOL_DEFAULT);
2493         POOL_TO_STR(WINED3D_POOL_MANAGED);
2494         POOL_TO_STR(WINED3D_POOL_SYSTEM_MEM);
2495         POOL_TO_STR(WINED3D_POOL_SCRATCH);
2496 #undef  POOL_TO_STR
2497         default:
2498             FIXME("Unrecognized pool %#x.\n", pool);
2499             return "unrecognized";
2500     }
2501 }
2502
2503 const char *debug_fbostatus(GLenum status) {
2504     switch(status) {
2505 #define FBOSTATUS_TO_STR(u) case u: return #u
2506         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2507         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2508         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2509         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2510         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2511         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2512         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2513         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2514         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2515         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2516 #undef FBOSTATUS_TO_STR
2517         default:
2518             FIXME("Unrecognied FBO status 0x%08x\n", status);
2519             return "unrecognized";
2520     }
2521 }
2522
2523 const char *debug_glerror(GLenum error) {
2524     switch(error) {
2525 #define GLERROR_TO_STR(u) case u: return #u
2526         GLERROR_TO_STR(GL_NO_ERROR);
2527         GLERROR_TO_STR(GL_INVALID_ENUM);
2528         GLERROR_TO_STR(GL_INVALID_VALUE);
2529         GLERROR_TO_STR(GL_INVALID_OPERATION);
2530         GLERROR_TO_STR(GL_STACK_OVERFLOW);
2531         GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2532         GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2533         GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2534 #undef GLERROR_TO_STR
2535         default:
2536             FIXME("Unrecognied GL error 0x%08x\n", error);
2537             return "unrecognized";
2538     }
2539 }
2540
2541 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2542 {
2543     switch(source)
2544     {
2545 #define WINED3D_TO_STR(x) case x: return #x
2546         WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2547         WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2548         WINED3D_TO_STR(CHANNEL_SOURCE_X);
2549         WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2550         WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2551         WINED3D_TO_STR(CHANNEL_SOURCE_W);
2552         WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2553         WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2554 #undef WINED3D_TO_STR
2555         default:
2556             FIXME("Unrecognized fixup_channel_source %#x\n", source);
2557             return "unrecognized";
2558     }
2559 }
2560
2561 static const char *debug_complex_fixup(enum complex_fixup fixup)
2562 {
2563     switch(fixup)
2564     {
2565 #define WINED3D_TO_STR(x) case x: return #x
2566         WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2567         WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2568         WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2569         WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2570 #undef WINED3D_TO_STR
2571         default:
2572             FIXME("Unrecognized complex fixup %#x\n", fixup);
2573             return "unrecognized";
2574     }
2575 }
2576
2577 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2578 {
2579     if (is_complex_fixup(fixup))
2580     {
2581         TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2582         return;
2583     }
2584
2585     TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2586     TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2587     TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2588     TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2589 }
2590
2591 const char *debug_surflocation(DWORD flag) {
2592     char buf[128];
2593
2594     buf[0] = 0;
2595     if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");                    /* 17 */
2596     if (flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");                /* 19 */
2597     if (flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");                  /* 18 */
2598     if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");                  /* 18 */
2599     if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE");    /* 25 */
2600     if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED");          /* 22 */
2601     return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2602 }
2603
2604 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2605         enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2606 {
2607     if (op == WINED3D_TOP_DISABLE)
2608         return FALSE;
2609     if (state->textures[stage])
2610         return FALSE;
2611
2612     if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2613             && op != WINED3D_TOP_SELECT_ARG2)
2614         return TRUE;
2615     if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2616             && op != WINED3D_TOP_SELECT_ARG1)
2617         return TRUE;
2618     if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2619             && (op == WINED3D_TOP_MULTIPLY_ADD || op == WINED3D_TOP_LERP))
2620         return TRUE;
2621
2622     return FALSE;
2623 }
2624
2625 /* Setup this textures matrix according to the texture flags. */
2626 /* Context activation is done by the caller (state handler). */
2627 void set_texture_matrix(const struct wined3d_gl_info *gl_info, const float *smat, DWORD flags,
2628         BOOL calculatedCoords, BOOL transformed, enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2629 {
2630     float mat[16];
2631
2632     gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
2633     checkGLcall("glMatrixMode(GL_TEXTURE)");
2634
2635     if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed)
2636     {
2637         gl_info->gl_ops.gl.p_glLoadIdentity();
2638         checkGLcall("glLoadIdentity()");
2639         return;
2640     }
2641
2642     if (flags == (WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED))
2643     {
2644         ERR("Invalid texture transform flags: WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED.\n");
2645         return;
2646     }
2647
2648     memcpy(mat, smat, 16 * sizeof(float));
2649
2650     if (flags & WINED3D_TTFF_PROJECTED)
2651     {
2652         if (!ffp_proj_control)
2653         {
2654             switch (flags & ~WINED3D_TTFF_PROJECTED)
2655             {
2656                 case WINED3D_TTFF_COUNT2:
2657                     mat[ 3] = mat[ 1];
2658                     mat[ 7] = mat[ 5];
2659                     mat[11] = mat[ 9];
2660                     mat[15] = mat[13];
2661                     mat[ 1] = mat[ 5] = mat[ 9] = mat[13] = 0.0f;
2662                     break;
2663                 case WINED3D_TTFF_COUNT3:
2664                     mat[ 3] = mat[ 2];
2665                     mat[ 7] = mat[ 6];
2666                     mat[11] = mat[10];
2667                     mat[15] = mat[14];
2668                     mat[ 2] = mat[ 6] = mat[10] = mat[14] = 0.0f;
2669                     break;
2670             }
2671         }
2672     } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2673         if(!calculatedCoords) {
2674             switch(vtx_fmt)
2675             {
2676                 case WINED3DFMT_R32_FLOAT:
2677                     /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2678                      * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2679                      * the input value to the transformation will be 0, so the matrix value is irrelevant
2680                      */
2681                     mat[12] = mat[4];
2682                     mat[13] = mat[5];
2683                     mat[14] = mat[6];
2684                     mat[15] = mat[7];
2685                     break;
2686                 case WINED3DFMT_R32G32_FLOAT:
2687                     /* See above, just 3rd and 4th coord
2688                     */
2689                     mat[12] = mat[8];
2690                     mat[13] = mat[9];
2691                     mat[14] = mat[10];
2692                     mat[15] = mat[11];
2693                     break;
2694                 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2695                 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2696
2697                 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2698                  * into a bad place. The division elimination below will apply to make sure the
2699                  * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2700                  */
2701                 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2702                     break;
2703                 default:
2704                     FIXME("Unexpected fixed function texture coord input\n");
2705             }
2706         }
2707         if (!ffp_proj_control)
2708         {
2709             switch (flags & ~WINED3D_TTFF_PROJECTED)
2710             {
2711                 /* case WINED3D_TTFF_COUNT1: Won't ever get here. */
2712                 case WINED3D_TTFF_COUNT2:
2713                     mat[2] = mat[6] = mat[10] = mat[14] = 0;
2714                 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2715                 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2716                 * the 4th coord evaluates to 1.0 to eliminate that.
2717                 *
2718                 * If the fixed function pipeline is used, the 4th value remains unused,
2719                 * so there is no danger in doing this. With vertex shaders we have a
2720                 * problem. Should an app hit that problem, the code here would have to
2721                 * check for pixel shaders, and the shader has to undo the default gl divide.
2722                 *
2723                 * A more serious problem occurs if the app passes 4 coordinates in, and the
2724                 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2725                 * or a replacement shader. */
2726                 default:
2727                     mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2728             }
2729         }
2730     }
2731
2732     gl_info->gl_ops.gl.p_glLoadMatrixf(mat);
2733     checkGLcall("glLoadMatrixf(mat)");
2734 }
2735
2736 /* This small helper function is used to convert a bitmask into the number of masked bits */
2737 unsigned int count_bits(unsigned int mask)
2738 {
2739     unsigned int count;
2740     for (count = 0; mask; ++count)
2741     {
2742         mask &= mask - 1;
2743     }
2744     return count;
2745 }
2746
2747 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2748  * The later function requires individual color components. */
2749 BOOL getColorBits(const struct wined3d_format *format,
2750         BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2751 {
2752     TRACE("format %s.\n", debug_d3dformat(format->id));
2753
2754     switch (format->id)
2755     {
2756         case WINED3DFMT_B10G10R10A2_UNORM:
2757         case WINED3DFMT_R10G10B10A2_UNORM:
2758         case WINED3DFMT_B8G8R8X8_UNORM:
2759         case WINED3DFMT_B8G8R8_UNORM:
2760         case WINED3DFMT_B8G8R8A8_UNORM:
2761         case WINED3DFMT_R8G8B8A8_UNORM:
2762         case WINED3DFMT_B5G5R5X1_UNORM:
2763         case WINED3DFMT_B5G5R5A1_UNORM:
2764         case WINED3DFMT_B5G6R5_UNORM:
2765         case WINED3DFMT_B4G4R4X4_UNORM:
2766         case WINED3DFMT_B4G4R4A4_UNORM:
2767         case WINED3DFMT_B2G3R3_UNORM:
2768         case WINED3DFMT_P8_UINT_A8_UNORM:
2769         case WINED3DFMT_P8_UINT:
2770             break;
2771         default:
2772             FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2773             return FALSE;
2774     }
2775
2776     *redSize = format->red_size;
2777     *greenSize = format->green_size;
2778     *blueSize = format->blue_size;
2779     *alphaSize = format->alpha_size;
2780     *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2781
2782     TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2783             *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2784     return TRUE;
2785 }
2786
2787 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2788 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
2789 {
2790     TRACE("format %s.\n", debug_d3dformat(format->id));
2791
2792     switch (format->id)
2793     {
2794         case WINED3DFMT_D16_LOCKABLE:
2795         case WINED3DFMT_D16_UNORM:
2796         case WINED3DFMT_S1_UINT_D15_UNORM:
2797         case WINED3DFMT_X8D24_UNORM:
2798         case WINED3DFMT_S4X4_UINT_D24_UNORM:
2799         case WINED3DFMT_D24_UNORM_S8_UINT:
2800         case WINED3DFMT_S8_UINT_D24_FLOAT:
2801         case WINED3DFMT_D32_UNORM:
2802         case WINED3DFMT_D32_FLOAT:
2803         case WINED3DFMT_INTZ:
2804             break;
2805         default:
2806             FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2807             return FALSE;
2808     }
2809
2810     *depthSize = format->depth_size;
2811     *stencilSize = format->stencil_size;
2812
2813     TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2814             *depthSize, *stencilSize, debug_d3dformat(format->id));
2815     return TRUE;
2816 }
2817
2818 /* Note: It's the caller's responsibility to ensure values can be expressed
2819  * in the requested format. UNORM formats for example can only express values
2820  * in the range 0.0f -> 1.0f. */
2821 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color)
2822 {
2823     static const struct
2824     {
2825         enum wined3d_format_id format_id;
2826         float r_mul;
2827         float g_mul;
2828         float b_mul;
2829         float a_mul;
2830         BYTE r_shift;
2831         BYTE g_shift;
2832         BYTE b_shift;
2833         BYTE a_shift;
2834     }
2835     conv[] =
2836     {
2837         {WINED3DFMT_B8G8R8A8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
2838         {WINED3DFMT_B8G8R8X8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
2839         {WINED3DFMT_B8G8R8_UNORM,       255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
2840         {WINED3DFMT_B5G6R5_UNORM,        31.0f,   63.0f,   31.0f,    0.0f, 11,  5,  0,  0},
2841         {WINED3DFMT_B5G5R5A1_UNORM,      31.0f,   31.0f,   31.0f,    1.0f, 10,  5,  0, 15},
2842         {WINED3DFMT_B5G5R5X1_UNORM,      31.0f,   31.0f,   31.0f,    1.0f, 10,  5,  0, 15},
2843         {WINED3DFMT_A8_UNORM,             0.0f,    0.0f,    0.0f,  255.0f,  0,  0,  0,  0},
2844         {WINED3DFMT_B4G4R4A4_UNORM,      15.0f,   15.0f,   15.0f,   15.0f,  8,  4,  0, 12},
2845         {WINED3DFMT_B4G4R4X4_UNORM,      15.0f,   15.0f,   15.0f,   15.0f,  8,  4,  0, 12},
2846         {WINED3DFMT_B2G3R3_UNORM,         7.0f,    7.0f,    3.0f,    0.0f,  5,  2,  0,  0},
2847         {WINED3DFMT_R8G8B8A8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f,  0,  8, 16, 24},
2848         {WINED3DFMT_R8G8B8X8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f,  0,  8, 16, 24},
2849         {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f,    3.0f, 20, 10,  0, 30},
2850         {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f,    3.0f,  0, 10, 20, 30},
2851     };
2852     const struct wined3d_format *format = surface->resource.format;
2853     unsigned int i;
2854
2855     TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2856             color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2857
2858     for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2859     {
2860         DWORD ret;
2861
2862         if (format->id != conv[i].format_id) continue;
2863
2864         ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2865         ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2866         ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2867         ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2868
2869         TRACE("Returning 0x%08x.\n", ret);
2870
2871         return ret;
2872     }
2873
2874     if (format->id == WINED3DFMT_P8_UINT)
2875     {
2876         PALETTEENTRY *e;
2877         BYTE r, g, b, a;
2878
2879         if (!surface->palette)
2880         {
2881             WARN("Surface doesn't have a palette, returning 0.\n");
2882             return 0;
2883         }
2884
2885         r = (BYTE)((color->r * 255.0f) + 0.5f);
2886         g = (BYTE)((color->g * 255.0f) + 0.5f);
2887         b = (BYTE)((color->b * 255.0f) + 0.5f);
2888         a = (BYTE)((color->a * 255.0f) + 0.5f);
2889
2890         e = &surface->palette->palents[a];
2891         if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2892             return a;
2893
2894         WARN("Alpha didn't match index, searching full palette.\n");
2895
2896         for (i = 0; i < 256; ++i)
2897         {
2898             e = &surface->palette->palents[i];
2899             if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2900                 return i;
2901         }
2902
2903         FIXME("Unable to convert color to palette index.\n");
2904
2905         return 0;
2906     }
2907
2908     FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2909
2910     return 0;
2911 }
2912
2913 /* DirectDraw stuff */
2914 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2915 {
2916     switch (depth)
2917     {
2918         case 8:  return WINED3DFMT_P8_UINT;
2919         case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2920         case 16: return WINED3DFMT_B5G6R5_UNORM;
2921         case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2922         case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2923         default: return WINED3DFMT_UNKNOWN;
2924     }
2925 }
2926
2927 void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
2928         const struct wined3d_matrix *src2)
2929 {
2930     struct wined3d_matrix temp;
2931
2932     /* Now do the multiplication 'by hand'.
2933        I know that all this could be optimised, but this will be done later :-) */
2934     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);
2935     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);
2936     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);
2937     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);
2938
2939     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);
2940     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);
2941     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);
2942     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);
2943
2944     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);
2945     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);
2946     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);
2947     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);
2948
2949     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);
2950     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);
2951     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);
2952     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);
2953
2954     /* And copy the new matrix in the good storage.. */
2955     memcpy(dest, &temp, 16 * sizeof(float));
2956 }
2957
2958 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2959     DWORD size = 0;
2960     int i;
2961     int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2962
2963     if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2964     if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2965     if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2966     if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2967     switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2968         case WINED3DFVF_XYZ:    size += 3 * sizeof(float); break;
2969         case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2970         case WINED3DFVF_XYZB1:  size += 4 * sizeof(float); break;
2971         case WINED3DFVF_XYZB2:  size += 5 * sizeof(float); break;
2972         case WINED3DFVF_XYZB3:  size += 6 * sizeof(float); break;
2973         case WINED3DFVF_XYZB4:  size += 7 * sizeof(float); break;
2974         case WINED3DFVF_XYZB5:  size += 8 * sizeof(float); break;
2975         case WINED3DFVF_XYZW:   size += 4 * sizeof(float); break;
2976         default: ERR("Unexpected position mask\n");
2977     }
2978     for (i = 0; i < numTextures; i++) {
2979         size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2980     }
2981
2982     return size;
2983 }
2984
2985 void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_state *state,
2986         struct ffp_frag_settings *settings, BOOL ignore_textype)
2987 {
2988 #define ARG1 0x01
2989 #define ARG2 0x02
2990 #define ARG0 0x04
2991     static const unsigned char args[WINED3D_TOP_LERP + 1] =
2992     {
2993         /* undefined                        */  0,
2994         /* D3DTOP_DISABLE                   */  0,
2995         /* D3DTOP_SELECTARG1                */  ARG1,
2996         /* D3DTOP_SELECTARG2                */  ARG2,
2997         /* D3DTOP_MODULATE                  */  ARG1 | ARG2,
2998         /* D3DTOP_MODULATE2X                */  ARG1 | ARG2,
2999         /* D3DTOP_MODULATE4X                */  ARG1 | ARG2,
3000         /* D3DTOP_ADD                       */  ARG1 | ARG2,
3001         /* D3DTOP_ADDSIGNED                 */  ARG1 | ARG2,
3002         /* D3DTOP_ADDSIGNED2X               */  ARG1 | ARG2,
3003         /* D3DTOP_SUBTRACT                  */  ARG1 | ARG2,
3004         /* D3DTOP_ADDSMOOTH                 */  ARG1 | ARG2,
3005         /* D3DTOP_BLENDDIFFUSEALPHA         */  ARG1 | ARG2,
3006         /* D3DTOP_BLENDTEXTUREALPHA         */  ARG1 | ARG2,
3007         /* D3DTOP_BLENDFACTORALPHA          */  ARG1 | ARG2,
3008         /* D3DTOP_BLENDTEXTUREALPHAPM       */  ARG1 | ARG2,
3009         /* D3DTOP_BLENDCURRENTALPHA         */  ARG1 | ARG2,
3010         /* D3DTOP_PREMODULATE               */  ARG1 | ARG2,
3011         /* D3DTOP_MODULATEALPHA_ADDCOLOR    */  ARG1 | ARG2,
3012         /* D3DTOP_MODULATECOLOR_ADDALPHA    */  ARG1 | ARG2,
3013         /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */  ARG1 | ARG2,
3014         /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */  ARG1 | ARG2,
3015         /* D3DTOP_BUMPENVMAP                */  ARG1 | ARG2,
3016         /* D3DTOP_BUMPENVMAPLUMINANCE       */  ARG1 | ARG2,
3017         /* D3DTOP_DOTPRODUCT3               */  ARG1 | ARG2,
3018         /* D3DTOP_MULTIPLYADD               */  ARG1 | ARG2 | ARG0,
3019         /* D3DTOP_LERP                      */  ARG1 | ARG2 | ARG0
3020     };
3021     unsigned int i;
3022     DWORD ttff;
3023     DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
3024     const struct wined3d_surface *rt = state->fb->render_targets[0];
3025     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
3026
3027     for (i = 0; i < gl_info->limits.texture_stages; ++i)
3028     {
3029         const struct wined3d_texture *texture;
3030
3031         settings->op[i].padding = 0;
3032         if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
3033         {
3034             settings->op[i].cop = WINED3D_TOP_DISABLE;
3035             settings->op[i].aop = WINED3D_TOP_DISABLE;
3036             settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
3037             settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
3038             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
3039             settings->op[i].dst = resultreg;
3040             settings->op[i].tex_type = tex_1d;
3041             settings->op[i].projected = proj_none;
3042             i++;
3043             break;
3044         }
3045
3046         if ((texture = state->textures[i]))
3047         {
3048             settings->op[i].color_fixup = texture->resource.format->color_fixup;
3049             if (ignore_textype)
3050             {
3051                 settings->op[i].tex_type = tex_1d;
3052             }
3053             else
3054             {
3055                 switch (texture->target)
3056                 {
3057                     case GL_TEXTURE_1D:
3058                         settings->op[i].tex_type = tex_1d;
3059                         break;
3060                     case GL_TEXTURE_2D:
3061                         settings->op[i].tex_type = tex_2d;
3062                         break;
3063                     case GL_TEXTURE_3D:
3064                         settings->op[i].tex_type = tex_3d;
3065                         break;
3066                     case GL_TEXTURE_CUBE_MAP_ARB:
3067                         settings->op[i].tex_type = tex_cube;
3068                         break;
3069                     case GL_TEXTURE_RECTANGLE_ARB:
3070                         settings->op[i].tex_type = tex_rect;
3071                         break;
3072                 }
3073             }
3074         } else {
3075             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
3076             settings->op[i].tex_type = tex_1d;
3077         }
3078
3079         cop = state->texture_states[i][WINED3D_TSS_COLOR_OP];
3080         aop = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
3081
3082         carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG1] : ARG_UNUSED;
3083         carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG2] : ARG_UNUSED;
3084         carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG0] : ARG_UNUSED;
3085
3086         if (is_invalid_op(state, i, cop, carg1, carg2, carg0))
3087         {
3088             carg0 = ARG_UNUSED;
3089             carg2 = ARG_UNUSED;
3090             carg1 = WINED3DTA_CURRENT;
3091             cop = WINED3D_TOP_SELECT_ARG1;
3092         }
3093
3094         if (cop == WINED3D_TOP_DOTPRODUCT3)
3095         {
3096             /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
3097              * the color result to the alpha component of the destination
3098              */
3099             aop = cop;
3100             aarg1 = carg1;
3101             aarg2 = carg2;
3102             aarg0 = carg0;
3103         }
3104         else
3105         {
3106             aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] : ARG_UNUSED;
3107             aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] : ARG_UNUSED;
3108             aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] : ARG_UNUSED;
3109         }
3110
3111         if (!i && state->textures[0] && state->render_states[WINED3D_RS_COLORKEYENABLE])
3112         {
3113             GLenum texture_dimensions;
3114
3115             texture = state->textures[0];
3116             texture_dimensions = texture->target;
3117
3118             if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3119             {
3120                 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3121
3122                 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size)
3123                 {
3124                     if (aop == WINED3D_TOP_DISABLE)
3125                     {
3126                        aarg1 = WINED3DTA_TEXTURE;
3127                        aop = WINED3D_TOP_SELECT_ARG1;
3128                     }
3129                     else if (aop == WINED3D_TOP_SELECT_ARG1 && aarg1 != WINED3DTA_TEXTURE)
3130                     {
3131                         if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3132                         {
3133                             aarg2 = WINED3DTA_TEXTURE;
3134                             aop = WINED3D_TOP_MODULATE;
3135                         }
3136                         else aarg1 = WINED3DTA_TEXTURE;
3137                     }
3138                     else if (aop == WINED3D_TOP_SELECT_ARG2 && aarg2 != WINED3DTA_TEXTURE)
3139                     {
3140                         if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3141                         {
3142                             aarg1 = WINED3DTA_TEXTURE;
3143                             aop = WINED3D_TOP_MODULATE;
3144                         }
3145                         else aarg2 = WINED3DTA_TEXTURE;
3146                     }
3147                 }
3148             }
3149         }
3150
3151         if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0))
3152         {
3153                aarg0 = ARG_UNUSED;
3154                aarg2 = ARG_UNUSED;
3155                aarg1 = WINED3DTA_CURRENT;
3156                aop = WINED3D_TOP_SELECT_ARG1;
3157         }
3158
3159         if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
3160                 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
3161         {
3162             ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
3163             if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3))
3164                 settings->op[i].projected = proj_count3;
3165             else if (ttff & WINED3D_TTFF_PROJECTED)
3166                 settings->op[i].projected = proj_count4;
3167             else
3168                 settings->op[i].projected = proj_none;
3169         }
3170         else
3171         {
3172             settings->op[i].projected = proj_none;
3173         }
3174
3175         settings->op[i].cop = cop;
3176         settings->op[i].aop = aop;
3177         settings->op[i].carg0 = carg0;
3178         settings->op[i].carg1 = carg1;
3179         settings->op[i].carg2 = carg2;
3180         settings->op[i].aarg0 = aarg0;
3181         settings->op[i].aarg1 = aarg1;
3182         settings->op[i].aarg2 = aarg2;
3183
3184         if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP)
3185             settings->op[i].dst = tempreg;
3186         else
3187             settings->op[i].dst = resultreg;
3188     }
3189
3190     /* Clear unsupported stages */
3191     for(; i < MAX_TEXTURES; i++) {
3192         memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
3193     }
3194
3195     if (!state->render_states[WINED3D_RS_FOGENABLE])
3196     {
3197         settings->fog = FOG_OFF;
3198     }
3199     else if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
3200     {
3201         if (use_vs(state) || state->vertex_declaration->position_transformed)
3202         {
3203             settings->fog = FOG_LINEAR;
3204         }
3205         else
3206         {
3207             switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
3208             {
3209                 case WINED3D_FOG_NONE:
3210                 case WINED3D_FOG_LINEAR:
3211                     settings->fog = FOG_LINEAR;
3212                     break;
3213                 case WINED3D_FOG_EXP:
3214                     settings->fog = FOG_EXP;
3215                     break;
3216                 case WINED3D_FOG_EXP2:
3217                     settings->fog = FOG_EXP2;
3218                     break;
3219             }
3220         }
3221     }
3222     else
3223     {
3224         switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
3225         {
3226             case WINED3D_FOG_LINEAR:
3227                 settings->fog = FOG_LINEAR;
3228                 break;
3229             case WINED3D_FOG_EXP:
3230                 settings->fog = FOG_EXP;
3231                 break;
3232             case WINED3D_FOG_EXP2:
3233                 settings->fog = FOG_EXP2;
3234                 break;
3235         }
3236     }
3237     if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB]
3238             && state->render_states[WINED3D_RS_SRGBWRITEENABLE]
3239             && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
3240     {
3241         settings->sRGB_write = 1;
3242     } else {
3243         settings->sRGB_write = 0;
3244     }
3245     if (device->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
3246             || !state->render_states[WINED3D_RS_CLIPPLANEENABLE])
3247     {
3248         /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3249          * the fixed function vertex pipeline is used(which always supports clipplanes), or
3250          * if no clipplane is enabled
3251          */
3252         settings->emul_clipplanes = 0;
3253     } else {
3254         settings->emul_clipplanes = 1;
3255     }
3256 }
3257
3258 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3259         const struct ffp_frag_settings *settings)
3260 {
3261     struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3262     return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3263 }
3264
3265 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3266 {
3267     /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3268      * whereas desc points to an extended structure with implementation specific parts. */
3269     if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3270     {
3271         ERR("Failed to insert ffp frag shader.\n");
3272     }
3273 }
3274
3275 /* Activates the texture dimension according to the bound D3D texture. Does
3276  * not care for the colorop or correct gl texture unit (when using nvrc).
3277  * Requires the caller to activate the correct unit. */
3278 /* Context activation is done by the caller (state handler). */
3279 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3280 {
3281     if (texture)
3282     {
3283         switch (texture->target)
3284         {
3285             case GL_TEXTURE_2D:
3286                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3287                 checkGLcall("glDisable(GL_TEXTURE_3D)");
3288                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3289                 {
3290                     gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3291                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3292                 }
3293                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3294                 {
3295                     gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3296                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3297                 }
3298                 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3299                 checkGLcall("glEnable(GL_TEXTURE_2D)");
3300                 break;
3301             case GL_TEXTURE_RECTANGLE_ARB:
3302                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3303                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3304                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3305                 checkGLcall("glDisable(GL_TEXTURE_3D)");
3306                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3307                 {
3308                     gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3309                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3310                 }
3311                 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_RECTANGLE_ARB);
3312                 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3313                 break;
3314             case GL_TEXTURE_3D:
3315                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3316                 {
3317                     gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3318                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3319                 }
3320                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3321                 {
3322                     gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3323                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3324                 }
3325                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3326                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3327                 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D);
3328                 checkGLcall("glEnable(GL_TEXTURE_3D)");
3329                 break;
3330             case GL_TEXTURE_CUBE_MAP_ARB:
3331                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3332                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3333                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3334                 checkGLcall("glDisable(GL_TEXTURE_3D)");
3335                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3336                 {
3337                     gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3338                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3339                 }
3340                 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3341                 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3342               break;
3343         }
3344     }
3345     else
3346     {
3347         gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3348         checkGLcall("glEnable(GL_TEXTURE_2D)");
3349         gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3350         checkGLcall("glDisable(GL_TEXTURE_3D)");
3351         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3352         {
3353             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3354             checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3355         }
3356         if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3357         {
3358             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3359             checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3360         }
3361         /* Binding textures is done by samplers. A dummy texture will be bound */
3362     }
3363 }
3364
3365 /* Context activation is done by the caller (state handler). */
3366 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3367 {
3368     DWORD sampler = state_id - STATE_SAMPLER(0);
3369     DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
3370
3371     /* No need to enable / disable anything here for unused samplers. The
3372      * tex_colorop handler takes care. Also no action is needed with pixel
3373      * shaders, or if tex_colorop will take care of this business. */
3374     if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
3375         return;
3376     if (sampler >= state->lowest_disabled_stage)
3377         return;
3378     if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)))
3379         return;
3380
3381     texture_activate_dimensions(state->textures[sampler], context->gl_info);
3382 }
3383
3384 void *wined3d_rb_alloc(size_t size)
3385 {
3386     return HeapAlloc(GetProcessHeap(), 0, size);
3387 }
3388
3389 void *wined3d_rb_realloc(void *ptr, size_t size)
3390 {
3391     return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3392 }
3393
3394 void wined3d_rb_free(void *ptr)
3395 {
3396     HeapFree(GetProcessHeap(), 0, ptr);
3397 }
3398
3399 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3400 {
3401     const struct ffp_frag_settings *ka = key;
3402     const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3403
3404     return memcmp(ka, kb, sizeof(*ka));
3405 }
3406
3407 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3408 {
3409     wined3d_rb_alloc,
3410     wined3d_rb_realloc,
3411     wined3d_rb_free,
3412     ffp_frag_program_key_compare,
3413 };
3414
3415 UINT wined3d_log2i(UINT32 x)
3416 {
3417     static const UINT l[] =
3418     {
3419         ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3420           4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3421           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3422           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3423           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3424           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3425           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3426           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3427           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3428           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3429           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3430           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3431           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3432           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3433           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3434           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3435     };
3436     UINT32 i;
3437
3438     return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3439 }
3440
3441 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3442         const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
3443         const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
3444 {
3445     static const struct blit_shader * const blitters[] =
3446     {
3447         &arbfp_blit,
3448         &ffp_blit,
3449         &cpu_blit,
3450     };
3451     unsigned int i;
3452
3453     for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3454     {
3455         if (blitters[i]->blit_supported(gl_info, blit_op,
3456                 src_rect, src_usage, src_pool, src_format,
3457                 dst_rect, dst_usage, dst_pool, dst_format))
3458             return blitters[i];
3459     }
3460
3461     return NULL;
3462 }
3463
3464 void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
3465 {
3466     const struct wined3d_viewport *vp = &state->viewport;
3467
3468     SetRect(rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
3469
3470     if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
3471         IntersectRect(rect, rect, &state->scissor_rect);
3472 }