wined3d: Drop the VBO when the GL alignment doesn't fit on dynamic buffers.
[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     GL_SupportedExt 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 endianess 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,
619             ARB_TEXTURE_FLOAT,          NULL},
620     {WINED3DFMT_R32_FLOAT,              GL_R32F,                          GL_R32F,                                0,
621             GL_RED,                     GL_FLOAT,                         0,
622             WINED3DFMT_FLAG_RENDERTARGET,
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,
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,
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,
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,
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,
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,
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,
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,
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     }
927
928     for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
929     {
930         int fmt_idx = getFmtIdx(format_base_flags[i].id);
931
932         if (fmt_idx == -1)
933         {
934             ERR("Format %s (%#x) not found.\n",
935                     debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
936             HeapFree(GetProcessHeap(), 0, gl_info->formats);
937             return FALSE;
938         }
939
940         gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
941     }
942
943     return TRUE;
944 }
945
946 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
947 {
948     unsigned int i;
949
950     for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
951     {
952         struct wined3d_format *format;
953         int fmt_idx = getFmtIdx(format_compression_info[i].id);
954
955         if (fmt_idx == -1)
956         {
957             ERR("Format %s (%#x) not found.\n",
958                     debug_d3dformat(format_compression_info[i].id), format_compression_info[i].id);
959             return FALSE;
960         }
961
962         format = &gl_info->formats[fmt_idx];
963         format->block_width = format_compression_info[i].block_width;
964         format->block_height = format_compression_info[i].block_height;
965         format->block_byte_count = format_compression_info[i].block_byte_count;
966         format->flags |= WINED3DFMT_FLAG_COMPRESSED;
967     }
968
969     return TRUE;
970 }
971
972 /* Context activation is done by the caller. */
973 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
974 {
975     /* Check if the default internal format is supported as a frame buffer
976      * target, otherwise fall back to the render target internal.
977      *
978      * Try to stick to the standard format if possible, this limits precision differences. */
979     GLenum status;
980     GLuint tex;
981
982     ENTER_GL();
983
984     while(glGetError());
985     glDisable(GL_BLEND);
986
987     glGenTextures(1, &tex);
988     glBindTexture(GL_TEXTURE_2D, tex);
989
990     glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
991     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
992     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
993
994     gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
995
996     status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
997     checkGLcall("Framebuffer format check");
998
999     if (status == GL_FRAMEBUFFER_COMPLETE)
1000     {
1001         TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1002         format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1003         format->rtInternal = format->glInternal;
1004     }
1005     else
1006     {
1007         if (!format->rtInternal)
1008         {
1009             if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1010             {
1011                 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1012                         " and no fallback specified.\n", debug_d3dformat(format->id));
1013                 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1014             }
1015             else
1016             {
1017                 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1018             }
1019             format->rtInternal = format->glInternal;
1020         }
1021         else
1022         {
1023             TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1024                     debug_d3dformat(format->id));
1025
1026             while(glGetError());
1027
1028             gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1029
1030             glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1031             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1032             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1033
1034             gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1035
1036             status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1037             checkGLcall("Framebuffer format check");
1038
1039             if (status == GL_FRAMEBUFFER_COMPLETE)
1040             {
1041                 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1042                         debug_d3dformat(format->id));
1043             }
1044             else
1045             {
1046                 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1047                         debug_d3dformat(format->id));
1048                 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1049             }
1050         }
1051     }
1052
1053     if (status == GL_FRAMEBUFFER_COMPLETE && format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1054     {
1055         GLuint rb;
1056
1057         if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1058                 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1059         {
1060             gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1061             gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1062             gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1063             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1064             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1065             checkGLcall("RB attachment");
1066         }
1067
1068         glEnable(GL_BLEND);
1069         glClear(GL_COLOR_BUFFER_BIT);
1070         if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1071         {
1072             while(glGetError());
1073             TRACE("Format doesn't support post-pixelshader blending.\n");
1074             format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1075         }
1076
1077         if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1078                 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1079         {
1080             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1081             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1082             gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1083             checkGLcall("RB cleanup");
1084         }
1085     }
1086
1087     if (format->glInternal != format->glGammaInternal)
1088     {
1089         glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1090         gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1091
1092         status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1093         checkGLcall("Framebuffer format check");
1094
1095         if (status == GL_FRAMEBUFFER_COMPLETE)
1096         {
1097             TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1098             format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1099         }
1100         else
1101         {
1102             WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1103         }
1104     }
1105
1106     glDeleteTextures(1, &tex);
1107
1108     LEAVE_GL();
1109 }
1110
1111 /* Context activation is done by the caller. */
1112 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1113 {
1114     unsigned int i;
1115     GLuint fbo;
1116
1117     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1118     {
1119         ENTER_GL();
1120
1121         gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1122         gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1123
1124         LEAVE_GL();
1125     }
1126
1127     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1128     {
1129         struct wined3d_format *format = &gl_info->formats[i];
1130
1131         if (!format->glInternal) continue;
1132
1133         if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1134         {
1135             TRACE("Skipping format %s because it's a depth/stencil format.\n",
1136                     debug_d3dformat(format->id));
1137             continue;
1138         }
1139
1140         if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1141         {
1142             TRACE("Skipping format %s because it's a compressed format.\n",
1143                     debug_d3dformat(format->id));
1144             continue;
1145         }
1146
1147         if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1148         {
1149             TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1150             check_fbo_compat(gl_info, format);
1151         }
1152         else
1153         {
1154             format->rtInternal = format->glInternal;
1155         }
1156     }
1157
1158     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1159     {
1160         ENTER_GL();
1161
1162         gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1163
1164         LEAVE_GL();
1165     }
1166 }
1167
1168 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1169 {
1170     unsigned int i;
1171
1172     for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1173     {
1174         int fmt_idx = getFmtIdx(format_texture_info[i].id);
1175         struct wined3d_format *format;
1176
1177         if (fmt_idx == -1)
1178         {
1179             ERR("Format %s (%#x) not found.\n",
1180                     debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1181             return FALSE;
1182         }
1183
1184         if (!gl_info->supported[format_texture_info[i].extension]) continue;
1185
1186         format = &gl_info->formats[fmt_idx];
1187
1188         /* ARB_texture_rg defines floating point formats, but only if
1189          * ARB_texture_float is also supported. */
1190         if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1191                 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1192             continue;
1193
1194         format->glInternal = format_texture_info[i].gl_internal;
1195         format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1196         format->rtInternal = format_texture_info[i].gl_rt_internal;
1197         format->glFormat = format_texture_info[i].gl_format;
1198         format->glType = format_texture_info[i].gl_type;
1199         format->color_fixup = COLOR_FIXUP_IDENTITY;
1200         format->flags |= format_texture_info[i].flags;
1201         format->heightscale = 1.0f;
1202
1203         if (format->glGammaInternal != format->glInternal)
1204         {
1205             /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1206             if (!gl_info->supported[EXT_TEXTURE_SRGB])
1207             {
1208                 format->glGammaInternal = format->glInternal;
1209                 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1210             }
1211             else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1212             {
1213                 format->glInternal = format->glGammaInternal;
1214             }
1215         }
1216
1217         /* Texture conversion stuff */
1218         format->convert = format_texture_info[i].convert;
1219         format->conv_byte_count = format_texture_info[i].conv_byte_count;
1220     }
1221
1222     return TRUE;
1223 }
1224
1225 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1226 {
1227     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1228     c1 >>= 8; c2 >>= 8;
1229     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1230     c1 >>= 8; c2 >>= 8;
1231     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1232     c1 >>= 8; c2 >>= 8;
1233     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1234     return TRUE;
1235 }
1236
1237 /* A context is provided by the caller */
1238 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1239 {
1240     static const DWORD data[] = {0x00000000, 0xffffffff};
1241     GLuint tex, fbo, buffer;
1242     DWORD readback[16 * 1];
1243     BOOL ret = FALSE;
1244
1245     /* Render a filtered texture and see what happens. This is intended to detect the lack of
1246      * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1247      * falling back to software. If this changes in the future this code will get fooled and
1248      * apps might hit the software path due to incorrectly advertised caps.
1249      *
1250      * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1251      * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1252      * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1253      */
1254
1255     ENTER_GL();
1256     while(glGetError());
1257
1258     glGenTextures(1, &buffer);
1259     glBindTexture(GL_TEXTURE_2D, buffer);
1260     memset(readback, 0x7e, sizeof(readback));
1261     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1262     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1263     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1264     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1265     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1266     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1267
1268     glGenTextures(1, &tex);
1269     glBindTexture(GL_TEXTURE_2D, tex);
1270     glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1271     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1272     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1273     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1274     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1275     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1276     glEnable(GL_TEXTURE_2D);
1277
1278     gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1279     gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1280     gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1281     glDrawBuffer(GL_COLOR_ATTACHMENT0);
1282
1283     glViewport(0, 0, 16, 1);
1284     glDisable(GL_LIGHTING);
1285     glMatrixMode(GL_MODELVIEW);
1286     glLoadIdentity();
1287     glMatrixMode(GL_PROJECTION);
1288     glLoadIdentity();
1289
1290     glClearColor(0, 1, 0, 0);
1291     glClear(GL_COLOR_BUFFER_BIT);
1292
1293     glBegin(GL_TRIANGLE_STRIP);
1294     glTexCoord2f(0.0, 0.0);
1295     glVertex2f(-1.0f, -1.0f);
1296     glTexCoord2f(1.0, 0.0);
1297     glVertex2f(1.0f, -1.0f);
1298     glTexCoord2f(0.0, 1.0);
1299     glVertex2f(-1.0f, 1.0f);
1300     glTexCoord2f(1.0, 1.0);
1301     glVertex2f(1.0f, 1.0f);
1302     glEnd();
1303
1304     glBindTexture(GL_TEXTURE_2D, buffer);
1305     memset(readback, 0x7f, sizeof(readback));
1306     glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1307     if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1308        color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1309     {
1310         TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1311               readback[6], readback[9]);
1312         ret = FALSE;
1313     }
1314     else
1315     {
1316         TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1317               readback[6], readback[9]);
1318         ret = TRUE;
1319     }
1320
1321     gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1322     gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1323     glDeleteTextures(1, &tex);
1324     glDeleteTextures(1, &buffer);
1325
1326     if(glGetError())
1327     {
1328         FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1329         ret = FALSE;
1330     }
1331     LEAVE_GL();
1332     return ret;
1333 }
1334
1335 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1336 {
1337     struct wined3d_format *format;
1338     unsigned int fmt_idx, i;
1339     static const enum wined3d_format_id fmts16[] =
1340     {
1341         WINED3DFMT_R16_FLOAT,
1342         WINED3DFMT_R16G16_FLOAT,
1343         WINED3DFMT_R16G16B16A16_FLOAT,
1344     };
1345     BOOL filtered;
1346
1347     if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1348     {
1349         WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1350         if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1351         {
1352             TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1353             filtered = TRUE;
1354         }
1355         else if (gl_info->limits.glsl_varyings > 44)
1356         {
1357             TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1358             filtered = TRUE;
1359         }
1360         else
1361         {
1362             TRACE("Assuming no float16 blending\n");
1363             filtered = FALSE;
1364         }
1365
1366         if(filtered)
1367         {
1368             for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1369             {
1370                 fmt_idx = getFmtIdx(fmts16[i]);
1371                 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1372             }
1373         }
1374         return;
1375     }
1376
1377     for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1378     {
1379         fmt_idx = getFmtIdx(fmts16[i]);
1380         format = &gl_info->formats[fmt_idx];
1381         if (!format->glInternal) continue; /* Not supported by GL */
1382
1383         filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1384         if(filtered)
1385         {
1386             TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1387             format->flags |= WINED3DFMT_FLAG_FILTERING;
1388         }
1389         else
1390         {
1391             TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1392         }
1393     }
1394 }
1395
1396 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1397 {
1398     int idx;
1399
1400     idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1401     gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1402             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1403
1404     idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1405     gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1406             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1407
1408     idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1409     gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1410             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1411
1412     idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1413     gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1414             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1415
1416     idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1417     gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1418             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1419
1420     /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1421      * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1422      * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1423      * the only driver that implements it(fglrx) has a buggy implementation.
1424      *
1425      * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1426      * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1427      * conversion for this format.
1428      */
1429     if (!gl_info->supported[NV_TEXTURE_SHADER])
1430     {
1431         idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1432         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1433                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1434         idx = getFmtIdx(WINED3DFMT_R16G16_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     }
1438     else
1439     {
1440         idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1441         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1442                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1443
1444         idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1445         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1446                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1447     }
1448
1449     if (!gl_info->supported[NV_TEXTURE_SHADER])
1450     {
1451         /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1452          * with each other
1453          */
1454         idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1455         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1456                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1457         idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1458         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1459                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1460         idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1461         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1462                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1463     }
1464     else
1465     {
1466         /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1467          * are converted at surface loading time, but they do not need any modification in
1468          * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1469          * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1470          */
1471     }
1472
1473     if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1474     {
1475         idx = getFmtIdx(WINED3DFMT_ATI2N);
1476         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1477                 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1478     }
1479     else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1480     {
1481         idx = getFmtIdx(WINED3DFMT_ATI2N);
1482         gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1483                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1484     }
1485
1486     if (!gl_info->supported[APPLE_YCBCR_422])
1487     {
1488         idx = getFmtIdx(WINED3DFMT_YUY2);
1489         gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1490
1491         idx = getFmtIdx(WINED3DFMT_UYVY);
1492         gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1493     }
1494
1495     idx = getFmtIdx(WINED3DFMT_YV12);
1496     gl_info->formats[idx].heightscale = 1.5f;
1497     gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1498
1499     if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1500     {
1501         idx = getFmtIdx(WINED3DFMT_P8_UINT);
1502         gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1503     }
1504
1505     if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1506     {
1507         idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1508         gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1509     }
1510
1511     if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1512     {
1513         /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1514          * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1515         idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1516         gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1517
1518         idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1519         gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1520     }
1521 }
1522
1523 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1524 {
1525     unsigned int i;
1526
1527     for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1528     {
1529         struct wined3d_format *format;
1530         int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1531
1532         if (fmt_idx == -1)
1533         {
1534             ERR("Format %s (%#x) not found.\n",
1535                     debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1536             return FALSE;
1537         }
1538
1539         format = &gl_info->formats[fmt_idx];
1540         format->emit_idx = format_vertex_info[i].emit_idx;
1541         format->component_count = format_vertex_info[i].component_count;
1542         format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1543         format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1544         format->gl_normalized = format_vertex_info[i].gl_normalized;
1545         format->component_size = format_vertex_info[i].component_size;
1546     }
1547
1548     return TRUE;
1549 }
1550
1551 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1552 {
1553     if (!init_format_base_info(gl_info)) return FALSE;
1554
1555     if (!init_format_compression_info(gl_info))
1556     {
1557         HeapFree(GetProcessHeap(), 0, gl_info->formats);
1558         gl_info->formats = NULL;
1559         return FALSE;
1560     }
1561
1562     return TRUE;
1563 }
1564
1565 /* Context activation is done by the caller. */
1566 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1567 {
1568     if (!init_format_base_info(gl_info)) return FALSE;
1569
1570     if (!init_format_compression_info(gl_info)) goto fail;
1571     if (!init_format_texture_info(gl_info)) goto fail;
1572     if (!init_format_vertex_info(gl_info)) goto fail;
1573
1574     apply_format_fixups(gl_info);
1575     init_format_fbo_compat_info(gl_info);
1576     init_format_filter_info(gl_info, vendor);
1577
1578     return TRUE;
1579
1580 fail:
1581     HeapFree(GetProcessHeap(), 0, gl_info->formats);
1582     gl_info->formats = NULL;
1583     return FALSE;
1584 }
1585
1586 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1587         enum wined3d_format_id format_id)
1588 {
1589     int idx = getFmtIdx(format_id);
1590
1591     if (idx == -1)
1592     {
1593         FIXME("Can't find format %s (%#x) in the format lookup table\n",
1594                 debug_d3dformat(format_id), format_id);
1595         /* Get the caller a valid pointer */
1596         idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1597     }
1598
1599     return &gl_info->formats[idx];
1600 }
1601
1602 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1603 {
1604     UINT size;
1605
1606     if (format->id == WINED3DFMT_UNKNOWN)
1607     {
1608         size = 0;
1609     }
1610     else if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1611     {
1612         UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1613         UINT row_count = (height + format->block_height - 1) / format->block_height;
1614         size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1615     }
1616     else
1617     {
1618         size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1619     }
1620
1621     if (format->heightscale != 0.0f)
1622     {
1623         /* The D3D format requirements make sure that the resulting format is an integer again */
1624         size = (UINT) (size * format->heightscale);
1625     }
1626
1627     return size;
1628 }
1629
1630 /*****************************************************************************
1631  * Trace formatting of useful values
1632  */
1633 const char *debug_d3dformat(enum wined3d_format_id format_id)
1634 {
1635     switch (format_id)
1636     {
1637 #define FMT_TO_STR(format_id) case format_id: return #format_id
1638         FMT_TO_STR(WINED3DFMT_UNKNOWN);
1639         FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1640         FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1641         FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1642         FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1643         FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1644         FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1645         FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1646         FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1647         FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1648         FMT_TO_STR(WINED3DFMT_P8_UINT);
1649         FMT_TO_STR(WINED3DFMT_L8_UNORM);
1650         FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1651         FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1652         FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1653         FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1654         FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1655         FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1656         FMT_TO_STR(WINED3DFMT_UYVY);
1657         FMT_TO_STR(WINED3DFMT_YUY2);
1658         FMT_TO_STR(WINED3DFMT_YV12);
1659         FMT_TO_STR(WINED3DFMT_DXT1);
1660         FMT_TO_STR(WINED3DFMT_DXT2);
1661         FMT_TO_STR(WINED3DFMT_DXT3);
1662         FMT_TO_STR(WINED3DFMT_DXT4);
1663         FMT_TO_STR(WINED3DFMT_DXT5);
1664         FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1665         FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1666         FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1667         FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1668         FMT_TO_STR(WINED3DFMT_D32_UNORM);
1669         FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1670         FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1671         FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1672         FMT_TO_STR(WINED3DFMT_L16_UNORM);
1673         FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1674         FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1675         FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1676         FMT_TO_STR(WINED3DFMT_ATI2N);
1677         FMT_TO_STR(WINED3DFMT_NVDB);
1678         FMT_TO_STR(WINED3DFMT_NVHU);
1679         FMT_TO_STR(WINED3DFMT_NVHS);
1680         FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1681         FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1682         FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1683         FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1684         FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1685         FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1686         FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1687         FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1688         FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1689         FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1690         FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1691         FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1692         FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1693         FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1694         FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1695         FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1696         FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1697         FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1698         FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1699         FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1700         FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1701         FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1702         FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1703         FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1704         FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1705         FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1706         FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1707         FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1708         FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1709         FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1710         FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1711         FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1712         FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1713         FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1714         FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1715         FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1716         FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1717         FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1718         FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1719         FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1720         FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1721         FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1722         FMT_TO_STR(WINED3DFMT_R32_UINT);
1723         FMT_TO_STR(WINED3DFMT_R32_SINT);
1724         FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1725         FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1726         FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1727         FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1728         FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1729         FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1730         FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1731         FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1732         FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1733         FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1734         FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1735         FMT_TO_STR(WINED3DFMT_D16_UNORM);
1736         FMT_TO_STR(WINED3DFMT_R16_UNORM);
1737         FMT_TO_STR(WINED3DFMT_R16_UINT);
1738         FMT_TO_STR(WINED3DFMT_R16_SNORM);
1739         FMT_TO_STR(WINED3DFMT_R16_SINT);
1740         FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1741         FMT_TO_STR(WINED3DFMT_R8_UNORM);
1742         FMT_TO_STR(WINED3DFMT_R8_UINT);
1743         FMT_TO_STR(WINED3DFMT_R8_SNORM);
1744         FMT_TO_STR(WINED3DFMT_R8_SINT);
1745         FMT_TO_STR(WINED3DFMT_A8_UNORM);
1746         FMT_TO_STR(WINED3DFMT_R1_UNORM);
1747         FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1748         FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1749         FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1750         FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1751         FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1752         FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1753         FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1754         FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1755         FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1756         FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1757         FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1758         FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1759         FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1760         FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1761         FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1762         FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1763         FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1764         FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1765         FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1766         FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1767         FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1768         FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1769         FMT_TO_STR(WINED3DFMT_INTZ);
1770         FMT_TO_STR(WINED3DFMT_NULL);
1771         FMT_TO_STR(WINED3DFMT_R16);
1772         FMT_TO_STR(WINED3DFMT_AL16);
1773 #undef FMT_TO_STR
1774         default:
1775         {
1776             char fourcc[5];
1777             fourcc[0] = (char)(format_id);
1778             fourcc[1] = (char)(format_id >> 8);
1779             fourcc[2] = (char)(format_id >> 16);
1780             fourcc[3] = (char)(format_id >> 24);
1781             fourcc[4] = 0;
1782             if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1783                 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1784             else
1785                 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1786         }
1787         return "unrecognized";
1788     }
1789 }
1790
1791 const char *debug_d3ddevicetype(WINED3DDEVTYPE devtype)
1792 {
1793     switch (devtype)
1794     {
1795 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1796         DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1797         DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1798         DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1799 #undef DEVTYPE_TO_STR
1800         default:
1801             FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1802             return "unrecognized";
1803     }
1804 }
1805
1806 const char *debug_d3dusage(DWORD usage)
1807 {
1808     char buf[333];
1809
1810     buf[0] = '\0';
1811 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1812     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1813     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1814     WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1815     WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1816     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1817     WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1818     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1819     WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1820     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1821     WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1822     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1823     WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1824     WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1825 #undef WINED3DUSAGE_TO_STR
1826     if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1827
1828     return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1829 }
1830
1831 const char *debug_d3dusagequery(DWORD usagequery)
1832 {
1833     char buf[238];
1834
1835     buf[0] = '\0';
1836 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1837     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1838     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1839     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1840     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1841     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1842     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1843     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1844 #undef WINED3DUSAGEQUERY_TO_STR
1845     if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1846
1847     return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1848 }
1849
1850 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1851     switch (method) {
1852 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1853         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1854         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1855         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1856         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1857         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1858         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1859         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1860 #undef WINED3DDECLMETHOD_TO_STR
1861         default:
1862             FIXME("Unrecognized %u declaration method!\n", method);
1863             return "unrecognized";
1864     }
1865 }
1866
1867 const char* debug_d3ddeclusage(BYTE usage) {
1868     switch (usage) {
1869 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1870         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1871         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1872         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1873         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1874         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1875         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1876         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1877         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1878         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1879         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1880         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1881         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1882         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1883         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1884 #undef WINED3DDECLUSAGE_TO_STR
1885         default:
1886             FIXME("Unrecognized %u declaration usage!\n", usage);
1887             return "unrecognized";
1888     }
1889 }
1890
1891 const char *debug_d3dresourcetype(WINED3DRESOURCETYPE res)
1892 {
1893     switch (res)
1894     {
1895 #define RES_TO_STR(res) case res: return #res
1896         RES_TO_STR(WINED3DRTYPE_SURFACE);
1897         RES_TO_STR(WINED3DRTYPE_VOLUME);
1898         RES_TO_STR(WINED3DRTYPE_TEXTURE);
1899         RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1900         RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1901         RES_TO_STR(WINED3DRTYPE_BUFFER);
1902 #undef  RES_TO_STR
1903         default:
1904             FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1905             return "unrecognized";
1906     }
1907 }
1908
1909 const char *debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType)
1910 {
1911     switch (PrimitiveType)
1912     {
1913 #define PRIM_TO_STR(prim) case prim: return #prim
1914         PRIM_TO_STR(WINED3DPT_UNDEFINED);
1915         PRIM_TO_STR(WINED3DPT_POINTLIST);
1916         PRIM_TO_STR(WINED3DPT_LINELIST);
1917         PRIM_TO_STR(WINED3DPT_LINESTRIP);
1918         PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1919         PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1920         PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1921         PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1922         PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1923         PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1924         PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1925 #undef  PRIM_TO_STR
1926         default:
1927             FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1928             return "unrecognized";
1929     }
1930 }
1931
1932 const char *debug_d3drenderstate(WINED3DRENDERSTATETYPE state)
1933 {
1934     switch (state)
1935     {
1936 #define D3DSTATE_TO_STR(u) case u: return #u
1937         D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS);
1938         D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE);
1939         D3DSTATE_TO_STR(WINED3DRS_WRAPU);
1940         D3DSTATE_TO_STR(WINED3DRS_WRAPV);
1941         D3DSTATE_TO_STR(WINED3DRS_ZENABLE);
1942         D3DSTATE_TO_STR(WINED3DRS_FILLMODE);
1943         D3DSTATE_TO_STR(WINED3DRS_SHADEMODE);
1944         D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN);
1945         D3DSTATE_TO_STR(WINED3DRS_MONOENABLE);
1946         D3DSTATE_TO_STR(WINED3DRS_ROP2);
1947         D3DSTATE_TO_STR(WINED3DRS_PLANEMASK);
1948         D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE);
1949         D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE);
1950         D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL);
1951         D3DSTATE_TO_STR(WINED3DRS_SRCBLEND);
1952         D3DSTATE_TO_STR(WINED3DRS_DESTBLEND);
1953         D3DSTATE_TO_STR(WINED3DRS_CULLMODE);
1954         D3DSTATE_TO_STR(WINED3DRS_ZFUNC);
1955         D3DSTATE_TO_STR(WINED3DRS_ALPHAREF);
1956         D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC);
1957         D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE);
1958         D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE);
1959         D3DSTATE_TO_STR(WINED3DRS_FOGENABLE);
1960         D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE);
1961         D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE);
1962         D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL);
1963         D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX);
1964         D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA);
1965         D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR);
1966         D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE);
1967         D3DSTATE_TO_STR(WINED3DRS_FOGSTART);
1968         D3DSTATE_TO_STR(WINED3DRS_FOGEND);
1969         D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY);
1970         D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE);
1971         D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS);
1972         D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE);
1973         D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS);
1974         D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE);
1975         D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY);
1976         D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH);
1977         D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1978         D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE);
1979         D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL);
1980         D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL);
1981         D3DSTATE_TO_STR(WINED3DRS_STENCILPASS);
1982         D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC);
1983         D3DSTATE_TO_STR(WINED3DRS_STENCILREF);
1984         D3DSTATE_TO_STR(WINED3DRS_STENCILMASK);
1985         D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK);
1986         D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR);
1987         D3DSTATE_TO_STR(WINED3DRS_WRAP0);
1988         D3DSTATE_TO_STR(WINED3DRS_WRAP1);
1989         D3DSTATE_TO_STR(WINED3DRS_WRAP2);
1990         D3DSTATE_TO_STR(WINED3DRS_WRAP3);
1991         D3DSTATE_TO_STR(WINED3DRS_WRAP4);
1992         D3DSTATE_TO_STR(WINED3DRS_WRAP5);
1993         D3DSTATE_TO_STR(WINED3DRS_WRAP6);
1994         D3DSTATE_TO_STR(WINED3DRS_WRAP7);
1995         D3DSTATE_TO_STR(WINED3DRS_CLIPPING);
1996         D3DSTATE_TO_STR(WINED3DRS_LIGHTING);
1997         D3DSTATE_TO_STR(WINED3DRS_EXTENTS);
1998         D3DSTATE_TO_STR(WINED3DRS_AMBIENT);
1999         D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE);
2000         D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX);
2001         D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER);
2002         D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS);
2003         D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE);
2004         D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE);
2005         D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE);
2006         D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE);
2007         D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE);
2008         D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND);
2009         D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE);
2010         D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING);
2011         D3DSTATE_TO_STR(WINED3DRS_POINTSIZE);
2012         D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN);
2013         D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE);
2014         D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE);
2015         D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A);
2016         D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B);
2017         D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C);
2018         D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS);
2019         D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK);
2020         D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE);
2021         D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS);
2022         D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN);
2023         D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX);
2024         D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE);
2025         D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE);
2026         D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR);
2027         D3DSTATE_TO_STR(WINED3DRS_BLENDOP);
2028         D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE);
2029         D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE);
2030         D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE);
2031         D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS);
2032         D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE);
2033         D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL);
2034         D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL);
2035         D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X);
2036         D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y);
2037         D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z);
2038         D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W);
2039         D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
2040         D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE);
2041         D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL);
2042         D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL);
2043         D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS);
2044         D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC);
2045         D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1);
2046         D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2);
2047         D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3);
2048         D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR);
2049         D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE);
2050         D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS);
2051         D3DSTATE_TO_STR(WINED3DRS_WRAP8);
2052         D3DSTATE_TO_STR(WINED3DRS_WRAP9);
2053         D3DSTATE_TO_STR(WINED3DRS_WRAP10);
2054         D3DSTATE_TO_STR(WINED3DRS_WRAP11);
2055         D3DSTATE_TO_STR(WINED3DRS_WRAP12);
2056         D3DSTATE_TO_STR(WINED3DRS_WRAP13);
2057         D3DSTATE_TO_STR(WINED3DRS_WRAP14);
2058         D3DSTATE_TO_STR(WINED3DRS_WRAP15);
2059         D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE);
2060         D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA);
2061         D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA);
2062         D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA);
2063 #undef D3DSTATE_TO_STR
2064         default:
2065             FIXME("Unrecognized %u render state!\n", state);
2066             return "unrecognized";
2067     }
2068 }
2069
2070 const char *debug_d3dsamplerstate(DWORD state)
2071 {
2072     switch (state)
2073     {
2074 #define D3DSTATE_TO_STR(u) case u: return #u
2075         D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR);
2076         D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU);
2077         D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV);
2078         D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW);
2079         D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER);
2080         D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER);
2081         D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER);
2082         D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
2083         D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL);
2084         D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
2085         D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE);
2086         D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX);
2087         D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET);
2088 #undef D3DSTATE_TO_STR
2089         default:
2090             FIXME("Unrecognized %u sampler state!\n", state);
2091             return "unrecognized";
2092     }
2093 }
2094
2095 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2096     switch (filter_type) {
2097 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2098         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2099         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2100         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2101         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2102         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2103         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2104         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2105         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2106 #undef D3DTEXTUREFILTERTYPE_TO_STR
2107         default:
2108             FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2109             return "unrecognized";
2110     }
2111 }
2112
2113 const char *debug_d3dtexturestate(DWORD state)
2114 {
2115     switch (state)
2116     {
2117 #define D3DSTATE_TO_STR(u) case u: return #u
2118         D3DSTATE_TO_STR(WINED3DTSS_COLOROP);
2119         D3DSTATE_TO_STR(WINED3DTSS_COLORARG1);
2120         D3DSTATE_TO_STR(WINED3DTSS_COLORARG2);
2121         D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP);
2122         D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1);
2123         D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2);
2124         D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00);
2125         D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01);
2126         D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10);
2127         D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11);
2128         D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX);
2129         D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE);
2130         D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET);
2131         D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS);
2132         D3DSTATE_TO_STR(WINED3DTSS_COLORARG0);
2133         D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0);
2134         D3DSTATE_TO_STR(WINED3DTSS_RESULTARG);
2135         D3DSTATE_TO_STR(WINED3DTSS_CONSTANT);
2136 #undef D3DSTATE_TO_STR
2137         default:
2138             FIXME("Unrecognized %u texture state!\n", state);
2139             return "unrecognized";
2140     }
2141 }
2142
2143 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2144     switch (d3dtop) {
2145 #define D3DTOP_TO_STR(u) case u: return #u
2146         D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2147         D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2148         D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2149         D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2150         D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2151         D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2152         D3DTOP_TO_STR(WINED3DTOP_ADD);
2153         D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2154         D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2155         D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2156         D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2157         D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2158         D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2159         D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2160         D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2161         D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2162         D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2163         D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2164         D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2165         D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2166         D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2167         D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2168         D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2169         D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2170         D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2171         D3DTOP_TO_STR(WINED3DTOP_LERP);
2172 #undef D3DTOP_TO_STR
2173         default:
2174             FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2175             return "unrecognized";
2176     }
2177 }
2178
2179 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2180     switch (tstype) {
2181 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2182     TSTYPE_TO_STR(WINED3DTS_VIEW);
2183     TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2184     TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2185     TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2186     TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2187     TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2188     TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2189     TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2190     TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2191     TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2192     TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2193 #undef TSTYPE_TO_STR
2194     default:
2195         if (tstype > 256 && tstype < 512) {
2196             FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2197             return ("WINED3DTS_WORLDMATRIX > 0");
2198         }
2199         FIXME("Unrecognized %u WINED3DTS\n", tstype);
2200         return "unrecognized";
2201     }
2202 }
2203
2204 const char *debug_d3dstate(DWORD state)
2205 {
2206     if (STATE_IS_RENDER(state))
2207         return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2208     if (STATE_IS_TEXTURESTAGE(state))
2209     {
2210         DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2211         DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2212         return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2213                 texture_stage, debug_d3dtexturestate(texture_state));
2214     }
2215     if (STATE_IS_SAMPLER(state))
2216         return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2217     if (STATE_IS_PIXELSHADER(state))
2218         return "STATE_PIXELSHADER";
2219     if (STATE_IS_TRANSFORM(state))
2220         return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2221     if (STATE_IS_STREAMSRC(state))
2222         return "STATE_STREAMSRC";
2223     if (STATE_IS_INDEXBUFFER(state))
2224         return "STATE_INDEXBUFFER";
2225     if (STATE_IS_VDECL(state))
2226         return "STATE_VDECL";
2227     if (STATE_IS_VSHADER(state))
2228         return "STATE_VSHADER";
2229     if (STATE_IS_VIEWPORT(state))
2230         return "STATE_VIEWPORT";
2231     if (STATE_IS_VERTEXSHADERCONSTANT(state))
2232         return "STATE_VERTEXSHADERCONSTANT";
2233     if (STATE_IS_PIXELSHADERCONSTANT(state))
2234         return "STATE_PIXELSHADERCONSTANT";
2235     if (STATE_IS_ACTIVELIGHT(state))
2236         return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2237     if (STATE_IS_SCISSORRECT(state))
2238         return "STATE_SCISSORRECT";
2239     if (STATE_IS_CLIPPLANE(state))
2240         return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2241     if (STATE_IS_MATERIAL(state))
2242         return "STATE_MATERIAL";
2243     if (STATE_IS_FRONTFACE(state))
2244         return "STATE_FRONTFACE";
2245     if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2246         return "STATE_POINTSPRITECOORDORIGIN";
2247     if (STATE_IS_BASEVERTEXINDEX(state))
2248         return "STATE_BASEVERTEXINDEX";
2249
2250     return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2251 }
2252
2253 const char *debug_d3dpool(WINED3DPOOL pool)
2254 {
2255     switch (pool)
2256     {
2257 #define POOL_TO_STR(p) case p: return #p
2258         POOL_TO_STR(WINED3DPOOL_DEFAULT);
2259         POOL_TO_STR(WINED3DPOOL_MANAGED);
2260         POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2261         POOL_TO_STR(WINED3DPOOL_SCRATCH);
2262 #undef  POOL_TO_STR
2263         default:
2264             FIXME("Unrecognized %u WINED3DPOOL!\n", pool);
2265             return "unrecognized";
2266     }
2267 }
2268
2269 const char *debug_fbostatus(GLenum status) {
2270     switch(status) {
2271 #define FBOSTATUS_TO_STR(u) case u: return #u
2272         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2273         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2274         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2275         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2276         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2277         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2278         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2279         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2280         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2281         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2282 #undef FBOSTATUS_TO_STR
2283         default:
2284             FIXME("Unrecognied FBO status 0x%08x\n", status);
2285             return "unrecognized";
2286     }
2287 }
2288
2289 const char *debug_glerror(GLenum error) {
2290     switch(error) {
2291 #define GLERROR_TO_STR(u) case u: return #u
2292         GLERROR_TO_STR(GL_NO_ERROR);
2293         GLERROR_TO_STR(GL_INVALID_ENUM);
2294         GLERROR_TO_STR(GL_INVALID_VALUE);
2295         GLERROR_TO_STR(GL_INVALID_OPERATION);
2296         GLERROR_TO_STR(GL_STACK_OVERFLOW);
2297         GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2298         GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2299         GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2300 #undef GLERROR_TO_STR
2301         default:
2302             FIXME("Unrecognied GL error 0x%08x\n", error);
2303             return "unrecognized";
2304     }
2305 }
2306
2307 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2308     switch(basis) {
2309         case WINED3DBASIS_BEZIER:       return "WINED3DBASIS_BEZIER";
2310         case WINED3DBASIS_BSPLINE:      return "WINED3DBASIS_BSPLINE";
2311         case WINED3DBASIS_INTERPOLATE:  return "WINED3DBASIS_INTERPOLATE";
2312         default:                        return "unrecognized";
2313     }
2314 }
2315
2316 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2317     switch(degree) {
2318         case WINED3DDEGREE_LINEAR:      return "WINED3DDEGREE_LINEAR";
2319         case WINED3DDEGREE_QUADRATIC:   return "WINED3DDEGREE_QUADRATIC";
2320         case WINED3DDEGREE_CUBIC:       return "WINED3DDEGREE_CUBIC";
2321         case WINED3DDEGREE_QUINTIC:     return "WINED3DDEGREE_QUINTIC";
2322         default:                        return "unrecognized";
2323     }
2324 }
2325
2326 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2327 {
2328     switch(source)
2329     {
2330 #define WINED3D_TO_STR(x) case x: return #x
2331         WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2332         WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2333         WINED3D_TO_STR(CHANNEL_SOURCE_X);
2334         WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2335         WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2336         WINED3D_TO_STR(CHANNEL_SOURCE_W);
2337         WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2338         WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2339 #undef WINED3D_TO_STR
2340         default:
2341             FIXME("Unrecognized fixup_channel_source %#x\n", source);
2342             return "unrecognized";
2343     }
2344 }
2345
2346 static const char *debug_complex_fixup(enum complex_fixup fixup)
2347 {
2348     switch(fixup)
2349     {
2350 #define WINED3D_TO_STR(x) case x: return #x
2351         WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2352         WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2353         WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2354         WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2355 #undef WINED3D_TO_STR
2356         default:
2357             FIXME("Unrecognized complex fixup %#x\n", fixup);
2358             return "unrecognized";
2359     }
2360 }
2361
2362 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2363 {
2364     if (is_complex_fixup(fixup))
2365     {
2366         TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2367         return;
2368     }
2369
2370     TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2371     TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2372     TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2373     TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2374 }
2375
2376 const char *debug_surflocation(DWORD flag) {
2377     char buf[128];
2378
2379     buf[0] = 0;
2380     if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2381     if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2382     if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2383     if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2384     return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2385 }
2386
2387 /*****************************************************************************
2388  * Useful functions mapping GL <-> D3D values
2389  */
2390 GLenum StencilOp(DWORD op) {
2391     switch(op) {
2392     case WINED3DSTENCILOP_KEEP    : return GL_KEEP;
2393     case WINED3DSTENCILOP_ZERO    : return GL_ZERO;
2394     case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2395     case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2396     case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2397     case WINED3DSTENCILOP_INVERT  : return GL_INVERT;
2398     case WINED3DSTENCILOP_INCR    : return GL_INCR_WRAP_EXT;
2399     case WINED3DSTENCILOP_DECR    : return GL_DECR_WRAP_EXT;
2400     default:
2401         FIXME("Unrecognized stencil op %d\n", op);
2402         return GL_KEEP;
2403     }
2404 }
2405
2406 GLenum CompareFunc(DWORD func) {
2407     switch ((WINED3DCMPFUNC)func) {
2408     case WINED3DCMP_NEVER        : return GL_NEVER;
2409     case WINED3DCMP_LESS         : return GL_LESS;
2410     case WINED3DCMP_EQUAL        : return GL_EQUAL;
2411     case WINED3DCMP_LESSEQUAL    : return GL_LEQUAL;
2412     case WINED3DCMP_GREATER      : return GL_GREATER;
2413     case WINED3DCMP_NOTEQUAL     : return GL_NOTEQUAL;
2414     case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2415     case WINED3DCMP_ALWAYS       : return GL_ALWAYS;
2416     default:
2417         FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2418         return 0;
2419     }
2420 }
2421
2422 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2423         WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
2424 {
2425     if (op == WINED3DTOP_DISABLE) return FALSE;
2426     if (state->textures[stage]) return FALSE;
2427
2428     if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2429             && op != WINED3DTOP_SELECTARG2) return TRUE;
2430     if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2431             && op != WINED3DTOP_SELECTARG1) return TRUE;
2432     if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2433             && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2434
2435     return FALSE;
2436 }
2437
2438 /* Setup this textures matrix according to the texture flags*/
2439 /* GL locking is done by the caller (state handler) */
2440 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2441         enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2442 {
2443     float mat[16];
2444
2445     glMatrixMode(GL_TEXTURE);
2446     checkGLcall("glMatrixMode(GL_TEXTURE)");
2447
2448     if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2449         glLoadIdentity();
2450         checkGLcall("glLoadIdentity()");
2451         return;
2452     }
2453
2454     if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2455         ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2456         return;
2457     }
2458
2459     memcpy(mat, smat, 16 * sizeof(float));
2460
2461     if (flags & WINED3DTTFF_PROJECTED) {
2462         if(!ffp_proj_control) {
2463             switch (flags & ~WINED3DTTFF_PROJECTED) {
2464             case WINED3DTTFF_COUNT2:
2465                 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2466                 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2467                 break;
2468             case WINED3DTTFF_COUNT3:
2469                 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2470                 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2471                 break;
2472             }
2473         }
2474     } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2475         if(!calculatedCoords) {
2476             switch(vtx_fmt)
2477             {
2478                 case WINED3DFMT_R32_FLOAT:
2479                     /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2480                      * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2481                      * the input value to the transformation will be 0, so the matrix value is irrelevant
2482                      */
2483                     mat[12] = mat[4];
2484                     mat[13] = mat[5];
2485                     mat[14] = mat[6];
2486                     mat[15] = mat[7];
2487                     break;
2488                 case WINED3DFMT_R32G32_FLOAT:
2489                     /* See above, just 3rd and 4th coord
2490                     */
2491                     mat[12] = mat[8];
2492                     mat[13] = mat[9];
2493                     mat[14] = mat[10];
2494                     mat[15] = mat[11];
2495                     break;
2496                 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2497                 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2498
2499                 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2500                  * into a bad place. The division elimination below will apply to make sure the
2501                  * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2502                  */
2503                 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2504                     break;
2505                 default:
2506                     FIXME("Unexpected fixed function texture coord input\n");
2507             }
2508         }
2509         if(!ffp_proj_control) {
2510             switch (flags & ~WINED3DTTFF_PROJECTED) {
2511                 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2512                 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2513                 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2514                 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2515                 * the 4th coord evaluates to 1.0 to eliminate that.
2516                 *
2517                 * If the fixed function pipeline is used, the 4th value remains unused,
2518                 * so there is no danger in doing this. With vertex shaders we have a
2519                 * problem. Should an app hit that problem, the code here would have to
2520                 * check for pixel shaders, and the shader has to undo the default gl divide.
2521                 *
2522                 * A more serious problem occurs if the app passes 4 coordinates in, and the
2523                 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2524                 * or a replacement shader
2525                 */
2526                 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2527             }
2528         }
2529     }
2530
2531     glLoadMatrixf(mat);
2532     checkGLcall("glLoadMatrixf(mat)");
2533 }
2534
2535 /* This small helper function is used to convert a bitmask into the number of masked bits */
2536 unsigned int count_bits(unsigned int mask)
2537 {
2538     unsigned int count;
2539     for (count = 0; mask; ++count)
2540     {
2541         mask &= mask - 1;
2542     }
2543     return count;
2544 }
2545
2546 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2547  * The later function requires individual color components. */
2548 BOOL getColorBits(const struct wined3d_format *format,
2549         BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2550 {
2551     TRACE("format %s.\n", debug_d3dformat(format->id));
2552
2553     switch (format->id)
2554     {
2555         case WINED3DFMT_B10G10R10A2_UNORM:
2556         case WINED3DFMT_R10G10B10A2_UNORM:
2557         case WINED3DFMT_B8G8R8X8_UNORM:
2558         case WINED3DFMT_B8G8R8_UNORM:
2559         case WINED3DFMT_B8G8R8A8_UNORM:
2560         case WINED3DFMT_R8G8B8A8_UNORM:
2561         case WINED3DFMT_B5G5R5X1_UNORM:
2562         case WINED3DFMT_B5G5R5A1_UNORM:
2563         case WINED3DFMT_B5G6R5_UNORM:
2564         case WINED3DFMT_B4G4R4X4_UNORM:
2565         case WINED3DFMT_B4G4R4A4_UNORM:
2566         case WINED3DFMT_B2G3R3_UNORM:
2567         case WINED3DFMT_P8_UINT_A8_UNORM:
2568         case WINED3DFMT_P8_UINT:
2569             break;
2570         default:
2571             FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2572             return FALSE;
2573     }
2574
2575     *redSize = count_bits(format->red_mask);
2576     *greenSize = count_bits(format->green_mask);
2577     *blueSize = count_bits(format->blue_mask);
2578     *alphaSize = count_bits(format->alpha_mask);
2579     *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2580
2581     TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2582             *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2583     return TRUE;
2584 }
2585
2586 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2587 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
2588 {
2589     TRACE("format %s.\n", debug_d3dformat(format->id));
2590
2591     switch (format->id)
2592     {
2593         case WINED3DFMT_D16_LOCKABLE:
2594         case WINED3DFMT_D16_UNORM:
2595         case WINED3DFMT_S1_UINT_D15_UNORM:
2596         case WINED3DFMT_X8D24_UNORM:
2597         case WINED3DFMT_S4X4_UINT_D24_UNORM:
2598         case WINED3DFMT_D24_UNORM_S8_UINT:
2599         case WINED3DFMT_S8_UINT_D24_FLOAT:
2600         case WINED3DFMT_D32_UNORM:
2601         case WINED3DFMT_D32_FLOAT:
2602         case WINED3DFMT_INTZ:
2603             break;
2604         default:
2605             FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2606             return FALSE;
2607     }
2608
2609     *depthSize = format->depth_size;
2610     *stencilSize = format->stencil_size;
2611
2612     TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2613             *depthSize, *stencilSize, debug_d3dformat(format->id));
2614     return TRUE;
2615 }
2616
2617 /* Note: It's the caller's responsibility to ensure values can be expressed
2618  * in the requested format. UNORM formats for example can only express values
2619  * in the range 0.0f -> 1.0f. */
2620 DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, const WINED3DCOLORVALUE *color)
2621 {
2622     static const struct
2623     {
2624         enum wined3d_format_id format_id;
2625         float r_mul;
2626         float g_mul;
2627         float b_mul;
2628         float a_mul;
2629         BYTE r_shift;
2630         BYTE g_shift;
2631         BYTE b_shift;
2632         BYTE a_shift;
2633     }
2634     conv[] =
2635     {
2636         {WINED3DFMT_B8G8R8A8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
2637         {WINED3DFMT_B8G8R8X8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
2638         {WINED3DFMT_B8G8R8_UNORM,       255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
2639         {WINED3DFMT_B5G6R5_UNORM,        31.0f,   63.0f,   31.0f,    0.0f, 11,  5,  0,  0},
2640         {WINED3DFMT_B5G5R5A1_UNORM,      31.0f,   31.0f,   31.0f,    1.0f, 10,  5,  0, 15},
2641         {WINED3DFMT_B5G5R5X1_UNORM,      31.0f,   31.0f,   31.0f,    1.0f, 10,  5,  0, 15},
2642         {WINED3DFMT_A8_UNORM,             0.0f,    0.0f,    0.0f,  255.0f,  0,  0,  0,  0},
2643         {WINED3DFMT_B4G4R4A4_UNORM,      15.0f,   15.0f,   15.0f,   15.0f,  8,  4,  0, 12},
2644         {WINED3DFMT_B4G4R4X4_UNORM,      15.0f,   15.0f,   15.0f,   15.0f,  8,  4,  0, 12},
2645         {WINED3DFMT_B2G3R3_UNORM,         7.0f,    7.0f,    3.0f,    0.0f,  5,  2,  0,  0},
2646         {WINED3DFMT_R8G8B8A8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f,  0,  8, 16, 24},
2647         {WINED3DFMT_R8G8B8X8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f,  0,  8, 16, 24},
2648         {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f,    3.0f, 20, 10,  0, 30},
2649         {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f,    3.0f,  0, 10, 20, 30},
2650     };
2651     unsigned int i;
2652
2653     TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2654             color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2655
2656     for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2657     {
2658         DWORD ret;
2659
2660         if (format->id != conv[i].format_id) continue;
2661
2662         ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2663         ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2664         ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2665         ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2666
2667         TRACE("Returning 0x%08x.\n", ret);
2668
2669         return ret;
2670     }
2671
2672     FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2673
2674     return 0;
2675 }
2676
2677 /* DirectDraw stuff */
2678 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2679 {
2680     switch (depth)
2681     {
2682         case 8:  return WINED3DFMT_P8_UINT;
2683         case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2684         case 16: return WINED3DFMT_B5G6R5_UNORM;
2685         case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2686         case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2687         default: return WINED3DFMT_UNKNOWN;
2688     }
2689 }
2690
2691 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2692     WINED3DMATRIX temp;
2693
2694     /* Now do the multiplication 'by hand'.
2695        I know that all this could be optimised, but this will be done later :-) */
2696     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);
2697     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);
2698     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);
2699     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);
2700
2701     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);
2702     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);
2703     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);
2704     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);
2705
2706     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);
2707     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);
2708     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);
2709     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);
2710
2711     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);
2712     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);
2713     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);
2714     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);
2715
2716     /* And copy the new matrix in the good storage.. */
2717     memcpy(dest, &temp, 16 * sizeof(float));
2718 }
2719
2720 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2721     DWORD size = 0;
2722     int i;
2723     int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2724
2725     if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2726     if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2727     if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2728     if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2729     switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2730         case WINED3DFVF_XYZ:    size += 3 * sizeof(float); break;
2731         case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2732         case WINED3DFVF_XYZB1:  size += 4 * sizeof(float); break;
2733         case WINED3DFVF_XYZB2:  size += 5 * sizeof(float); break;
2734         case WINED3DFVF_XYZB3:  size += 6 * sizeof(float); break;
2735         case WINED3DFVF_XYZB4:  size += 7 * sizeof(float); break;
2736         case WINED3DFVF_XYZB5:  size += 8 * sizeof(float); break;
2737         case WINED3DFVF_XYZW:   size += 4 * sizeof(float); break;
2738         default: ERR("Unexpected position mask\n");
2739     }
2740     for (i = 0; i < numTextures; i++) {
2741         size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2742     }
2743
2744     return size;
2745 }
2746
2747 void gen_ffp_frag_op(struct wined3d_stateblock *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype)
2748 {
2749 #define ARG1 0x01
2750 #define ARG2 0x02
2751 #define ARG0 0x04
2752     static const unsigned char args[WINED3DTOP_LERP + 1] = {
2753         /* undefined                        */  0,
2754         /* D3DTOP_DISABLE                   */  0,
2755         /* D3DTOP_SELECTARG1                */  ARG1,
2756         /* D3DTOP_SELECTARG2                */  ARG2,
2757         /* D3DTOP_MODULATE                  */  ARG1 | ARG2,
2758         /* D3DTOP_MODULATE2X                */  ARG1 | ARG2,
2759         /* D3DTOP_MODULATE4X                */  ARG1 | ARG2,
2760         /* D3DTOP_ADD                       */  ARG1 | ARG2,
2761         /* D3DTOP_ADDSIGNED                 */  ARG1 | ARG2,
2762         /* D3DTOP_ADDSIGNED2X               */  ARG1 | ARG2,
2763         /* D3DTOP_SUBTRACT                  */  ARG1 | ARG2,
2764         /* D3DTOP_ADDSMOOTH                 */  ARG1 | ARG2,
2765         /* D3DTOP_BLENDDIFFUSEALPHA         */  ARG1 | ARG2,
2766         /* D3DTOP_BLENDTEXTUREALPHA         */  ARG1 | ARG2,
2767         /* D3DTOP_BLENDFACTORALPHA          */  ARG1 | ARG2,
2768         /* D3DTOP_BLENDTEXTUREALPHAPM       */  ARG1 | ARG2,
2769         /* D3DTOP_BLENDCURRENTALPHA         */  ARG1 | ARG2,
2770         /* D3DTOP_PREMODULATE               */  ARG1 | ARG2,
2771         /* D3DTOP_MODULATEALPHA_ADDCOLOR    */  ARG1 | ARG2,
2772         /* D3DTOP_MODULATECOLOR_ADDALPHA    */  ARG1 | ARG2,
2773         /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */  ARG1 | ARG2,
2774         /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */  ARG1 | ARG2,
2775         /* D3DTOP_BUMPENVMAP                */  ARG1 | ARG2,
2776         /* D3DTOP_BUMPENVMAPLUMINANCE       */  ARG1 | ARG2,
2777         /* D3DTOP_DOTPRODUCT3               */  ARG1 | ARG2,
2778         /* D3DTOP_MULTIPLYADD               */  ARG1 | ARG2 | ARG0,
2779         /* D3DTOP_LERP                      */  ARG1 | ARG2 | ARG0
2780     };
2781     unsigned int i;
2782     DWORD ttff;
2783     DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2784     struct wined3d_device *device = stateblock->device;
2785     struct wined3d_surface *rt = device->fb.render_targets[0];
2786     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2787
2788     for (i = 0; i < gl_info->limits.texture_stages; ++i)
2789     {
2790         const struct wined3d_texture *texture;
2791
2792         settings->op[i].padding = 0;
2793         if (stateblock->state.texture_states[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE)
2794         {
2795             settings->op[i].cop = WINED3DTOP_DISABLE;
2796             settings->op[i].aop = WINED3DTOP_DISABLE;
2797             settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2798             settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2799             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2800             settings->op[i].dst = resultreg;
2801             settings->op[i].tex_type = tex_1d;
2802             settings->op[i].projected = proj_none;
2803             i++;
2804             break;
2805         }
2806
2807         if ((texture = stateblock->state.textures[i]))
2808         {
2809             settings->op[i].color_fixup = texture->resource.format->color_fixup;
2810             if (ignore_textype)
2811             {
2812                 settings->op[i].tex_type = tex_1d;
2813             }
2814             else
2815             {
2816                 switch (texture->target)
2817                 {
2818                     case GL_TEXTURE_1D:
2819                         settings->op[i].tex_type = tex_1d;
2820                         break;
2821                     case GL_TEXTURE_2D:
2822                         settings->op[i].tex_type = tex_2d;
2823                         break;
2824                     case GL_TEXTURE_3D:
2825                         settings->op[i].tex_type = tex_3d;
2826                         break;
2827                     case GL_TEXTURE_CUBE_MAP_ARB:
2828                         settings->op[i].tex_type = tex_cube;
2829                         break;
2830                     case GL_TEXTURE_RECTANGLE_ARB:
2831                         settings->op[i].tex_type = tex_rect;
2832                         break;
2833                 }
2834             }
2835         } else {
2836             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2837             settings->op[i].tex_type = tex_1d;
2838         }
2839
2840         cop = stateblock->state.texture_states[i][WINED3DTSS_COLOROP];
2841         aop = stateblock->state.texture_states[i][WINED3DTSS_ALPHAOP];
2842
2843         carg1 = (args[cop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2844         carg2 = (args[cop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2845         carg0 = (args[cop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2846
2847         if (is_invalid_op(&stateblock->state, i, cop, carg1, carg2, carg0))
2848         {
2849             carg0 = ARG_UNUSED;
2850             carg2 = ARG_UNUSED;
2851             carg1 = WINED3DTA_CURRENT;
2852             cop = WINED3DTOP_SELECTARG1;
2853         }
2854
2855         if(cop == WINED3DTOP_DOTPRODUCT3) {
2856             /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2857              * the color result to the alpha component of the destination
2858              */
2859             aop = cop;
2860             aarg1 = carg1;
2861             aarg2 = carg2;
2862             aarg0 = carg0;
2863         }
2864         else
2865         {
2866             aarg1 = (args[aop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2867             aarg2 = (args[aop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2868             aarg0 = (args[aop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2869         }
2870
2871         if (!i && stateblock->state.textures[0] && stateblock->state.render_states[WINED3DRS_COLORKEYENABLE])
2872         {
2873             GLenum texture_dimensions;
2874
2875             texture = stateblock->state.textures[0];
2876             texture_dimensions = texture->target;
2877
2878             if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2879             {
2880                 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
2881
2882                 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
2883                 {
2884                     if (aop == WINED3DTOP_DISABLE)
2885                     {
2886                        aarg1 = WINED3DTA_TEXTURE;
2887                        aop = WINED3DTOP_SELECTARG1;
2888                     }
2889                     else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2890                     {
2891                         if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2892                         {
2893                             aarg2 = WINED3DTA_TEXTURE;
2894                             aop = WINED3DTOP_MODULATE;
2895                         }
2896                         else aarg1 = WINED3DTA_TEXTURE;
2897                     }
2898                     else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2899                     {
2900                         if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2901                         {
2902                             aarg1 = WINED3DTA_TEXTURE;
2903                             aop = WINED3DTOP_MODULATE;
2904                         }
2905                         else aarg2 = WINED3DTA_TEXTURE;
2906                     }
2907                 }
2908             }
2909         }
2910
2911         if (is_invalid_op(&stateblock->state, i, aop, aarg1, aarg2, aarg0))
2912         {
2913                aarg0 = ARG_UNUSED;
2914                aarg2 = ARG_UNUSED;
2915                aarg1 = WINED3DTA_CURRENT;
2916                aop = WINED3DTOP_SELECTARG1;
2917         }
2918
2919         if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
2920                 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
2921         {
2922             ttff = stateblock->state.texture_states[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2923             if (ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3))
2924             {
2925                 settings->op[i].projected = proj_count3;
2926             } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2927                 settings->op[i].projected = proj_count4;
2928             } else {
2929                 settings->op[i].projected = proj_none;
2930             }
2931         } else {
2932             settings->op[i].projected = proj_none;
2933         }
2934
2935         settings->op[i].cop = cop;
2936         settings->op[i].aop = aop;
2937         settings->op[i].carg0 = carg0;
2938         settings->op[i].carg1 = carg1;
2939         settings->op[i].carg2 = carg2;
2940         settings->op[i].aarg0 = aarg0;
2941         settings->op[i].aarg1 = aarg1;
2942         settings->op[i].aarg2 = aarg2;
2943
2944         if (stateblock->state.texture_states[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP)
2945         {
2946             settings->op[i].dst = tempreg;
2947         } else {
2948             settings->op[i].dst = resultreg;
2949         }
2950     }
2951
2952     /* Clear unsupported stages */
2953     for(; i < MAX_TEXTURES; i++) {
2954         memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2955     }
2956
2957     if (!stateblock->state.render_states[WINED3DRS_FOGENABLE])
2958     {
2959         settings->fog = FOG_OFF;
2960     }
2961     else if (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
2962     {
2963         if (use_vs(&stateblock->state) || stateblock->state.vertex_declaration->position_transformed)
2964         {
2965             settings->fog = FOG_LINEAR;
2966         }
2967         else
2968         {
2969             switch (stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE])
2970             {
2971                 case WINED3DFOG_NONE:
2972                 case WINED3DFOG_LINEAR:
2973                     settings->fog = FOG_LINEAR;
2974                     break;
2975                 case WINED3DFOG_EXP:
2976                     settings->fog = FOG_EXP;
2977                     break;
2978                 case WINED3DFOG_EXP2:
2979                     settings->fog = FOG_EXP2;
2980                     break;
2981             }
2982         }
2983     }
2984     else
2985     {
2986         switch (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE])
2987         {
2988             case WINED3DFOG_LINEAR:
2989                 settings->fog = FOG_LINEAR;
2990                 break;
2991             case WINED3DFOG_EXP:
2992                 settings->fog = FOG_EXP;
2993                 break;
2994             case WINED3DFOG_EXP2:
2995                 settings->fog = FOG_EXP2;
2996                 break;
2997         }
2998     }
2999     if (stateblock->state.render_states[WINED3DRS_SRGBWRITEENABLE]
3000             && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
3001     {
3002         settings->sRGB_write = 1;
3003     } else {
3004         settings->sRGB_write = 0;
3005     }
3006     if (device->vs_clipping || !use_vs(&stateblock->state) || !stateblock->state.render_states[WINED3DRS_CLIPPING]
3007             || !stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE])
3008     {
3009         /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3010          * the fixed function vertex pipeline is used(which always supports clipplanes), or
3011          * if no clipplane is enabled
3012          */
3013         settings->emul_clipplanes = 0;
3014     } else {
3015         settings->emul_clipplanes = 1;
3016     }
3017 }
3018
3019 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3020         const struct ffp_frag_settings *settings)
3021 {
3022     struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3023     return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3024 }
3025
3026 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3027 {
3028     /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3029      * whereas desc points to an extended structure with implementation specific parts. */
3030     if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3031     {
3032         ERR("Failed to insert ffp frag shader.\n");
3033     }
3034 }
3035
3036 /* Activates the texture dimension according to the bound D3D texture.
3037  * Does not care for the colorop or correct gl texture unit(when using nvrc)
3038  * Requires the caller to activate the correct unit before
3039  */
3040 /* GL locking is done by the caller (state handler) */
3041 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3042 {
3043     if (texture)
3044     {
3045         switch (texture->target)
3046         {
3047             case GL_TEXTURE_2D:
3048                 glDisable(GL_TEXTURE_3D);
3049                 checkGLcall("glDisable(GL_TEXTURE_3D)");
3050                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3051                 {
3052                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3053                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3054                 }
3055                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3056                 {
3057                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
3058                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3059                 }
3060                 glEnable(GL_TEXTURE_2D);
3061                 checkGLcall("glEnable(GL_TEXTURE_2D)");
3062                 break;
3063             case GL_TEXTURE_RECTANGLE_ARB:
3064                 glDisable(GL_TEXTURE_2D);
3065                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3066                 glDisable(GL_TEXTURE_3D);
3067                 checkGLcall("glDisable(GL_TEXTURE_3D)");
3068                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3069                 {
3070                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3071                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3072                 }
3073                 glEnable(GL_TEXTURE_RECTANGLE_ARB);
3074                 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3075                 break;
3076             case GL_TEXTURE_3D:
3077                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3078                 {
3079                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3080                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3081                 }
3082                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3083                 {
3084                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
3085                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3086                 }
3087                 glDisable(GL_TEXTURE_2D);
3088                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3089                 glEnable(GL_TEXTURE_3D);
3090                 checkGLcall("glEnable(GL_TEXTURE_3D)");
3091                 break;
3092             case GL_TEXTURE_CUBE_MAP_ARB:
3093                 glDisable(GL_TEXTURE_2D);
3094                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3095                 glDisable(GL_TEXTURE_3D);
3096                 checkGLcall("glDisable(GL_TEXTURE_3D)");
3097                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3098                 {
3099                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
3100                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3101                 }
3102                 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3103                 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3104               break;
3105         }
3106     } else {
3107         glEnable(GL_TEXTURE_2D);
3108         checkGLcall("glEnable(GL_TEXTURE_2D)");
3109         glDisable(GL_TEXTURE_3D);
3110         checkGLcall("glDisable(GL_TEXTURE_3D)");
3111         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3112         {
3113             glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3114             checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3115         }
3116         if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3117         {
3118             glDisable(GL_TEXTURE_RECTANGLE_ARB);
3119             checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3120         }
3121         /* Binding textures is done by samplers. A dummy texture will be bound */
3122     }
3123 }
3124
3125 /* GL locking is done by the caller (state handler) */
3126 void sampler_texdim(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3127 {
3128     DWORD sampler = state - STATE_SAMPLER(0);
3129     DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3130
3131     /* No need to enable / disable anything here for unused samplers. The tex_colorop
3132     * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3133     * will take care of this business
3134     */
3135     if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3136     if (sampler >= stateblock->state.lowest_disabled_stage) return;
3137     if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3138
3139     texture_activate_dimensions(stateblock->state.textures[sampler], context->gl_info);
3140 }
3141
3142 void *wined3d_rb_alloc(size_t size)
3143 {
3144     return HeapAlloc(GetProcessHeap(), 0, size);
3145 }
3146
3147 void *wined3d_rb_realloc(void *ptr, size_t size)
3148 {
3149     return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3150 }
3151
3152 void wined3d_rb_free(void *ptr)
3153 {
3154     HeapFree(GetProcessHeap(), 0, ptr);
3155 }
3156
3157 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3158 {
3159     const struct ffp_frag_settings *ka = key;
3160     const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3161
3162     return memcmp(ka, kb, sizeof(*ka));
3163 }
3164
3165 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3166 {
3167     wined3d_rb_alloc,
3168     wined3d_rb_realloc,
3169     wined3d_rb_free,
3170     ffp_frag_program_key_compare,
3171 };
3172
3173 UINT wined3d_log2i(UINT32 x)
3174 {
3175     static const UINT l[] =
3176     {
3177         ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3178           4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3179           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3180           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3181           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3182           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3183           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3184           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3185           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3186           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3187           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3188           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3189           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3190           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3191           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3192           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3193     };
3194     UINT32 i;
3195
3196     return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3197 }
3198
3199 /* Set the shader type for this device, depending on the given capabilities
3200  * and the user preferences in wined3d_settings. */
3201 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3202 {
3203     BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3204
3205     if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3206     else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3207     {
3208         /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3209          * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3210          * shaders only on this card. */
3211         if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3212         else *vs_selected = SHADER_GLSL;
3213     }
3214     else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3215     else *vs_selected = SHADER_NONE;
3216
3217     if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3218     else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3219     else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3220     else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3221     else *ps_selected = SHADER_NONE;
3222 }
3223
3224 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3225         const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format *src_format,
3226         const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format *dst_format)
3227 {
3228     static const struct blit_shader * const blitters[] =
3229     {
3230         &arbfp_blit,
3231         &ffp_blit,
3232         &cpu_blit,
3233     };
3234     unsigned int i;
3235
3236     for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3237     {
3238         if (blitters[i]->blit_supported(gl_info, blit_op,
3239                 src_rect, src_usage, src_pool, src_format,
3240                 dst_rect, dst_usage, dst_pool, dst_format))
3241             return blitters[i];
3242     }
3243
3244     return NULL;
3245 }