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