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