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