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