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