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