d3d10core: Implement d3d10_device_PSGetSamplers().
[wine] / dlls / wined3d / utils.c
1 /*
2  * Utility functions for the WineD3D Library
3  *
4  * Copyright 2002-2004 Jason Edmeades
5  * Copyright 2003-2004 Raphael Junqueira
6  * Copyright 2004 Christian Costa
7  * Copyright 2005 Oliver Stieber
8  * Copyright 2006-2008 Henri Verbeet
9  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
10  * Copyright 2009-2010 Henri Verbeet for CodeWeavers
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with this library; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26
27 #include "config.h"
28 #include "wine/port.h"
29
30 #include "wined3d_private.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
33
34 struct wined3d_format_channels
35 {
36     enum wined3d_format_id id;
37     DWORD red_size, green_size, blue_size, alpha_size;
38     DWORD red_offset, green_offset, blue_offset, alpha_offset;
39     UINT bpp;
40     BYTE depth_size, stencil_size;
41 };
42
43 static const struct wined3d_format_channels formats[] =
44 {
45     /*                                          size            offset
46      *  format id                           r   g   b   a    r   g   b   a    bpp depth stencil */
47     {WINED3DFMT_UNKNOWN,                    0,  0,  0,  0,   0,  0,  0,  0,    0,   0,     0},
48     /* FourCC formats */
49     {WINED3DFMT_UYVY,                       0,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
50     {WINED3DFMT_YUY2,                       0,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
51     {WINED3DFMT_YV12,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
52     {WINED3DFMT_DXT1,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
53     {WINED3DFMT_DXT2,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
54     {WINED3DFMT_DXT3,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
55     {WINED3DFMT_DXT4,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
56     {WINED3DFMT_DXT5,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
57     {WINED3DFMT_MULTI2_ARGB8,               0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
58     {WINED3DFMT_G8R8_G8B8,                  0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
59     {WINED3DFMT_R8G8_B8G8,                  0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
60     /* IEEE formats */
61     {WINED3DFMT_R32_FLOAT,                 32,  0,  0,  0,   0,  0,  0,  0,    4,   0,     0},
62     {WINED3DFMT_R32G32_FLOAT,              32, 32,  0,  0,   0, 32,  0,  0,    8,   0,     0},
63     {WINED3DFMT_R32G32B32_FLOAT,           32, 32, 32,  0,   0, 32, 64,  0,   12,   0,     0},
64     {WINED3DFMT_R32G32B32A32_FLOAT,        32, 32, 32, 32,   0, 32, 64, 96,   16,   0,     0},
65     /* Hmm? */
66     {WINED3DFMT_R8G8_SNORM_Cx,              0,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
67     /* Float */
68     {WINED3DFMT_R16_FLOAT,                 16,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
69     {WINED3DFMT_R16G16_FLOAT,              16, 16,  0,  0,   0, 16,  0,  0,    4,   0,     0},
70     {WINED3DFMT_R16G16_SINT,               16, 16,  0,  0,   0, 16,  0,  0,    4,   0,     0},
71     {WINED3DFMT_R16G16B16A16_FLOAT,        16, 16, 16, 16,   0, 16, 32, 48,    8,   0,     0},
72     {WINED3DFMT_R16G16B16A16_SINT,         16, 16, 16, 16,   0, 16, 32, 48,    8,   0,     0},
73     /* Palettized formats */
74     {WINED3DFMT_P8_UINT_A8_UNORM,           0,  0,  0,  8,   0,  0,  0,  8,    2,   0,     0},
75     {WINED3DFMT_P8_UINT,                    0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
76     /* Standard ARGB formats. */
77     {WINED3DFMT_B8G8R8_UNORM,               8,  8,  8,  0,  16,  8,  0,  0,    3,   0,     0},
78     {WINED3DFMT_B8G8R8A8_UNORM,             8,  8,  8,  8,  16,  8,  0, 24,    4,   0,     0},
79     {WINED3DFMT_B8G8R8X8_UNORM,             8,  8,  8,  0,  16,  8,  0,  0,    4,   0,     0},
80     {WINED3DFMT_B5G6R5_UNORM,               5,  6,  5,  0,  11,  5,  0,  0,    2,   0,     0},
81     {WINED3DFMT_B5G5R5X1_UNORM,             5,  5,  5,  0,  10,  5,  0,  0,    2,   0,     0},
82     {WINED3DFMT_B5G5R5A1_UNORM,             5,  5,  5,  1,  10,  5,  0, 15,    2,   0,     0},
83     {WINED3DFMT_B4G4R4A4_UNORM,             4,  4,  4,  4,   8,  4,  0, 12,    2,   0,     0},
84     {WINED3DFMT_B2G3R3_UNORM,               3,  3,  2,  0,   5,  2,  0,  0,    1,   0,     0},
85     {WINED3DFMT_A8_UNORM,                   0,  0,  0,  8,   0,  0,  0,  0,    1,   0,     0},
86     {WINED3DFMT_B2G3R3A8_UNORM,             3,  3,  2,  8,   5,  2,  0,  8,    2,   0,     0},
87     {WINED3DFMT_B4G4R4X4_UNORM,             4,  4,  4,  0,   8,  4,  0,  0,    2,   0,     0},
88     {WINED3DFMT_R10G10B10A2_UNORM,         10, 10, 10,  2,   0, 10, 20, 30,    4,   0,     0},
89     {WINED3DFMT_R10G10B10A2_UINT,          10, 10, 10,  2,   0, 10, 20, 30,    4,   0,     0},
90     {WINED3DFMT_R10G10B10A2_SNORM,         10, 10, 10,  2,   0, 10, 20, 30,    4,   0,     0},
91     {WINED3DFMT_R8G8B8A8_UNORM,             8,  8,  8,  8,   0,  8, 16, 24,    4,   0,     0},
92     {WINED3DFMT_R8G8B8A8_UINT,              8,  8,  8,  8,   0,  8, 16, 24,    4,   0,     0},
93     {WINED3DFMT_R8G8B8X8_UNORM,             8,  8,  8,  0,   0,  8, 16,  0,    4,   0,     0},
94     {WINED3DFMT_R16G16_UNORM,              16, 16,  0,  0,   0, 16,  0,  0,    4,   0,     0},
95     {WINED3DFMT_B10G10R10A2_UNORM,         10, 10, 10,  2,  20, 10,  0, 30,    4,   0,     0},
96     {WINED3DFMT_R16G16B16A16_UNORM,        16, 16, 16, 16,   0, 16, 32, 48,    8,   0,     0},
97     /* Luminance */
98     {WINED3DFMT_L8_UNORM,                   0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
99     {WINED3DFMT_L8A8_UNORM,                 0,  0,  0,  8,   0,  0,  0,  8,    2,   0,     0},
100     {WINED3DFMT_L4A4_UNORM,                 0,  0,  0,  4,   0,  0,  0,  4,    1,   0,     0},
101     {WINED3DFMT_L16_UNORM,                  0,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
102     /* Bump mapping stuff */
103     {WINED3DFMT_R8G8_SNORM,                 8,  8,  0,  0,   0,  8,  0,  0,    2,   0,     0},
104     {WINED3DFMT_R5G5_SNORM_L6_UNORM,        5,  5,  0,  0,   0,  5,  0,  0,    2,   0,     0},
105     {WINED3DFMT_R8G8_SNORM_L8X8_UNORM,      8,  8,  0,  0,   0,  8,  0,  0,    4,   0,     0},
106     {WINED3DFMT_R8G8B8A8_SNORM,             8,  8,  8,  8,   0,  8, 16, 24,    4,   0,     0},
107     {WINED3DFMT_R16G16_SNORM,              16, 16,  0,  0,   0, 16,  0,  0,    4,   0,     0},
108     {WINED3DFMT_R10G11B11_SNORM,           10, 11, 11,  0,   0, 10, 21,  0,    4,   0,     0},
109     {WINED3DFMT_R10G10B10_SNORM_A2_UNORM,  10, 10, 10,  2,   0, 10, 20, 30,    4,   0,     0},
110     /* Depth stencil formats */
111     {WINED3DFMT_D16_LOCKABLE,               0,  0,  0,  0,   0,  0,  0,  0,    2,  16,     0},
112     {WINED3DFMT_D32_UNORM,                  0,  0,  0,  0,   0,  0,  0,  0,    4,  32,     0},
113     {WINED3DFMT_S1_UINT_D15_UNORM,          0,  0,  0,  0,   0,  0,  0,  0,    2,  15,     1},
114     {WINED3DFMT_D24_UNORM_S8_UINT,          0,  0,  0,  0,   0,  0,  0,  0,    4,  24,     8},
115     {WINED3DFMT_X8D24_UNORM,                0,  0,  0,  0,   0,  0,  0,  0,    4,  24,     0},
116     {WINED3DFMT_S4X4_UINT_D24_UNORM,        0,  0,  0,  0,   0,  0,  0,  0,    4,  24,     4},
117     {WINED3DFMT_D16_UNORM,                  0,  0,  0,  0,   0,  0,  0,  0,    2,  16,     0},
118     {WINED3DFMT_D32_FLOAT,                  0,  0,  0,  0,   0,  0,  0,  0,    4,  32,     0},
119     {WINED3DFMT_S8_UINT_D24_FLOAT,          0,  0,  0,  0,   0,  0,  0,  0,    4,  24,     8},
120     {WINED3DFMT_VERTEXDATA,                 0,  0,  0,  0,   0,  0,  0,  0,    0,   0,     0},
121     {WINED3DFMT_R16_UINT,                  16,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
122     {WINED3DFMT_R32_UINT,                  32,  0,  0,  0,   0,  0,  0,  0,    4,   0,     0},
123     {WINED3DFMT_R16G16B16A16_SNORM,        16, 16, 16, 16,   0, 16, 32, 48,    8,   0,     0},
124     /* Vendor-specific formats */
125     {WINED3DFMT_ATI2N,                      0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
126     {WINED3DFMT_NVDB,                       0,  0,  0,  0,   0,  0,  0,  0,    0,   0,     0},
127     {WINED3DFMT_INTZ,                       0,  0,  0,  0,   0,  0,  0,  0,    4,  24,     8},
128     {WINED3DFMT_NVHU,                       0,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
129     {WINED3DFMT_NVHS,                       0,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
130     {WINED3DFMT_NULL,                       8,  8,  8,  8,   0,  8, 16, 24,    4,   0,     0},
131     /* Unsure about them, could not find a Windows driver that supports them */
132     {WINED3DFMT_R16,                       16,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
133     {WINED3DFMT_AL16,                       0,  0,  0, 16,   0,  0,  0, 16,    4,   0,     0},
134 };
135
136 struct wined3d_format_base_flags
137 {
138     enum wined3d_format_id id;
139     DWORD flags;
140 };
141
142 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
143  * still needs to use the correct block based calculation for e.g. the
144  * resource size. */
145 static const struct wined3d_format_base_flags format_base_flags[] =
146 {
147     {WINED3DFMT_UYVY,               WINED3DFMT_FLAG_FOURCC},
148     {WINED3DFMT_YUY2,               WINED3DFMT_FLAG_FOURCC},
149     {WINED3DFMT_YV12,               WINED3DFMT_FLAG_FOURCC},
150     {WINED3DFMT_DXT1,               WINED3DFMT_FLAG_FOURCC},
151     {WINED3DFMT_DXT2,               WINED3DFMT_FLAG_FOURCC},
152     {WINED3DFMT_DXT3,               WINED3DFMT_FLAG_FOURCC},
153     {WINED3DFMT_DXT4,               WINED3DFMT_FLAG_FOURCC},
154     {WINED3DFMT_DXT5,               WINED3DFMT_FLAG_FOURCC},
155     {WINED3DFMT_MULTI2_ARGB8,       WINED3DFMT_FLAG_FOURCC},
156     {WINED3DFMT_G8R8_G8B8,          WINED3DFMT_FLAG_FOURCC},
157     {WINED3DFMT_R8G8_B8G8,          WINED3DFMT_FLAG_FOURCC},
158     {WINED3DFMT_INTZ,               WINED3DFMT_FLAG_FOURCC},
159     {WINED3DFMT_NULL,               WINED3DFMT_FLAG_FOURCC},
160     {WINED3DFMT_P8_UINT,            WINED3DFMT_FLAG_GETDC},
161     {WINED3DFMT_B8G8R8_UNORM,       WINED3DFMT_FLAG_GETDC},
162     {WINED3DFMT_B8G8R8A8_UNORM,     WINED3DFMT_FLAG_GETDC},
163     {WINED3DFMT_B8G8R8X8_UNORM,     WINED3DFMT_FLAG_GETDC},
164     {WINED3DFMT_B5G6R5_UNORM,       WINED3DFMT_FLAG_GETDC},
165     {WINED3DFMT_B5G5R5X1_UNORM,     WINED3DFMT_FLAG_GETDC},
166     {WINED3DFMT_B5G5R5A1_UNORM,     WINED3DFMT_FLAG_GETDC},
167     {WINED3DFMT_B4G4R4A4_UNORM,     WINED3DFMT_FLAG_GETDC},
168     {WINED3DFMT_B4G4R4X4_UNORM,     WINED3DFMT_FLAG_GETDC},
169     {WINED3DFMT_R8G8B8A8_UNORM,     WINED3DFMT_FLAG_GETDC},
170     {WINED3DFMT_R8G8B8X8_UNORM,     WINED3DFMT_FLAG_GETDC},
171     {WINED3DFMT_ATI2N,              WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
172     {WINED3DFMT_NVDB,               WINED3DFMT_FLAG_FOURCC},
173     {WINED3DFMT_NVHU,               WINED3DFMT_FLAG_FOURCC},
174     {WINED3DFMT_NVHS,               WINED3DFMT_FLAG_FOURCC},
175     {WINED3DFMT_R32_FLOAT,          WINED3DFMT_FLAG_FLOAT},
176     {WINED3DFMT_R32G32_FLOAT,       WINED3DFMT_FLAG_FLOAT},
177     {WINED3DFMT_R32G32B32_FLOAT,    WINED3DFMT_FLAG_FLOAT},
178     {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
179     {WINED3DFMT_R16_FLOAT,          WINED3DFMT_FLAG_FLOAT},
180     {WINED3DFMT_R16G16_FLOAT,       WINED3DFMT_FLAG_FLOAT},
181     {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
182     {WINED3DFMT_D32_FLOAT,          WINED3DFMT_FLAG_FLOAT},
183     {WINED3DFMT_S8_UINT_D24_FLOAT,  WINED3DFMT_FLAG_FLOAT},
184 };
185
186 struct wined3d_format_block_info
187 {
188     enum wined3d_format_id id;
189     UINT block_width;
190     UINT block_height;
191     UINT block_byte_count;
192 };
193
194 static const struct wined3d_format_block_info format_block_info[] =
195 {
196     {WINED3DFMT_DXT1,   4,  4,  8},
197     {WINED3DFMT_DXT2,   4,  4,  16},
198     {WINED3DFMT_DXT3,   4,  4,  16},
199     {WINED3DFMT_DXT4,   4,  4,  16},
200     {WINED3DFMT_DXT5,   4,  4,  16},
201     {WINED3DFMT_ATI2N,  4,  4,  16},
202     {WINED3DFMT_YUY2,   2,  1,  4},
203     {WINED3DFMT_UYVY,   2,  1,  4},
204 };
205
206 struct wined3d_format_vertex_info
207 {
208     enum wined3d_format_id id;
209     enum wined3d_ffp_emit_idx emit_idx;
210     GLint component_count;
211     GLenum gl_vtx_type;
212     GLint gl_vtx_format;
213     GLboolean gl_normalized;
214     unsigned int component_size;
215 };
216
217 static const struct wined3d_format_vertex_info format_vertex_info[] =
218 {
219     {WINED3DFMT_R32_FLOAT,          WINED3D_FFP_EMIT_FLOAT1,    1, GL_FLOAT,          1, GL_FALSE, sizeof(float)},
220     {WINED3DFMT_R32G32_FLOAT,       WINED3D_FFP_EMIT_FLOAT2,    2, GL_FLOAT,          2, GL_FALSE, sizeof(float)},
221     {WINED3DFMT_R32G32B32_FLOAT,    WINED3D_FFP_EMIT_FLOAT3,    3, GL_FLOAT,          3, GL_FALSE, sizeof(float)},
222     {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4,    4, GL_FLOAT,          4, GL_FALSE, sizeof(float)},
223     {WINED3DFMT_B8G8R8A8_UNORM,     WINED3D_FFP_EMIT_D3DCOLOR,  4, GL_UNSIGNED_BYTE,  4, GL_TRUE,  sizeof(BYTE)},
224     {WINED3DFMT_R8G8B8A8_UINT,      WINED3D_FFP_EMIT_UBYTE4,    4, GL_UNSIGNED_BYTE,  4, GL_FALSE, sizeof(BYTE)},
225     {WINED3DFMT_R16G16_SINT,        WINED3D_FFP_EMIT_SHORT2,    2, GL_SHORT,          2, GL_FALSE, sizeof(short int)},
226     {WINED3DFMT_R16G16B16A16_SINT,  WINED3D_FFP_EMIT_SHORT4,    4, GL_SHORT,          4, GL_FALSE, sizeof(short int)},
227     {WINED3DFMT_R8G8B8A8_UNORM,     WINED3D_FFP_EMIT_UBYTE4N,   4, GL_UNSIGNED_BYTE,  4, GL_TRUE,  sizeof(BYTE)},
228     {WINED3DFMT_R16G16_SNORM,       WINED3D_FFP_EMIT_SHORT2N,   2, GL_SHORT,          2, GL_TRUE,  sizeof(short int)},
229     {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N,   4, GL_SHORT,          4, GL_TRUE,  sizeof(short int)},
230     {WINED3DFMT_R16G16_UNORM,       WINED3D_FFP_EMIT_USHORT2N,  2, GL_UNSIGNED_SHORT, 2, GL_TRUE,  sizeof(short int)},
231     {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N,  4, GL_UNSIGNED_SHORT, 4, GL_TRUE,  sizeof(short int)},
232     {WINED3DFMT_R10G10B10A2_UINT,   WINED3D_FFP_EMIT_UDEC3,     3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
233     {WINED3DFMT_R10G10B10A2_SNORM,  WINED3D_FFP_EMIT_DEC3N,     3, GL_SHORT,          3, GL_TRUE,  sizeof(short int)},
234     {WINED3DFMT_R16G16_FLOAT,       WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT,          2, GL_FALSE, sizeof(GLhalfNV)},
235     {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT,          4, GL_FALSE, sizeof(GLhalfNV)}
236 };
237
238 struct wined3d_format_texture_info
239 {
240     enum wined3d_format_id id;
241     GLint gl_internal;
242     GLint gl_srgb_internal;
243     GLint gl_rt_internal;
244     GLint gl_format;
245     GLint gl_type;
246     unsigned int conv_byte_count;
247     unsigned int flags;
248     enum wined3d_gl_extension extension;
249     void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
250 };
251
252 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
253 {
254     /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
255      * format+type combination to load it. Thus convert it to A8L8, then load it
256      * with A4L4 internal, but A8L8 format+type
257      */
258     unsigned int x, y;
259     const unsigned char *Source;
260     unsigned char *Dest;
261     UINT outpitch = pitch * 2;
262
263     for(y = 0; y < height; y++) {
264         Source = src + y * pitch;
265         Dest = dst + y * outpitch;
266         for (x = 0; x < width; x++ ) {
267             unsigned char color = (*Source++);
268             /* A */ Dest[1] = (color & 0xf0) << 0;
269             /* L */ Dest[0] = (color & 0x0f) << 4;
270             Dest += 2;
271         }
272     }
273 }
274
275 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
276 {
277     unsigned int x, y;
278     const WORD *Source;
279
280     for(y = 0; y < height; y++)
281     {
282         unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
283         Source = (const WORD *)(src + y * pitch);
284         for (x = 0; x < width; x++ )
285         {
286             short color = (*Source++);
287             unsigned char l = ((color >> 10) & 0xfc);
288                     short v = ((color >>  5) & 0x3e);
289                     short u = ((color      ) & 0x1f);
290             short v_conv = v + 16;
291             short u_conv = u + 16;
292
293             *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
294             Dest_s += 1;
295         }
296     }
297 }
298
299 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
300 {
301     unsigned int x, y;
302     const WORD *Source;
303     unsigned char *Dest;
304     UINT outpitch = (pitch * 3)/2;
305
306     /* This makes the gl surface bigger(24 bit instead of 16), but it works with
307      * fixed function and shaders without further conversion once the surface is
308      * loaded
309      */
310     for(y = 0; y < height; y++) {
311         Source = (const WORD *)(src + y * pitch);
312         Dest = dst + y * outpitch;
313         for (x = 0; x < width; x++ ) {
314             short color = (*Source++);
315             unsigned char l = ((color >> 10) & 0xfc);
316                      char v = ((color >>  5) & 0x3e);
317                      char u = ((color      ) & 0x1f);
318
319             /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
320              * and doubles the positive range. Thus shift left only once, gl does the 2nd
321              * shift. GL reads a signed value and converts it into an unsigned value.
322              */
323             /* M */ Dest[2] = l << 1;
324
325             /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
326              * from 5 bit values to 8 bit values.
327              */
328             /* V */ Dest[1] = v << 3;
329             /* U */ Dest[0] = u << 3;
330             Dest += 3;
331         }
332     }
333 }
334
335 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
336 {
337     unsigned int x, y;
338     const short *Source;
339     unsigned char *Dest;
340     UINT outpitch = (pitch * 3)/2;
341
342     for(y = 0; y < height; y++)
343     {
344         Source = (const short *)(src + y * pitch);
345         Dest = dst + y * outpitch;
346         for (x = 0; x < width; x++ )
347         {
348             const short color = (*Source++);
349             /* B */ Dest[0] = 0xff;
350             /* G */ Dest[1] = (color >> 8) + 128; /* V */
351             /* R */ Dest[2] = (color & 0xff) + 128;      /* U */
352             Dest += 3;
353         }
354     }
355 }
356
357 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
358 {
359     unsigned int x, y;
360     const DWORD *Source;
361     unsigned char *Dest;
362
363     /* Doesn't work correctly with the fixed function pipeline, but can work in
364      * shaders if the shader is adjusted. (There's no use for this format in gl's
365      * standard fixed function pipeline anyway).
366      */
367     for(y = 0; y < height; y++)
368     {
369         Source = (const DWORD *)(src + y * pitch);
370         Dest = dst + y * pitch;
371         for (x = 0; x < width; x++ )
372         {
373             LONG color = (*Source++);
374             /* B */ Dest[0] = ((color >> 16) & 0xff);       /* L */
375             /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
376             /* R */ Dest[2] = (color         & 0xff) + 128; /* U */
377             Dest += 4;
378         }
379     }
380 }
381
382 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
383 {
384     unsigned int x, y;
385     const DWORD *Source;
386     unsigned char *Dest;
387
388     /* This implementation works with the fixed function pipeline and shaders
389      * without further modification after converting the surface.
390      */
391     for(y = 0; y < height; y++)
392     {
393         Source = (const DWORD *)(src + y * pitch);
394         Dest = dst + y * pitch;
395         for (x = 0; x < width; x++ )
396         {
397             LONG color = (*Source++);
398             /* L */ Dest[2] = ((color >> 16) & 0xff);   /* L */
399             /* V */ Dest[1] = ((color >> 8 ) & 0xff);   /* V */
400             /* U */ Dest[0] = (color         & 0xff);   /* U */
401             /* I */ Dest[3] = 255;                      /* X */
402             Dest += 4;
403         }
404     }
405 }
406
407 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
408 {
409     unsigned int x, y;
410     const DWORD *Source;
411     unsigned char *Dest;
412
413     for(y = 0; y < height; y++)
414     {
415         Source = (const DWORD *)(src + y * pitch);
416         Dest = dst + y * pitch;
417         for (x = 0; x < width; x++ )
418         {
419             LONG color = (*Source++);
420             /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
421             /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
422             /* R */ Dest[2] = (color         & 0xff) + 128; /* U */
423             /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
424             Dest += 4;
425         }
426     }
427 }
428
429 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
430 {
431     unsigned int x, y;
432     const DWORD *Source;
433     unsigned short *Dest;
434     UINT outpitch = (pitch * 3)/2;
435
436     for(y = 0; y < height; y++)
437     {
438         Source = (const DWORD *)(src + y * pitch);
439         Dest = (unsigned short *) (dst + y * outpitch);
440         for (x = 0; x < width; x++ )
441         {
442             const DWORD color = (*Source++);
443             /* B */ Dest[0] = 0xffff;
444             /* G */ Dest[1] = (color >> 16) + 32768; /* V */
445             /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */
446             Dest += 3;
447         }
448     }
449 }
450
451 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
452 {
453     unsigned int x, y;
454     const WORD *Source;
455     WORD *Dest;
456     UINT outpitch = (pitch * 3)/2;
457
458     for(y = 0; y < height; y++)
459     {
460         Source = (const WORD *)(src + y * pitch);
461         Dest = (WORD *) (dst + y * outpitch);
462         for (x = 0; x < width; x++ )
463         {
464             WORD green = (*Source++);
465             WORD red = (*Source++);
466             Dest[0] = green;
467             Dest[1] = red;
468             /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
469              * shader overwrites it anyway
470              */
471             Dest[2] = 0xffff;
472             Dest += 3;
473         }
474     }
475 }
476
477 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
478 {
479     unsigned int x, y;
480     const float *Source;
481     float *Dest;
482     UINT outpitch = (pitch * 3)/2;
483
484     for(y = 0; y < height; y++)
485     {
486         Source = (const float *)(src + y * pitch);
487         Dest = (float *) (dst + y * outpitch);
488         for (x = 0; x < width; x++ )
489         {
490             float green = (*Source++);
491             float red = (*Source++);
492             Dest[0] = green;
493             Dest[1] = red;
494             Dest[2] = 1.0f;
495             Dest += 3;
496         }
497     }
498 }
499
500 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
501 {
502     unsigned int x, y;
503     UINT outpitch = pitch * 2;
504
505     for (y = 0; y < height; ++y)
506     {
507         const WORD *source = (const WORD *)(src + y * pitch);
508         DWORD *dest = (DWORD *)(dst + y * outpitch);
509
510         for (x = 0; x < width; ++x)
511         {
512             /* The depth data is normalized, so needs to be scaled,
513              * the stencil data isn't.  Scale depth data by
514              *      (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
515             WORD d15 = source[x] >> 1;
516             DWORD d24 = (d15 << 9) + (d15 >> 6);
517             dest[x] = (d24 << 8) | (source[x] & 0x1);
518         }
519     }
520 }
521
522 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
523 {
524     unsigned int x, y;
525
526     for (y = 0; y < height; ++y)
527     {
528         const DWORD *source = (const DWORD *)(src + y * pitch);
529         DWORD *dest = (DWORD *)(dst + y * pitch);
530
531         for (x = 0; x < width; ++x)
532         {
533             /* Just need to clear out the X4 part. */
534             dest[x] = source[x] & ~0xf0;
535         }
536     }
537 }
538
539 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
540 {
541     unsigned int x, y;
542     UINT outpitch = pitch * 2;
543
544     for (y = 0; y < height; ++y)
545     {
546         const DWORD *source = (const DWORD *)(src + y * pitch);
547         float *dest_f = (float *)(dst + y * outpitch);
548         DWORD *dest_s = (DWORD *)(dst + y * outpitch);
549
550         for (x = 0; x < width; ++x)
551         {
552             dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
553             dest_s[x * 2 + 1] = source[x] & 0xff;
554         }
555     }
556 }
557
558 static const struct wined3d_format_texture_info format_texture_info[] =
559 {
560     /* format id                        internal                          srgbInternal                       rtInternal
561             format                      type
562             flags
563             extension */
564     /* FourCC formats */
565     /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
566      * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
567      * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
568      * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
569      * endian machine
570      */
571     {WINED3DFMT_UYVY,                   GL_LUMINANCE_ALPHA,               GL_LUMINANCE_ALPHA,                     0,
572             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
573             WINED3DFMT_FLAG_FILTERING,
574             WINED3D_GL_EXT_NONE,        NULL},
575     {WINED3DFMT_UYVY,                   GL_RGB,                           GL_RGB,                                 0,
576             GL_YCBCR_422_APPLE,         GL_UNSIGNED_SHORT_8_8_APPLE,      0,
577             WINED3DFMT_FLAG_FILTERING,
578             APPLE_YCBCR_422,            NULL},
579     {WINED3DFMT_YUY2,                   GL_LUMINANCE_ALPHA,               GL_LUMINANCE_ALPHA,                     0,
580             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
581             WINED3DFMT_FLAG_FILTERING,
582             WINED3D_GL_EXT_NONE,        NULL},
583     {WINED3DFMT_YUY2,                   GL_RGB,                           GL_RGB,                                 0,
584             GL_YCBCR_422_APPLE,         GL_UNSIGNED_SHORT_8_8_REV_APPLE,  0,
585             WINED3DFMT_FLAG_FILTERING,
586             APPLE_YCBCR_422,            NULL},
587     {WINED3DFMT_YV12,                   GL_ALPHA,                         GL_ALPHA,                               0,
588             GL_ALPHA,                   GL_UNSIGNED_BYTE,                 0,
589             WINED3DFMT_FLAG_FILTERING,
590             WINED3D_GL_EXT_NONE,        NULL},
591     {WINED3DFMT_DXT1,                   GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
592             GL_RGBA,                    GL_UNSIGNED_BYTE,                 0,
593             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
594             | WINED3DFMT_FLAG_COMPRESSED,
595             EXT_TEXTURE_COMPRESSION_S3TC, NULL},
596     {WINED3DFMT_DXT2,                   GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
597             GL_RGBA,                    GL_UNSIGNED_BYTE,                 0,
598             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
599             | WINED3DFMT_FLAG_COMPRESSED,
600             EXT_TEXTURE_COMPRESSION_S3TC, NULL},
601     {WINED3DFMT_DXT3,                   GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
602             GL_RGBA,                    GL_UNSIGNED_BYTE,                 0,
603             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
604             | WINED3DFMT_FLAG_COMPRESSED,
605             EXT_TEXTURE_COMPRESSION_S3TC, NULL},
606     {WINED3DFMT_DXT4,                   GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
607             GL_RGBA,                    GL_UNSIGNED_BYTE,                 0,
608             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
609             | WINED3DFMT_FLAG_COMPRESSED,
610             EXT_TEXTURE_COMPRESSION_S3TC, NULL},
611     {WINED3DFMT_DXT5,                   GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
612             GL_RGBA,                    GL_UNSIGNED_BYTE,                 0,
613             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
614             | WINED3DFMT_FLAG_COMPRESSED,
615             EXT_TEXTURE_COMPRESSION_S3TC, NULL},
616     /* IEEE formats */
617     {WINED3DFMT_R32_FLOAT,              GL_RGB32F_ARB,                    GL_RGB32F_ARB,                          0,
618             GL_RED,                     GL_FLOAT,                         0,
619             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
620             ARB_TEXTURE_FLOAT,          NULL},
621     {WINED3DFMT_R32_FLOAT,              GL_R32F,                          GL_R32F,                                0,
622             GL_RED,                     GL_FLOAT,                         0,
623             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
624             ARB_TEXTURE_RG,             NULL},
625     {WINED3DFMT_R32G32_FLOAT,           GL_RGB32F_ARB,                    GL_RGB32F_ARB,                          0,
626             GL_RGB,                     GL_FLOAT,                         12,
627             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
628             ARB_TEXTURE_FLOAT,          convert_r32g32_float},
629     {WINED3DFMT_R32G32_FLOAT,           GL_RG32F,                         GL_RG32F,                               0,
630             GL_RG,                      GL_FLOAT,                         0,
631             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
632             ARB_TEXTURE_RG,             NULL},
633     {WINED3DFMT_R32G32B32A32_FLOAT,     GL_RGBA32F_ARB,                   GL_RGBA32F_ARB,                         0,
634             GL_RGBA,                    GL_FLOAT,                         0,
635             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
636             ARB_TEXTURE_FLOAT,          NULL},
637     /* Float */
638     {WINED3DFMT_R16_FLOAT,              GL_RGB16F_ARB,                    GL_RGB16F_ARB,                          0,
639             GL_RED,                     GL_HALF_FLOAT_ARB,                0,
640             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
641             ARB_TEXTURE_FLOAT,          NULL},
642     {WINED3DFMT_R16_FLOAT,              GL_R16F,                          GL_R16F,                                0,
643             GL_RED,                     GL_HALF_FLOAT_ARB,                0,
644             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
645             ARB_TEXTURE_RG,             NULL},
646     {WINED3DFMT_R16G16_FLOAT,           GL_RGB16F_ARB,                    GL_RGB16F_ARB,                          0,
647             GL_RGB,                     GL_HALF_FLOAT_ARB,                6,
648             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
649             ARB_TEXTURE_FLOAT,          convert_r16g16},
650     {WINED3DFMT_R16G16_FLOAT,           GL_RG16F,                         GL_RG16F,                               0,
651             GL_RG,                      GL_HALF_FLOAT_ARB,                0,
652             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
653             ARB_TEXTURE_RG,             NULL},
654     {WINED3DFMT_R16G16B16A16_FLOAT,     GL_RGBA16F_ARB,                   GL_RGBA16F_ARB,                         0,
655             GL_RGBA,                    GL_HALF_FLOAT_ARB,                0,
656             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
657             ARB_TEXTURE_FLOAT,          NULL},
658     /* Palettized formats */
659     {WINED3DFMT_P8_UINT,                GL_RGBA,                          GL_RGBA,                                0,
660             GL_ALPHA,                   GL_UNSIGNED_BYTE,                 0,
661             0,
662             ARB_FRAGMENT_PROGRAM,       NULL},
663     {WINED3DFMT_P8_UINT,                GL_COLOR_INDEX8_EXT,              GL_COLOR_INDEX8_EXT,                    0,
664             GL_COLOR_INDEX,             GL_UNSIGNED_BYTE,                 0,
665             0,
666             EXT_PALETTED_TEXTURE,       NULL},
667     /* Standard ARGB formats */
668     {WINED3DFMT_B8G8R8_UNORM,           GL_RGB8,                          GL_RGB8,                                0,
669             GL_BGR,                     GL_UNSIGNED_BYTE,                 0,
670             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
671             WINED3D_GL_EXT_NONE,        NULL},
672     {WINED3DFMT_B8G8R8A8_UNORM,         GL_RGBA8,                         GL_SRGB8_ALPHA8_EXT,                    0,
673             GL_BGRA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      0,
674             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
675             | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE | WINED3DFMT_FLAG_VTF,
676             WINED3D_GL_EXT_NONE,        NULL},
677     {WINED3DFMT_B8G8R8X8_UNORM,         GL_RGB8,                          GL_SRGB8_EXT,                           0,
678             GL_BGRA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      0,
679             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
680             | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
681             WINED3D_GL_EXT_NONE,        NULL},
682     {WINED3DFMT_B5G6R5_UNORM,           GL_RGB5,                          GL_RGB5,                          GL_RGB8,
683             GL_RGB,                     GL_UNSIGNED_SHORT_5_6_5,          0,
684             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
685             WINED3D_GL_EXT_NONE,        NULL},
686     {WINED3DFMT_B5G5R5X1_UNORM,         GL_RGB5,                          GL_RGB5_A1,                             0,
687             GL_BGRA,                    GL_UNSIGNED_SHORT_1_5_5_5_REV,    0,
688             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
689             WINED3D_GL_EXT_NONE,        NULL},
690     {WINED3DFMT_B5G5R5A1_UNORM,         GL_RGB5_A1,                       GL_RGB5_A1,                             0,
691             GL_BGRA,                    GL_UNSIGNED_SHORT_1_5_5_5_REV,    0,
692             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
693             WINED3D_GL_EXT_NONE,        NULL},
694     {WINED3DFMT_B4G4R4A4_UNORM,         GL_RGBA4,                         GL_SRGB8_ALPHA8_EXT,                    0,
695             GL_BGRA,                    GL_UNSIGNED_SHORT_4_4_4_4_REV,    0,
696             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
697             WINED3D_GL_EXT_NONE,        NULL},
698     {WINED3DFMT_B2G3R3_UNORM,           GL_R3_G3_B2,                      GL_R3_G3_B2,                            0,
699             GL_RGB,                     GL_UNSIGNED_BYTE_3_3_2,           0,
700             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
701             WINED3D_GL_EXT_NONE,        NULL},
702     {WINED3DFMT_A8_UNORM,               GL_ALPHA8,                        GL_ALPHA8,                              0,
703             GL_ALPHA,                   GL_UNSIGNED_BYTE,                 0,
704             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
705             WINED3D_GL_EXT_NONE,        NULL},
706     {WINED3DFMT_B4G4R4X4_UNORM,         GL_RGB4,                          GL_RGB4,                                0,
707             GL_BGRA,                    GL_UNSIGNED_SHORT_4_4_4_4_REV,    0,
708             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
709             WINED3D_GL_EXT_NONE,        NULL},
710     {WINED3DFMT_R10G10B10A2_UNORM,      GL_RGB10_A2,                      GL_RGB10_A2,                            0,
711             GL_RGBA,                    GL_UNSIGNED_INT_2_10_10_10_REV,   0,
712             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
713             WINED3D_GL_EXT_NONE,        NULL},
714     {WINED3DFMT_R8G8B8A8_UNORM,         GL_RGBA8,                         GL_RGBA8,                               0,
715             GL_RGBA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      0,
716             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
717             WINED3D_GL_EXT_NONE,        NULL},
718     {WINED3DFMT_R8G8B8X8_UNORM,         GL_RGB8,                          GL_RGB8,                                0,
719             GL_RGBA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      0,
720             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
721             WINED3D_GL_EXT_NONE,        NULL},
722     {WINED3DFMT_R16G16_UNORM,           GL_RGB16,                         GL_RGB16,                       GL_RGBA16,
723             GL_RGB,                     GL_UNSIGNED_SHORT,                6,
724             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
725             WINED3D_GL_EXT_NONE,        convert_r16g16},
726     {WINED3DFMT_R16G16_UNORM,           GL_RG16,                          GL_RG16,                                0,
727             GL_RG,                      GL_UNSIGNED_SHORT,                0,
728             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
729             ARB_TEXTURE_RG,             NULL},
730     {WINED3DFMT_B10G10R10A2_UNORM,      GL_RGB10_A2,                      GL_RGB10_A2,                            0,
731             GL_BGRA,                    GL_UNSIGNED_INT_2_10_10_10_REV,   0,
732             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
733             WINED3D_GL_EXT_NONE,        NULL},
734     {WINED3DFMT_R16G16B16A16_UNORM,     GL_RGBA16,                        GL_RGBA16,                              0,
735             GL_RGBA,                    GL_UNSIGNED_SHORT,                0,
736             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
737             WINED3D_GL_EXT_NONE,        NULL},
738     /* Luminance */
739     {WINED3DFMT_L8_UNORM,               GL_LUMINANCE8,                    GL_SLUMINANCE8_EXT,                     0,
740             GL_LUMINANCE,               GL_UNSIGNED_BYTE,                 0,
741             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
742             WINED3D_GL_EXT_NONE,        NULL},
743     {WINED3DFMT_L8A8_UNORM,             GL_LUMINANCE8_ALPHA8,             GL_SLUMINANCE8_ALPHA8_EXT,              0,
744             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
745             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
746             WINED3D_GL_EXT_NONE,        NULL},
747     {WINED3DFMT_L4A4_UNORM,             GL_LUMINANCE4_ALPHA4,             GL_LUMINANCE4_ALPHA4,                   0,
748             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 2,
749             WINED3DFMT_FLAG_FILTERING,
750             WINED3D_GL_EXT_NONE,        convert_l4a4_unorm},
751     /* Bump mapping stuff */
752     {WINED3DFMT_R8G8_SNORM,             GL_RGB8,                          GL_RGB8,                                0,
753             GL_BGR,                     GL_UNSIGNED_BYTE,                 3,
754             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
755             WINED3D_GL_EXT_NONE,        convert_r8g8_snorm},
756     {WINED3DFMT_R8G8_SNORM,             GL_DSDT8_NV,                      GL_DSDT8_NV,                            0,
757             GL_DSDT_NV,                 GL_BYTE,                          0,
758             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
759             NV_TEXTURE_SHADER,          NULL},
760     {WINED3DFMT_R5G5_SNORM_L6_UNORM,    GL_RGB5,                          GL_RGB5,                                0,
761             GL_RGB,                     GL_UNSIGNED_SHORT_5_6_5,          2,
762             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
763             WINED3D_GL_EXT_NONE,        convert_r5g5_snorm_l6_unorm},
764     {WINED3DFMT_R5G5_SNORM_L6_UNORM,    GL_DSDT8_MAG8_NV,                 GL_DSDT8_MAG8_NV,                       0,
765             GL_DSDT_MAG_NV,             GL_BYTE,                          3,
766             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
767             NV_TEXTURE_SHADER,          convert_r5g5_snorm_l6_unorm_nv},
768     {WINED3DFMT_R8G8_SNORM_L8X8_UNORM,  GL_RGB8,                          GL_RGB8,                                0,
769             GL_BGRA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      4,
770             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
771             WINED3D_GL_EXT_NONE,        convert_r8g8_snorm_l8x8_unorm},
772     {WINED3DFMT_R8G8_SNORM_L8X8_UNORM,  GL_DSDT8_MAG8_INTENSITY8_NV,      GL_DSDT8_MAG8_INTENSITY8_NV,            0,
773             GL_DSDT_MAG_VIB_NV,         GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
774             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
775             NV_TEXTURE_SHADER,          convert_r8g8_snorm_l8x8_unorm_nv},
776     {WINED3DFMT_R8G8B8A8_SNORM,         GL_RGBA8,                         GL_RGBA8,                               0,
777             GL_BGRA,                    GL_UNSIGNED_BYTE,                 4,
778             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
779             WINED3D_GL_EXT_NONE,        convert_r8g8b8a8_snorm},
780     {WINED3DFMT_R8G8B8A8_SNORM,         GL_SIGNED_RGBA8_NV,               GL_SIGNED_RGBA8_NV,                     0,
781             GL_RGBA,                    GL_BYTE,                          0,
782             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
783             NV_TEXTURE_SHADER,          NULL},
784     {WINED3DFMT_R16G16_SNORM,           GL_RGB16,                         GL_RGB16,                               0,
785             GL_BGR,                     GL_UNSIGNED_SHORT,                6,
786             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
787             WINED3D_GL_EXT_NONE,        convert_r16g16_snorm},
788     {WINED3DFMT_R16G16_SNORM,           GL_SIGNED_HILO16_NV,              GL_SIGNED_HILO16_NV,                    0,
789             GL_HILO_NV,                 GL_SHORT,                         0,
790             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
791             NV_TEXTURE_SHADER,          NULL},
792     /* Depth stencil formats */
793     {WINED3DFMT_D16_LOCKABLE,           GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
794             GL_DEPTH_COMPONENT,         GL_UNSIGNED_SHORT,                0,
795             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
796             ARB_DEPTH_TEXTURE,          NULL},
797     {WINED3DFMT_D32_UNORM,              GL_DEPTH_COMPONENT32_ARB,         GL_DEPTH_COMPONENT32_ARB,               0,
798             GL_DEPTH_COMPONENT,         GL_UNSIGNED_INT,                  0,
799             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
800             ARB_DEPTH_TEXTURE,          NULL},
801     {WINED3DFMT_S1_UINT_D15_UNORM,      GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
802             GL_DEPTH_COMPONENT,         GL_UNSIGNED_SHORT,                0,
803             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
804             ARB_DEPTH_TEXTURE,          NULL},
805     {WINED3DFMT_S1_UINT_D15_UNORM,      GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
806             GL_DEPTH_STENCIL_EXT,       GL_UNSIGNED_INT_24_8_EXT,         4,
807             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
808             EXT_PACKED_DEPTH_STENCIL,   convert_s1_uint_d15_unorm},
809     {WINED3DFMT_S1_UINT_D15_UNORM,      GL_DEPTH24_STENCIL8,              GL_DEPTH24_STENCIL8,                    0,
810             GL_DEPTH_STENCIL,           GL_UNSIGNED_INT_24_8,             4,
811             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
812             ARB_FRAMEBUFFER_OBJECT,     convert_s1_uint_d15_unorm},
813     {WINED3DFMT_D24_UNORM_S8_UINT,      GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
814             GL_DEPTH_COMPONENT,         GL_UNSIGNED_INT,                  0,
815             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
816             | WINED3DFMT_FLAG_SHADOW,
817             ARB_DEPTH_TEXTURE,          NULL},
818     {WINED3DFMT_D24_UNORM_S8_UINT,      GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
819             GL_DEPTH_STENCIL_EXT,       GL_UNSIGNED_INT_24_8_EXT,         0,
820             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
821             | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
822             EXT_PACKED_DEPTH_STENCIL,   NULL},
823     {WINED3DFMT_D24_UNORM_S8_UINT,      GL_DEPTH24_STENCIL8,              GL_DEPTH24_STENCIL8,                    0,
824             GL_DEPTH_STENCIL,           GL_UNSIGNED_INT_24_8,             0,
825             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
826             | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
827             ARB_FRAMEBUFFER_OBJECT,     NULL},
828     {WINED3DFMT_X8D24_UNORM,            GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
829             GL_DEPTH_COMPONENT,         GL_UNSIGNED_INT,                  0,
830             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
831             | WINED3DFMT_FLAG_SHADOW,
832             ARB_DEPTH_TEXTURE,          NULL},
833     {WINED3DFMT_S4X4_UINT_D24_UNORM,    GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
834             GL_DEPTH_COMPONENT,         GL_UNSIGNED_INT,                  0,
835             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
836             ARB_DEPTH_TEXTURE,          NULL},
837     {WINED3DFMT_S4X4_UINT_D24_UNORM,    GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
838             GL_DEPTH_STENCIL_EXT,       GL_UNSIGNED_INT_24_8_EXT,         4,
839             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
840             EXT_PACKED_DEPTH_STENCIL,   convert_s4x4_uint_d24_unorm},
841     {WINED3DFMT_S4X4_UINT_D24_UNORM,    GL_DEPTH24_STENCIL8,              GL_DEPTH24_STENCIL8,                    0,
842             GL_DEPTH_STENCIL,           GL_UNSIGNED_INT_24_8,             4,
843             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
844             ARB_FRAMEBUFFER_OBJECT,     convert_s4x4_uint_d24_unorm},
845     {WINED3DFMT_D16_UNORM,              GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
846             GL_DEPTH_COMPONENT,         GL_UNSIGNED_SHORT,                0,
847             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
848             | WINED3DFMT_FLAG_SHADOW,
849             ARB_DEPTH_TEXTURE,          NULL},
850     {WINED3DFMT_L16_UNORM,              GL_LUMINANCE16,                   GL_LUMINANCE16,                         0,
851             GL_LUMINANCE,               GL_UNSIGNED_SHORT,                0,
852             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
853             WINED3D_GL_EXT_NONE,        NULL},
854     {WINED3DFMT_D32_FLOAT,              GL_DEPTH_COMPONENT32F,            GL_DEPTH_COMPONENT32F,                  0,
855             GL_DEPTH_COMPONENT,         GL_FLOAT,                         0,
856             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
857             ARB_DEPTH_BUFFER_FLOAT,     NULL},
858     {WINED3DFMT_S8_UINT_D24_FLOAT,      GL_DEPTH32F_STENCIL8,             GL_DEPTH32F_STENCIL8,                   0,
859             GL_DEPTH_STENCIL,           GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
860             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
861             ARB_DEPTH_BUFFER_FLOAT,     convert_s8_uint_d24_float},
862     /* Vendor-specific formats */
863     {WINED3DFMT_ATI2N,                  GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
864             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
865             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_COMPRESSED,
866             ATI_TEXTURE_COMPRESSION_3DC, NULL},
867     {WINED3DFMT_ATI2N,                  GL_COMPRESSED_RG_RGTC2,           GL_COMPRESSED_RG_RGTC2,                 0,
868             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
869             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_COMPRESSED,
870             ARB_TEXTURE_COMPRESSION_RGTC, NULL},
871     {WINED3DFMT_INTZ,                   GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
872             GL_DEPTH_STENCIL_EXT,       GL_UNSIGNED_INT_24_8_EXT,         0,
873             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
874             | WINED3DFMT_FLAG_STENCIL,
875             EXT_PACKED_DEPTH_STENCIL,   NULL},
876     {WINED3DFMT_INTZ,                   GL_DEPTH24_STENCIL8,              GL_DEPTH24_STENCIL8,                    0,
877             GL_DEPTH_STENCIL,           GL_UNSIGNED_INT_24_8,             0,
878             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
879             | WINED3DFMT_FLAG_STENCIL,
880             ARB_FRAMEBUFFER_OBJECT,     NULL},
881     {WINED3DFMT_NULL,                   GL_RGBA8,                         GL_RGBA8,                               0,
882             GL_RGBA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      0,
883             WINED3DFMT_FLAG_RENDERTARGET,
884             ARB_FRAMEBUFFER_OBJECT,     NULL},
885 };
886
887 static inline int getFmtIdx(enum wined3d_format_id format_id)
888 {
889     /* First check if the format is at the position of its value.
890      * This will catch the argb formats before the loop is entered. */
891     if (format_id < (sizeof(formats) / sizeof(*formats))
892             && formats[format_id].id == format_id)
893     {
894         return format_id;
895     }
896     else
897     {
898         unsigned int i;
899
900         for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
901         {
902             if (formats[i].id == format_id) return i;
903         }
904     }
905     return -1;
906 }
907
908 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
909 {
910     UINT format_count = sizeof(formats) / sizeof(*formats);
911     UINT i;
912
913     gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
914     if (!gl_info->formats)
915     {
916         ERR("Failed to allocate memory.\n");
917         return FALSE;
918     }
919
920     for (i = 0; i < format_count; ++i)
921     {
922         struct wined3d_format *format = &gl_info->formats[i];
923         format->id = formats[i].id;
924         format->red_size = formats[i].red_size;
925         format->green_size = formats[i].green_size;
926         format->blue_size = formats[i].blue_size;
927         format->alpha_size = formats[i].alpha_size;
928         format->red_offset = formats[i].red_offset;
929         format->green_offset = formats[i].green_offset;
930         format->blue_offset = formats[i].blue_offset;
931         format->alpha_offset = formats[i].alpha_offset;
932         format->byte_count = formats[i].bpp;
933         format->depth_size = formats[i].depth_size;
934         format->stencil_size = formats[i].stencil_size;
935         format->block_width = 1;
936         format->block_height = 1;
937         format->block_byte_count = formats[i].bpp;
938     }
939
940     for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
941     {
942         int fmt_idx = getFmtIdx(format_base_flags[i].id);
943
944         if (fmt_idx == -1)
945         {
946             ERR("Format %s (%#x) not found.\n",
947                     debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
948             HeapFree(GetProcessHeap(), 0, gl_info->formats);
949             return FALSE;
950         }
951
952         gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
953     }
954
955     return TRUE;
956 }
957
958 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
959 {
960     unsigned int i;
961
962     for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i)
963     {
964         struct wined3d_format *format;
965         int fmt_idx = getFmtIdx(format_block_info[i].id);
966
967         if (fmt_idx == -1)
968         {
969             ERR("Format %s (%#x) not found.\n",
970                     debug_d3dformat(format_block_info[i].id), format_block_info[i].id);
971             return FALSE;
972         }
973
974         format = &gl_info->formats[fmt_idx];
975         format->block_width = format_block_info[i].block_width;
976         format->block_height = format_block_info[i].block_height;
977         format->block_byte_count = format_block_info[i].block_byte_count;
978         format->flags |= WINED3DFMT_FLAG_BLOCKS;
979     }
980
981     return TRUE;
982 }
983
984 /* Context activation is done by the caller. */
985 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
986 {
987     /* Check if the default internal format is supported as a frame buffer
988      * target, otherwise fall back to the render target internal.
989      *
990      * Try to stick to the standard format if possible, this limits precision differences. */
991     GLenum status;
992     GLuint tex;
993
994     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;
1142             a_range = format->alpha_size < 8 ? 1 << (8 - format->alpha_size) : 1;
1143             if (format->red_size && (r < 0x7f - r_range || r > 0x7f + 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_GEOMETRY_SHADER(state))
2339         return "STATE_GEOMETRY_SHADER";
2340     if (STATE_IS_VIEWPORT(state))
2341         return "STATE_VIEWPORT";
2342     if (STATE_IS_VERTEXSHADERCONSTANT(state))
2343         return "STATE_VERTEXSHADERCONSTANT";
2344     if (STATE_IS_PIXELSHADERCONSTANT(state))
2345         return "STATE_PIXELSHADERCONSTANT";
2346     if (STATE_IS_ACTIVELIGHT(state))
2347         return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2348     if (STATE_IS_SCISSORRECT(state))
2349         return "STATE_SCISSORRECT";
2350     if (STATE_IS_CLIPPLANE(state))
2351         return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2352     if (STATE_IS_MATERIAL(state))
2353         return "STATE_MATERIAL";
2354     if (STATE_IS_FRONTFACE(state))
2355         return "STATE_FRONTFACE";
2356     if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2357         return "STATE_POINTSPRITECOORDORIGIN";
2358     if (STATE_IS_BASEVERTEXINDEX(state))
2359         return "STATE_BASEVERTEXINDEX";
2360     if (STATE_IS_FRAMEBUFFER(state))
2361         return "STATE_FRAMEBUFFER";
2362
2363     return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2364 }
2365
2366 const char *debug_d3dpool(enum wined3d_pool pool)
2367 {
2368     switch (pool)
2369     {
2370 #define POOL_TO_STR(p) case p: return #p
2371         POOL_TO_STR(WINED3D_POOL_DEFAULT);
2372         POOL_TO_STR(WINED3D_POOL_MANAGED);
2373         POOL_TO_STR(WINED3D_POOL_SYSTEM_MEM);
2374         POOL_TO_STR(WINED3D_POOL_SCRATCH);
2375 #undef  POOL_TO_STR
2376         default:
2377             FIXME("Unrecognized pool %#x.\n", pool);
2378             return "unrecognized";
2379     }
2380 }
2381
2382 const char *debug_fbostatus(GLenum status) {
2383     switch(status) {
2384 #define FBOSTATUS_TO_STR(u) case u: return #u
2385         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2386         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2387         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2388         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2389         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2390         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2391         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2392         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2393         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2394         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2395 #undef FBOSTATUS_TO_STR
2396         default:
2397             FIXME("Unrecognied FBO status 0x%08x\n", status);
2398             return "unrecognized";
2399     }
2400 }
2401
2402 const char *debug_glerror(GLenum error) {
2403     switch(error) {
2404 #define GLERROR_TO_STR(u) case u: return #u
2405         GLERROR_TO_STR(GL_NO_ERROR);
2406         GLERROR_TO_STR(GL_INVALID_ENUM);
2407         GLERROR_TO_STR(GL_INVALID_VALUE);
2408         GLERROR_TO_STR(GL_INVALID_OPERATION);
2409         GLERROR_TO_STR(GL_STACK_OVERFLOW);
2410         GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2411         GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2412         GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2413 #undef GLERROR_TO_STR
2414         default:
2415             FIXME("Unrecognied GL error 0x%08x\n", error);
2416             return "unrecognized";
2417     }
2418 }
2419
2420 const char *debug_d3dbasis(enum wined3d_basis_type basis)
2421 {
2422     switch (basis)
2423     {
2424         case WINED3D_BASIS_BEZIER:      return "WINED3D_BASIS_BEZIER";
2425         case WINED3D_BASIS_BSPLINE:     return "WINED3D_BASIS_BSPLINE";
2426         case WINED3D_BASIS_INTERPOLATE: return "WINED3D_BASIS_INTERPOLATE";
2427         default:                        return "unrecognized";
2428     }
2429 }
2430
2431 const char *debug_d3ddegree(enum wined3d_degree_type degree)
2432 {
2433     switch (degree)
2434     {
2435         case WINED3D_DEGREE_LINEAR:     return "WINED3D_DEGREE_LINEAR";
2436         case WINED3D_DEGREE_QUADRATIC:  return "WINED3D_DEGREE_QUADRATIC";
2437         case WINED3D_DEGREE_CUBIC:      return "WINED3D_DEGREE_CUBIC";
2438         case WINED3D_DEGREE_QUINTIC:    return "WINED3D_DEGREE_QUINTIC";
2439         default:                        return "unrecognized";
2440     }
2441 }
2442
2443 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2444 {
2445     switch(source)
2446     {
2447 #define WINED3D_TO_STR(x) case x: return #x
2448         WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2449         WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2450         WINED3D_TO_STR(CHANNEL_SOURCE_X);
2451         WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2452         WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2453         WINED3D_TO_STR(CHANNEL_SOURCE_W);
2454         WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2455         WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2456 #undef WINED3D_TO_STR
2457         default:
2458             FIXME("Unrecognized fixup_channel_source %#x\n", source);
2459             return "unrecognized";
2460     }
2461 }
2462
2463 static const char *debug_complex_fixup(enum complex_fixup fixup)
2464 {
2465     switch(fixup)
2466     {
2467 #define WINED3D_TO_STR(x) case x: return #x
2468         WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2469         WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2470         WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2471         WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2472 #undef WINED3D_TO_STR
2473         default:
2474             FIXME("Unrecognized complex fixup %#x\n", fixup);
2475             return "unrecognized";
2476     }
2477 }
2478
2479 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2480 {
2481     if (is_complex_fixup(fixup))
2482     {
2483         TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2484         return;
2485     }
2486
2487     TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2488     TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2489     TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2490     TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2491 }
2492
2493 const char *debug_surflocation(DWORD flag) {
2494     char buf[128];
2495
2496     buf[0] = 0;
2497     if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");                    /* 17 */
2498     if (flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");                /* 19 */
2499     if (flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");                  /* 18 */
2500     if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");                  /* 18 */
2501     if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE");    /* 25 */
2502     if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED");          /* 22 */
2503     return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2504 }
2505
2506 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2507         enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2508 {
2509     if (op == WINED3D_TOP_DISABLE)
2510         return FALSE;
2511     if (state->textures[stage])
2512         return FALSE;
2513
2514     if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2515             && op != WINED3D_TOP_SELECT_ARG2)
2516         return TRUE;
2517     if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2518             && op != WINED3D_TOP_SELECT_ARG1)
2519         return TRUE;
2520     if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2521             && (op == WINED3D_TOP_MULTIPLY_ADD || op == WINED3D_TOP_LERP))
2522         return TRUE;
2523
2524     return FALSE;
2525 }
2526
2527 /* Setup this textures matrix according to the texture flags*/
2528 /* GL locking is done by the caller (state handler) */
2529 void set_texture_matrix(const struct wined3d_gl_info *gl_info, const float *smat, DWORD flags,
2530         BOOL calculatedCoords, BOOL transformed, enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2531 {
2532     float mat[16];
2533
2534     gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
2535     checkGLcall("glMatrixMode(GL_TEXTURE)");
2536
2537     if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed)
2538     {
2539         gl_info->gl_ops.gl.p_glLoadIdentity();
2540         checkGLcall("glLoadIdentity()");
2541         return;
2542     }
2543
2544     if (flags == (WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED))
2545     {
2546         ERR("Invalid texture transform flags: WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED.\n");
2547         return;
2548     }
2549
2550     memcpy(mat, smat, 16 * sizeof(float));
2551
2552     if (flags & WINED3D_TTFF_PROJECTED)
2553     {
2554         if (!ffp_proj_control)
2555         {
2556             switch (flags & ~WINED3D_TTFF_PROJECTED)
2557             {
2558                 case WINED3D_TTFF_COUNT2:
2559                     mat[ 3] = mat[ 1];
2560                     mat[ 7] = mat[ 5];
2561                     mat[11] = mat[ 9];
2562                     mat[15] = mat[13];
2563                     mat[ 1] = mat[ 5] = mat[ 9] = mat[13] = 0.0f;
2564                     break;
2565                 case WINED3D_TTFF_COUNT3:
2566                     mat[ 3] = mat[ 2];
2567                     mat[ 7] = mat[ 6];
2568                     mat[11] = mat[10];
2569                     mat[15] = mat[14];
2570                     mat[ 2] = mat[ 6] = mat[10] = mat[14] = 0.0f;
2571                     break;
2572             }
2573         }
2574     } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2575         if(!calculatedCoords) {
2576             switch(vtx_fmt)
2577             {
2578                 case WINED3DFMT_R32_FLOAT:
2579                     /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2580                      * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2581                      * the input value to the transformation will be 0, so the matrix value is irrelevant
2582                      */
2583                     mat[12] = mat[4];
2584                     mat[13] = mat[5];
2585                     mat[14] = mat[6];
2586                     mat[15] = mat[7];
2587                     break;
2588                 case WINED3DFMT_R32G32_FLOAT:
2589                     /* See above, just 3rd and 4th coord
2590                     */
2591                     mat[12] = mat[8];
2592                     mat[13] = mat[9];
2593                     mat[14] = mat[10];
2594                     mat[15] = mat[11];
2595                     break;
2596                 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2597                 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2598
2599                 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2600                  * into a bad place. The division elimination below will apply to make sure the
2601                  * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2602                  */
2603                 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2604                     break;
2605                 default:
2606                     FIXME("Unexpected fixed function texture coord input\n");
2607             }
2608         }
2609         if (!ffp_proj_control)
2610         {
2611             switch (flags & ~WINED3D_TTFF_PROJECTED)
2612             {
2613                 /* case WINED3D_TTFF_COUNT1: Won't ever get here. */
2614                 case WINED3D_TTFF_COUNT2:
2615                     mat[2] = mat[6] = mat[10] = mat[14] = 0;
2616                 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2617                 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2618                 * the 4th coord evaluates to 1.0 to eliminate that.
2619                 *
2620                 * If the fixed function pipeline is used, the 4th value remains unused,
2621                 * so there is no danger in doing this. With vertex shaders we have a
2622                 * problem. Should an app hit that problem, the code here would have to
2623                 * check for pixel shaders, and the shader has to undo the default gl divide.
2624                 *
2625                 * A more serious problem occurs if the app passes 4 coordinates in, and the
2626                 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2627                 * or a replacement shader. */
2628                 default:
2629                     mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2630             }
2631         }
2632     }
2633
2634     gl_info->gl_ops.gl.p_glLoadMatrixf(mat);
2635     checkGLcall("glLoadMatrixf(mat)");
2636 }
2637
2638 /* This small helper function is used to convert a bitmask into the number of masked bits */
2639 unsigned int count_bits(unsigned int mask)
2640 {
2641     unsigned int count;
2642     for (count = 0; mask; ++count)
2643     {
2644         mask &= mask - 1;
2645     }
2646     return count;
2647 }
2648
2649 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2650  * The later function requires individual color components. */
2651 BOOL getColorBits(const struct wined3d_format *format,
2652         BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2653 {
2654     TRACE("format %s.\n", debug_d3dformat(format->id));
2655
2656     switch (format->id)
2657     {
2658         case WINED3DFMT_B10G10R10A2_UNORM:
2659         case WINED3DFMT_R10G10B10A2_UNORM:
2660         case WINED3DFMT_B8G8R8X8_UNORM:
2661         case WINED3DFMT_B8G8R8_UNORM:
2662         case WINED3DFMT_B8G8R8A8_UNORM:
2663         case WINED3DFMT_R8G8B8A8_UNORM:
2664         case WINED3DFMT_B5G5R5X1_UNORM:
2665         case WINED3DFMT_B5G5R5A1_UNORM:
2666         case WINED3DFMT_B5G6R5_UNORM:
2667         case WINED3DFMT_B4G4R4X4_UNORM:
2668         case WINED3DFMT_B4G4R4A4_UNORM:
2669         case WINED3DFMT_B2G3R3_UNORM:
2670         case WINED3DFMT_P8_UINT_A8_UNORM:
2671         case WINED3DFMT_P8_UINT:
2672             break;
2673         default:
2674             FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2675             return FALSE;
2676     }
2677
2678     *redSize = format->red_size;
2679     *greenSize = format->green_size;
2680     *blueSize = format->blue_size;
2681     *alphaSize = format->alpha_size;
2682     *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2683
2684     TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2685             *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2686     return TRUE;
2687 }
2688
2689 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2690 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
2691 {
2692     TRACE("format %s.\n", debug_d3dformat(format->id));
2693
2694     switch (format->id)
2695     {
2696         case WINED3DFMT_D16_LOCKABLE:
2697         case WINED3DFMT_D16_UNORM:
2698         case WINED3DFMT_S1_UINT_D15_UNORM:
2699         case WINED3DFMT_X8D24_UNORM:
2700         case WINED3DFMT_S4X4_UINT_D24_UNORM:
2701         case WINED3DFMT_D24_UNORM_S8_UINT:
2702         case WINED3DFMT_S8_UINT_D24_FLOAT:
2703         case WINED3DFMT_D32_UNORM:
2704         case WINED3DFMT_D32_FLOAT:
2705         case WINED3DFMT_INTZ:
2706             break;
2707         default:
2708             FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2709             return FALSE;
2710     }
2711
2712     *depthSize = format->depth_size;
2713     *stencilSize = format->stencil_size;
2714
2715     TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2716             *depthSize, *stencilSize, debug_d3dformat(format->id));
2717     return TRUE;
2718 }
2719
2720 /* Note: It's the caller's responsibility to ensure values can be expressed
2721  * in the requested format. UNORM formats for example can only express values
2722  * in the range 0.0f -> 1.0f. */
2723 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color)
2724 {
2725     static const struct
2726     {
2727         enum wined3d_format_id format_id;
2728         float r_mul;
2729         float g_mul;
2730         float b_mul;
2731         float a_mul;
2732         BYTE r_shift;
2733         BYTE g_shift;
2734         BYTE b_shift;
2735         BYTE a_shift;
2736     }
2737     conv[] =
2738     {
2739         {WINED3DFMT_B8G8R8A8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
2740         {WINED3DFMT_B8G8R8X8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
2741         {WINED3DFMT_B8G8R8_UNORM,       255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
2742         {WINED3DFMT_B5G6R5_UNORM,        31.0f,   63.0f,   31.0f,    0.0f, 11,  5,  0,  0},
2743         {WINED3DFMT_B5G5R5A1_UNORM,      31.0f,   31.0f,   31.0f,    1.0f, 10,  5,  0, 15},
2744         {WINED3DFMT_B5G5R5X1_UNORM,      31.0f,   31.0f,   31.0f,    1.0f, 10,  5,  0, 15},
2745         {WINED3DFMT_A8_UNORM,             0.0f,    0.0f,    0.0f,  255.0f,  0,  0,  0,  0},
2746         {WINED3DFMT_B4G4R4A4_UNORM,      15.0f,   15.0f,   15.0f,   15.0f,  8,  4,  0, 12},
2747         {WINED3DFMT_B4G4R4X4_UNORM,      15.0f,   15.0f,   15.0f,   15.0f,  8,  4,  0, 12},
2748         {WINED3DFMT_B2G3R3_UNORM,         7.0f,    7.0f,    3.0f,    0.0f,  5,  2,  0,  0},
2749         {WINED3DFMT_R8G8B8A8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f,  0,  8, 16, 24},
2750         {WINED3DFMT_R8G8B8X8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f,  0,  8, 16, 24},
2751         {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f,    3.0f, 20, 10,  0, 30},
2752         {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f,    3.0f,  0, 10, 20, 30},
2753     };
2754     const struct wined3d_format *format = surface->resource.format;
2755     unsigned int i;
2756
2757     TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2758             color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2759
2760     for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2761     {
2762         DWORD ret;
2763
2764         if (format->id != conv[i].format_id) continue;
2765
2766         ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2767         ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2768         ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2769         ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2770
2771         TRACE("Returning 0x%08x.\n", ret);
2772
2773         return ret;
2774     }
2775
2776     if (format->id == WINED3DFMT_P8_UINT)
2777     {
2778         PALETTEENTRY *e;
2779         BYTE r, g, b, a;
2780
2781         if (!surface->palette)
2782         {
2783             WARN("Surface doesn't have a palette, returning 0.\n");
2784             return 0;
2785         }
2786
2787         r = (BYTE)((color->r * 255.0f) + 0.5f);
2788         g = (BYTE)((color->g * 255.0f) + 0.5f);
2789         b = (BYTE)((color->b * 255.0f) + 0.5f);
2790         a = (BYTE)((color->a * 255.0f) + 0.5f);
2791
2792         e = &surface->palette->palents[a];
2793         if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2794             return a;
2795
2796         WARN("Alpha didn't match index, searching full palette.\n");
2797
2798         for (i = 0; i < 256; ++i)
2799         {
2800             e = &surface->palette->palents[i];
2801             if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2802                 return i;
2803         }
2804
2805         FIXME("Unable to convert color to palette index.\n");
2806
2807         return 0;
2808     }
2809
2810     FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2811
2812     return 0;
2813 }
2814
2815 /* DirectDraw stuff */
2816 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2817 {
2818     switch (depth)
2819     {
2820         case 8:  return WINED3DFMT_P8_UINT;
2821         case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2822         case 16: return WINED3DFMT_B5G6R5_UNORM;
2823         case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2824         case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2825         default: return WINED3DFMT_UNKNOWN;
2826     }
2827 }
2828
2829 void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
2830         const struct wined3d_matrix *src2)
2831 {
2832     struct wined3d_matrix temp;
2833
2834     /* Now do the multiplication 'by hand'.
2835        I know that all this could be optimised, but this will be done later :-) */
2836     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);
2837     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);
2838     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);
2839     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);
2840
2841     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);
2842     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);
2843     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);
2844     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);
2845
2846     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);
2847     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);
2848     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);
2849     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);
2850
2851     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);
2852     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);
2853     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);
2854     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);
2855
2856     /* And copy the new matrix in the good storage.. */
2857     memcpy(dest, &temp, 16 * sizeof(float));
2858 }
2859
2860 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2861     DWORD size = 0;
2862     int i;
2863     int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2864
2865     if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2866     if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2867     if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2868     if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2869     switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2870         case WINED3DFVF_XYZ:    size += 3 * sizeof(float); break;
2871         case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2872         case WINED3DFVF_XYZB1:  size += 4 * sizeof(float); break;
2873         case WINED3DFVF_XYZB2:  size += 5 * sizeof(float); break;
2874         case WINED3DFVF_XYZB3:  size += 6 * sizeof(float); break;
2875         case WINED3DFVF_XYZB4:  size += 7 * sizeof(float); break;
2876         case WINED3DFVF_XYZB5:  size += 8 * sizeof(float); break;
2877         case WINED3DFVF_XYZW:   size += 4 * sizeof(float); break;
2878         default: ERR("Unexpected position mask\n");
2879     }
2880     for (i = 0; i < numTextures; i++) {
2881         size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2882     }
2883
2884     return size;
2885 }
2886
2887 void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_state *state,
2888         struct ffp_frag_settings *settings, BOOL ignore_textype)
2889 {
2890 #define ARG1 0x01
2891 #define ARG2 0x02
2892 #define ARG0 0x04
2893     static const unsigned char args[WINED3D_TOP_LERP + 1] =
2894     {
2895         /* undefined                        */  0,
2896         /* D3DTOP_DISABLE                   */  0,
2897         /* D3DTOP_SELECTARG1                */  ARG1,
2898         /* D3DTOP_SELECTARG2                */  ARG2,
2899         /* D3DTOP_MODULATE                  */  ARG1 | ARG2,
2900         /* D3DTOP_MODULATE2X                */  ARG1 | ARG2,
2901         /* D3DTOP_MODULATE4X                */  ARG1 | ARG2,
2902         /* D3DTOP_ADD                       */  ARG1 | ARG2,
2903         /* D3DTOP_ADDSIGNED                 */  ARG1 | ARG2,
2904         /* D3DTOP_ADDSIGNED2X               */  ARG1 | ARG2,
2905         /* D3DTOP_SUBTRACT                  */  ARG1 | ARG2,
2906         /* D3DTOP_ADDSMOOTH                 */  ARG1 | ARG2,
2907         /* D3DTOP_BLENDDIFFUSEALPHA         */  ARG1 | ARG2,
2908         /* D3DTOP_BLENDTEXTUREALPHA         */  ARG1 | ARG2,
2909         /* D3DTOP_BLENDFACTORALPHA          */  ARG1 | ARG2,
2910         /* D3DTOP_BLENDTEXTUREALPHAPM       */  ARG1 | ARG2,
2911         /* D3DTOP_BLENDCURRENTALPHA         */  ARG1 | ARG2,
2912         /* D3DTOP_PREMODULATE               */  ARG1 | ARG2,
2913         /* D3DTOP_MODULATEALPHA_ADDCOLOR    */  ARG1 | ARG2,
2914         /* D3DTOP_MODULATECOLOR_ADDALPHA    */  ARG1 | ARG2,
2915         /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */  ARG1 | ARG2,
2916         /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */  ARG1 | ARG2,
2917         /* D3DTOP_BUMPENVMAP                */  ARG1 | ARG2,
2918         /* D3DTOP_BUMPENVMAPLUMINANCE       */  ARG1 | ARG2,
2919         /* D3DTOP_DOTPRODUCT3               */  ARG1 | ARG2,
2920         /* D3DTOP_MULTIPLYADD               */  ARG1 | ARG2 | ARG0,
2921         /* D3DTOP_LERP                      */  ARG1 | ARG2 | ARG0
2922     };
2923     unsigned int i;
2924     DWORD ttff;
2925     DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2926     const struct wined3d_surface *rt = state->fb->render_targets[0];
2927     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2928
2929     for (i = 0; i < gl_info->limits.texture_stages; ++i)
2930     {
2931         const struct wined3d_texture *texture;
2932
2933         settings->op[i].padding = 0;
2934         if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
2935         {
2936             settings->op[i].cop = WINED3D_TOP_DISABLE;
2937             settings->op[i].aop = WINED3D_TOP_DISABLE;
2938             settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2939             settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2940             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2941             settings->op[i].dst = resultreg;
2942             settings->op[i].tex_type = tex_1d;
2943             settings->op[i].projected = proj_none;
2944             i++;
2945             break;
2946         }
2947
2948         if ((texture = state->textures[i]))
2949         {
2950             settings->op[i].color_fixup = texture->resource.format->color_fixup;
2951             if (ignore_textype)
2952             {
2953                 settings->op[i].tex_type = tex_1d;
2954             }
2955             else
2956             {
2957                 switch (texture->target)
2958                 {
2959                     case GL_TEXTURE_1D:
2960                         settings->op[i].tex_type = tex_1d;
2961                         break;
2962                     case GL_TEXTURE_2D:
2963                         settings->op[i].tex_type = tex_2d;
2964                         break;
2965                     case GL_TEXTURE_3D:
2966                         settings->op[i].tex_type = tex_3d;
2967                         break;
2968                     case GL_TEXTURE_CUBE_MAP_ARB:
2969                         settings->op[i].tex_type = tex_cube;
2970                         break;
2971                     case GL_TEXTURE_RECTANGLE_ARB:
2972                         settings->op[i].tex_type = tex_rect;
2973                         break;
2974                 }
2975             }
2976         } else {
2977             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2978             settings->op[i].tex_type = tex_1d;
2979         }
2980
2981         cop = state->texture_states[i][WINED3D_TSS_COLOR_OP];
2982         aop = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
2983
2984         carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG1] : ARG_UNUSED;
2985         carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG2] : ARG_UNUSED;
2986         carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG0] : ARG_UNUSED;
2987
2988         if (is_invalid_op(state, i, cop, carg1, carg2, carg0))
2989         {
2990             carg0 = ARG_UNUSED;
2991             carg2 = ARG_UNUSED;
2992             carg1 = WINED3DTA_CURRENT;
2993             cop = WINED3D_TOP_SELECT_ARG1;
2994         }
2995
2996         if (cop == WINED3D_TOP_DOTPRODUCT3)
2997         {
2998             /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2999              * the color result to the alpha component of the destination
3000              */
3001             aop = cop;
3002             aarg1 = carg1;
3003             aarg2 = carg2;
3004             aarg0 = carg0;
3005         }
3006         else
3007         {
3008             aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] : ARG_UNUSED;
3009             aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] : ARG_UNUSED;
3010             aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] : ARG_UNUSED;
3011         }
3012
3013         if (!i && state->textures[0] && state->render_states[WINED3D_RS_COLORKEYENABLE])
3014         {
3015             GLenum texture_dimensions;
3016
3017             texture = state->textures[0];
3018             texture_dimensions = texture->target;
3019
3020             if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3021             {
3022                 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3023
3024                 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size)
3025                 {
3026                     if (aop == WINED3D_TOP_DISABLE)
3027                     {
3028                        aarg1 = WINED3DTA_TEXTURE;
3029                        aop = WINED3D_TOP_SELECT_ARG1;
3030                     }
3031                     else if (aop == WINED3D_TOP_SELECT_ARG1 && aarg1 != WINED3DTA_TEXTURE)
3032                     {
3033                         if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3034                         {
3035                             aarg2 = WINED3DTA_TEXTURE;
3036                             aop = WINED3D_TOP_MODULATE;
3037                         }
3038                         else aarg1 = WINED3DTA_TEXTURE;
3039                     }
3040                     else if (aop == WINED3D_TOP_SELECT_ARG2 && aarg2 != WINED3DTA_TEXTURE)
3041                     {
3042                         if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3043                         {
3044                             aarg1 = WINED3DTA_TEXTURE;
3045                             aop = WINED3D_TOP_MODULATE;
3046                         }
3047                         else aarg2 = WINED3DTA_TEXTURE;
3048                     }
3049                 }
3050             }
3051         }
3052
3053         if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0))
3054         {
3055                aarg0 = ARG_UNUSED;
3056                aarg2 = ARG_UNUSED;
3057                aarg1 = WINED3DTA_CURRENT;
3058                aop = WINED3D_TOP_SELECT_ARG1;
3059         }
3060
3061         if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
3062                 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
3063         {
3064             ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
3065             if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3))
3066                 settings->op[i].projected = proj_count3;
3067             else if (ttff & WINED3D_TTFF_PROJECTED)
3068                 settings->op[i].projected = proj_count4;
3069             else
3070                 settings->op[i].projected = proj_none;
3071         }
3072         else
3073         {
3074             settings->op[i].projected = proj_none;
3075         }
3076
3077         settings->op[i].cop = cop;
3078         settings->op[i].aop = aop;
3079         settings->op[i].carg0 = carg0;
3080         settings->op[i].carg1 = carg1;
3081         settings->op[i].carg2 = carg2;
3082         settings->op[i].aarg0 = aarg0;
3083         settings->op[i].aarg1 = aarg1;
3084         settings->op[i].aarg2 = aarg2;
3085
3086         if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP)
3087             settings->op[i].dst = tempreg;
3088         else
3089             settings->op[i].dst = resultreg;
3090     }
3091
3092     /* Clear unsupported stages */
3093     for(; i < MAX_TEXTURES; i++) {
3094         memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
3095     }
3096
3097     if (!state->render_states[WINED3D_RS_FOGENABLE])
3098     {
3099         settings->fog = FOG_OFF;
3100     }
3101     else if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
3102     {
3103         if (use_vs(state) || state->vertex_declaration->position_transformed)
3104         {
3105             settings->fog = FOG_LINEAR;
3106         }
3107         else
3108         {
3109             switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
3110             {
3111                 case WINED3D_FOG_NONE:
3112                 case WINED3D_FOG_LINEAR:
3113                     settings->fog = FOG_LINEAR;
3114                     break;
3115                 case WINED3D_FOG_EXP:
3116                     settings->fog = FOG_EXP;
3117                     break;
3118                 case WINED3D_FOG_EXP2:
3119                     settings->fog = FOG_EXP2;
3120                     break;
3121             }
3122         }
3123     }
3124     else
3125     {
3126         switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
3127         {
3128             case WINED3D_FOG_LINEAR:
3129                 settings->fog = FOG_LINEAR;
3130                 break;
3131             case WINED3D_FOG_EXP:
3132                 settings->fog = FOG_EXP;
3133                 break;
3134             case WINED3D_FOG_EXP2:
3135                 settings->fog = FOG_EXP2;
3136                 break;
3137         }
3138     }
3139     if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB]
3140             && state->render_states[WINED3D_RS_SRGBWRITEENABLE]
3141             && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
3142     {
3143         settings->sRGB_write = 1;
3144     } else {
3145         settings->sRGB_write = 0;
3146     }
3147     if (device->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
3148             || !state->render_states[WINED3D_RS_CLIPPLANEENABLE])
3149     {
3150         /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3151          * the fixed function vertex pipeline is used(which always supports clipplanes), or
3152          * if no clipplane is enabled
3153          */
3154         settings->emul_clipplanes = 0;
3155     } else {
3156         settings->emul_clipplanes = 1;
3157     }
3158 }
3159
3160 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3161         const struct ffp_frag_settings *settings)
3162 {
3163     struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3164     return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3165 }
3166
3167 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3168 {
3169     /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3170      * whereas desc points to an extended structure with implementation specific parts. */
3171     if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3172     {
3173         ERR("Failed to insert ffp frag shader.\n");
3174     }
3175 }
3176
3177 /* Activates the texture dimension according to the bound D3D texture.
3178  * Does not care for the colorop or correct gl texture unit(when using nvrc)
3179  * Requires the caller to activate the correct unit before
3180  */
3181 /* GL locking is done by the caller (state handler) */
3182 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3183 {
3184     if (texture)
3185     {
3186         switch (texture->target)
3187         {
3188             case GL_TEXTURE_2D:
3189                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3190                 checkGLcall("glDisable(GL_TEXTURE_3D)");
3191                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3192                 {
3193                     gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3194                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3195                 }
3196                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3197                 {
3198                     gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3199                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3200                 }
3201                 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3202                 checkGLcall("glEnable(GL_TEXTURE_2D)");
3203                 break;
3204             case GL_TEXTURE_RECTANGLE_ARB:
3205                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3206                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3207                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3208                 checkGLcall("glDisable(GL_TEXTURE_3D)");
3209                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3210                 {
3211                     gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3212                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3213                 }
3214                 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_RECTANGLE_ARB);
3215                 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3216                 break;
3217             case GL_TEXTURE_3D:
3218                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3219                 {
3220                     gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3221                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3222                 }
3223                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3224                 {
3225                     gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3226                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3227                 }
3228                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3229                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3230                 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D);
3231                 checkGLcall("glEnable(GL_TEXTURE_3D)");
3232                 break;
3233             case GL_TEXTURE_CUBE_MAP_ARB:
3234                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3235                 checkGLcall("glDisable(GL_TEXTURE_2D)");
3236                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3237                 checkGLcall("glDisable(GL_TEXTURE_3D)");
3238                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3239                 {
3240                     gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3241                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3242                 }
3243                 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3244                 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3245               break;
3246         }
3247     }
3248     else
3249     {
3250         gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3251         checkGLcall("glEnable(GL_TEXTURE_2D)");
3252         gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3253         checkGLcall("glDisable(GL_TEXTURE_3D)");
3254         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3255         {
3256             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3257             checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3258         }
3259         if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3260         {
3261             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3262             checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3263         }
3264         /* Binding textures is done by samplers. A dummy texture will be bound */
3265     }
3266 }
3267
3268 /* GL locking is done by the caller (state handler) */
3269 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3270 {
3271     DWORD sampler = state_id - STATE_SAMPLER(0);
3272     DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
3273
3274     /* No need to enable / disable anything here for unused samplers. The
3275      * tex_colorop handler takes care. Also no action is needed with pixel
3276      * shaders, or if tex_colorop will take care of this business. */
3277     if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
3278         return;
3279     if (sampler >= state->lowest_disabled_stage)
3280         return;
3281     if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)))
3282         return;
3283
3284     texture_activate_dimensions(state->textures[sampler], context->gl_info);
3285 }
3286
3287 void *wined3d_rb_alloc(size_t size)
3288 {
3289     return HeapAlloc(GetProcessHeap(), 0, size);
3290 }
3291
3292 void *wined3d_rb_realloc(void *ptr, size_t size)
3293 {
3294     return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3295 }
3296
3297 void wined3d_rb_free(void *ptr)
3298 {
3299     HeapFree(GetProcessHeap(), 0, ptr);
3300 }
3301
3302 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3303 {
3304     const struct ffp_frag_settings *ka = key;
3305     const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3306
3307     return memcmp(ka, kb, sizeof(*ka));
3308 }
3309
3310 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3311 {
3312     wined3d_rb_alloc,
3313     wined3d_rb_realloc,
3314     wined3d_rb_free,
3315     ffp_frag_program_key_compare,
3316 };
3317
3318 UINT wined3d_log2i(UINT32 x)
3319 {
3320     static const UINT l[] =
3321     {
3322         ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3323           4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3324           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3325           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
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           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3329           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3330           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           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3337           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3338     };
3339     UINT32 i;
3340
3341     return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3342 }
3343
3344 /* Set the shader type for this device, depending on the given capabilities
3345  * and the user preferences in wined3d_settings. */
3346 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3347 {
3348     BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3349
3350     if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3351     else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3352     {
3353         /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3354          * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3355          * shaders only on this card. */
3356         if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3357         else *vs_selected = SHADER_GLSL;
3358     }
3359     else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3360     else *vs_selected = SHADER_NONE;
3361
3362     if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3363     else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3364     else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3365     else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3366     else *ps_selected = SHADER_NONE;
3367 }
3368
3369 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3370         const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
3371         const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
3372 {
3373     static const struct blit_shader * const blitters[] =
3374     {
3375         &arbfp_blit,
3376         &ffp_blit,
3377         &cpu_blit,
3378     };
3379     unsigned int i;
3380
3381     for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3382     {
3383         if (blitters[i]->blit_supported(gl_info, blit_op,
3384                 src_rect, src_usage, src_pool, src_format,
3385                 dst_rect, dst_usage, dst_pool, dst_format))
3386             return blitters[i];
3387     }
3388
3389     return NULL;
3390 }
3391
3392 void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
3393 {
3394     const struct wined3d_viewport *vp = &state->viewport;
3395
3396     SetRect(rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
3397
3398     if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
3399         IntersectRect(rect, rect, &state->scissor_rect);
3400 }