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