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