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