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