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