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