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