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