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