wined3d: Handle per-texture max LOD level.
[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  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25
26 #include "config.h"
27 #include "wined3d_private.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
30
31 struct StaticPixelFormatDesc
32 {
33     WINED3DFORMAT format;
34     DWORD alphaMask, redMask, greenMask, blueMask;
35     UINT bpp;
36     short depthSize, stencilSize;
37     BOOL isFourcc;
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   /* WINED3DFORMAT               alphamask    redmask    greenmask    bluemask     bpp    depth  stencil   isFourcc */
53     {WINED3DFMT_UNKNOWN,            0x0,        0x0,        0x0,        0x0,        0,      0,      0,      FALSE},
54     /* FourCC formats, kept here to have WINED3DFMT_R8G8B8(=20) at position 20 */
55     {WINED3DFMT_UYVY,               0x0,        0x0,        0x0,        0x0,        2,      0,      0,      TRUE },
56     {WINED3DFMT_YUY2,               0x0,        0x0,        0x0,        0x0,        2,      0,      0,      TRUE },
57     {WINED3DFMT_YV12,               0x0,        0x0,        0x0,        0x0,        1,      0,      0,      TRUE },
58     {WINED3DFMT_DXT1,               0x0,        0x0,        0x0,        0x0,        1,      0,      0,      TRUE },
59     {WINED3DFMT_DXT2,               0x0,        0x0,        0x0,        0x0,        1,      0,      0,      TRUE },
60     {WINED3DFMT_DXT3,               0x0,        0x0,        0x0,        0x0,        1,      0,      0,      TRUE },
61     {WINED3DFMT_DXT4,               0x0,        0x0,        0x0,        0x0,        1,      0,      0,      TRUE },
62     {WINED3DFMT_DXT5,               0x0,        0x0,        0x0,        0x0,        1,      0,      0,      TRUE },
63     {WINED3DFMT_MULTI2_ARGB8,       0x0,        0x0,        0x0,        0x0,        1/*?*/, 0,      0,      TRUE },
64     {WINED3DFMT_G8R8_G8B8,          0x0,        0x0,        0x0,        0x0,        1/*?*/, 0,      0,      TRUE },
65     {WINED3DFMT_R8G8_B8G8,          0x0,        0x0,        0x0,        0x0,        1/*?*/, 0,      0,      TRUE },
66     /* IEEE formats */
67     {WINED3DFMT_R32_FLOAT,          0x0,        0x0,        0x0,        0x0,        4,      0,      0,      FALSE},
68     {WINED3DFMT_R32G32_FLOAT,       0x0,        0x0,        0x0,        0x0,        8,      0,      0,      FALSE},
69     {WINED3DFMT_R32G32B32_FLOAT,    0x0,        0x0,        0x0,        0x0,        12,     0,      0,      FALSE},
70     {WINED3DFMT_R32G32B32A32_FLOAT, 0x1,        0x0,        0x0,        0x0,        16,     0,      0,      FALSE},
71     /* Hmm? */
72     {WINED3DFMT_CxV8U8,             0x0,        0x0,        0x0,        0x0,        2,      0,      0,      FALSE},
73     /* Float */
74     {WINED3DFMT_R16_FLOAT,          0x0,        0x0,        0x0,        0x0,        2,      0,      0,      FALSE},
75     {WINED3DFMT_R16G16_FLOAT,       0x0,        0x0,        0x0,        0x0,        4,      0,      0,      FALSE},
76     {WINED3DFMT_R16G16_SINT,        0x0,        0x0,        0x0,        0x0,        4,      0,      0,      FALSE},
77     {WINED3DFMT_R16G16B16A16_FLOAT, 0x1,        0x0,        0x0,        0x0,        8,      0,      0,      FALSE},
78     {WINED3DFMT_R16G16B16A16_SINT,  0x1,        0x0,        0x0,        0x0,        8,      0,      0,      FALSE},
79     /* Palettized formats */
80     {WINED3DFMT_A8P8,               0x0000ff00, 0x0,        0x0,        0x0,        2,      0,      0,      FALSE},
81     {WINED3DFMT_P8,                 0x0,        0x0,        0x0,        0x0,        1,      0,      0,      FALSE},
82     /* Standard ARGB formats. */
83     {WINED3DFMT_R8G8B8,             0x0,        0x00ff0000, 0x0000ff00, 0x000000ff, 3,      0,      0,      FALSE},
84     {WINED3DFMT_A8R8G8B8,           0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4,      0,      0,      FALSE},
85     {WINED3DFMT_X8R8G8B8,           0x0,        0x00ff0000, 0x0000ff00, 0x000000ff, 4,      0,      0,      FALSE},
86     {WINED3DFMT_R5G6B5,             0x0,        0x0000f800, 0x000007e0, 0x0000001f, 2,      0,      0,      FALSE},
87     {WINED3DFMT_X1R5G5B5,           0x0,        0x00007c00, 0x000003e0, 0x0000001f, 2,      0,      0,      FALSE},
88     {WINED3DFMT_A1R5G5B5,           0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2,      0,      0,      FALSE},
89     {WINED3DFMT_A4R4G4B4,           0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2,      0,      0,      FALSE},
90     {WINED3DFMT_R3G3B2,             0x0,        0x000000e0, 0x0000001c, 0x00000003, 1,      0,      0,      FALSE},
91     {WINED3DFMT_A8_UNORM,           0x000000ff, 0x0,        0x0,        0x0,        1,      0,      0,      FALSE},
92     {WINED3DFMT_A8R3G3B2,           0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2,      0,      0,      FALSE},
93     {WINED3DFMT_X4R4G4B4,           0x0,        0x00000f00, 0x000000f0, 0x0000000f, 2,      0,      0,      FALSE},
94     {WINED3DFMT_R10G10B10A2_UNORM,  0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4,      0,      0,      FALSE},
95     {WINED3DFMT_R10G10B10A2_UINT,   0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4,      0,      0,      FALSE},
96     {WINED3DFMT_R10G10B10A2_SNORM,  0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4,      0,      0,      FALSE},
97     {WINED3DFMT_R8G8B8A8_UNORM,     0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4,      0,      0,      FALSE},
98     {WINED3DFMT_R8G8B8A8_UINT,      0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4,      0,      0,      FALSE},
99     {WINED3DFMT_X8B8G8R8,           0x0,        0x000000ff, 0x0000ff00, 0x00ff0000, 4,      0,      0,      FALSE},
100     {WINED3DFMT_R16G16_UNORM,       0x0,        0x0000ffff, 0xffff0000, 0x0,        4,      0,      0,      FALSE},
101     {WINED3DFMT_A2R10G10B10,        0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4,      0,      0,      FALSE},
102     {WINED3DFMT_R16G16B16A16_UNORM, 0x1,        0x0000ffff, 0xffff0000, 0x0,        8,      0,      0,      FALSE},
103     /* Luminance */
104     {WINED3DFMT_L8,                 0x0,        0x0,        0x0,        0x0,        1,      0,      0,      FALSE},
105     {WINED3DFMT_A8L8,               0x0000ff00, 0x0,        0x0,        0x0,        2,      0,      0,      FALSE},
106     {WINED3DFMT_A4L4,               0x000000f0, 0x0,        0x0,        0x0,        1,      0,      0,      FALSE},
107     /* Bump mapping stuff */
108     {WINED3DFMT_R8G8_SNORM,         0x0,        0x0,        0x0,        0x0,        2,      0,      0,      FALSE},
109     {WINED3DFMT_L6V5U5,             0x0,        0x0,        0x0,        0x0,        2,      0,      0,      FALSE},
110     {WINED3DFMT_X8L8V8U8,           0x0,        0x0,        0x0,        0x0,        4,      0,      0,      FALSE},
111     {WINED3DFMT_R8G8B8A8_SNORM,     0x0,        0x0,        0x0,        0x0,        4,      0,      0,      FALSE},
112     {WINED3DFMT_R16G16_SNORM,       0x0,        0x0,        0x0,        0x0,        4,      0,      0,      FALSE},
113     {WINED3DFMT_W11V11U10,          0x0,        0x0,        0x0,        0x0,        4,      0,      0,      FALSE},
114     {WINED3DFMT_A2W10V10U10,        0xb0000000, 0x0,        0x0,        0x0,        4,      0,      0,      FALSE},
115     /* Depth stencil formats */
116     {WINED3DFMT_D16_LOCKABLE,       0x0,        0x0,        0x0,        0x0,        2,      16,     0,      FALSE},
117     {WINED3DFMT_D32,                0x0,        0x0,        0x0,        0x0,        4,      32,     0,      FALSE},
118     {WINED3DFMT_D15S1,              0x0,        0x0,        0x0,        0x0,        2,      15,     1,      FALSE},
119     {WINED3DFMT_D24S8,              0x0,        0x0,        0x0,        0x0,        4,      24,     8,      FALSE},
120     {WINED3DFMT_D24X8,              0x0,        0x0,        0x0,        0x0,        4,      24,     0,      FALSE},
121     {WINED3DFMT_D24X4S4,            0x0,        0x0,        0x0,        0x0,        4,      24,     4,      FALSE},
122     {WINED3DFMT_D16_UNORM,          0x0,        0x0,        0x0,        0x0,        2,      16,     0,      FALSE},
123     {WINED3DFMT_L16,                0x0,        0x0,        0x0,        0x0,        2,      16,     0,      FALSE},
124     {WINED3DFMT_D32F_LOCKABLE,      0x0,        0x0,        0x0,        0x0,        4,      32,     0,      FALSE},
125     {WINED3DFMT_D24FS8,             0x0,        0x0,        0x0,        0x0,        4,      24,     8,      FALSE},
126     /* Is this a vertex buffer? */
127     {WINED3DFMT_VERTEXDATA,         0x0,        0x0,        0x0,        0x0,        0,      0,      0,      FALSE},
128     {WINED3DFMT_R16_UINT,           0x0,        0x0,        0x0,        0x0,        2,      0,      0,      FALSE},
129     {WINED3DFMT_R32_UINT,           0x0,        0x0,        0x0,        0x0,        4,      0,      0,      FALSE},
130     {WINED3DFMT_R16G16B16A16_SNORM, 0x0,        0x0,        0x0,        0x0,        8,      0,      0,      FALSE},
131     /* Vendor-specific formats */
132     {WINED3DFMT_ATI2N,              0x0,        0x0,        0x0,        0x0,        1,      0,      0,      TRUE },
133     {WINED3DFMT_NVHU,               0x0,        0x0,        0x0,        0x0,        2,      0,      0,      TRUE },
134     {WINED3DFMT_NVHS,               0x0,        0x0,        0x0,        0x0,        2,      0,      0,      TRUE },
135 };
136
137 struct wined3d_format_compression_info
138 {
139     WINED3DFORMAT format;
140     UINT block_width;
141     UINT block_height;
142     UINT block_byte_count;
143 };
144
145 static const struct wined3d_format_compression_info format_compression_info[] =
146 {
147     {WINED3DFMT_DXT1,   4,  4,  8},
148     {WINED3DFMT_DXT2,   4,  4,  16},
149     {WINED3DFMT_DXT3,   4,  4,  16},
150     {WINED3DFMT_DXT4,   4,  4,  16},
151     {WINED3DFMT_DXT5,   4,  4,  16},
152     {WINED3DFMT_ATI2N,  4,  4,  16},
153 };
154
155 struct wined3d_format_vertex_info
156 {
157     WINED3DFORMAT format;
158     enum wined3d_ffp_emit_idx emit_idx;
159     GLint component_count;
160     GLenum gl_vtx_type;
161     GLint gl_vtx_format;
162     GLboolean gl_normalized;
163     unsigned int component_size;
164 };
165
166 static const struct wined3d_format_vertex_info format_vertex_info[] =
167 {
168     {WINED3DFMT_R32_FLOAT,          WINED3D_FFP_EMIT_FLOAT1,    1, GL_FLOAT,          1, GL_FALSE, sizeof(float)},
169     {WINED3DFMT_R32G32_FLOAT,       WINED3D_FFP_EMIT_FLOAT2,    2, GL_FLOAT,          2, GL_FALSE, sizeof(float)},
170     {WINED3DFMT_R32G32B32_FLOAT,    WINED3D_FFP_EMIT_FLOAT3,    3, GL_FLOAT,          3, GL_FALSE, sizeof(float)},
171     {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4,    4, GL_FLOAT,          4, GL_FALSE, sizeof(float)},
172     {WINED3DFMT_A8R8G8B8,           WINED3D_FFP_EMIT_D3DCOLOR,  4, GL_UNSIGNED_BYTE,  4, GL_TRUE,  sizeof(BYTE)},
173     {WINED3DFMT_R8G8B8A8_UINT,      WINED3D_FFP_EMIT_UBYTE4,    4, GL_UNSIGNED_BYTE,  4, GL_FALSE, sizeof(BYTE)},
174     {WINED3DFMT_R16G16_SINT,        WINED3D_FFP_EMIT_SHORT2,    2, GL_SHORT,          2, GL_FALSE, sizeof(short int)},
175     {WINED3DFMT_R16G16B16A16_SINT,  WINED3D_FFP_EMIT_SHORT4,    4, GL_SHORT,          4, GL_FALSE, sizeof(short int)},
176     {WINED3DFMT_R8G8B8A8_UNORM,     WINED3D_FFP_EMIT_UBYTE4N,   4, GL_UNSIGNED_BYTE,  4, GL_TRUE,  sizeof(BYTE)},
177     {WINED3DFMT_R16G16_SNORM,       WINED3D_FFP_EMIT_SHORT2N,   2, GL_SHORT,          2, GL_TRUE,  sizeof(short int)},
178     {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N,   4, GL_SHORT,          4, GL_TRUE,  sizeof(short int)},
179     {WINED3DFMT_R16G16_UNORM,       WINED3D_FFP_EMIT_USHORT2N,  2, GL_UNSIGNED_SHORT, 2, GL_TRUE,  sizeof(short int)},
180     {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N,  4, GL_UNSIGNED_SHORT, 4, GL_TRUE,  sizeof(short int)},
181     {WINED3DFMT_R10G10B10A2_UINT,   WINED3D_FFP_EMIT_UDEC3,     3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
182     {WINED3DFMT_R10G10B10A2_SNORM,  WINED3D_FFP_EMIT_DEC3N,     3, GL_SHORT,          3, GL_TRUE,  sizeof(short int)},
183     {WINED3DFMT_R16G16_FLOAT,       WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT,          2, GL_FALSE, sizeof(GLhalfNV)},
184     {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT,          4, GL_FALSE, sizeof(GLhalfNV)}
185 };
186
187 typedef struct {
188     WINED3DFORMAT           fmt;
189     GLint                   glInternal, glGammaInternal, rtInternal, glFormat, glType;
190     unsigned int            Flags;
191     GL_SupportedExt extension;
192 } GlPixelFormatDescTemplate;
193
194 /*****************************************************************************
195  * OpenGL format template. Contains unexciting formats which do not need
196  * extension checks. The order in this table is independent of the order in
197  * the table StaticPixelFormatDesc above. Not all formats have to be in this
198  * table.
199  */
200 static const GlPixelFormatDescTemplate gl_formats_template[] = {
201     /* WINED3DFORMAT                internal                          srgbInternal                            rtInternal
202             format                  type
203             flags
204             extension */
205     /* FourCC formats */
206     /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
207      * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
208      * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
209      * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
210      * endian machine
211      */
212     {WINED3DFMT_UYVY,               GL_LUMINANCE_ALPHA,               GL_LUMINANCE_ALPHA,                     0,
213             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
214             WINED3DFMT_FLAG_FILTERING,
215             WINED3D_GL_EXT_NONE},
216     {WINED3DFMT_UYVY,               GL_RGB,                           GL_RGB,                                 0,
217             GL_YCBCR_422_APPLE,     UNSIGNED_SHORT_8_8_APPLE,
218             WINED3DFMT_FLAG_FILTERING,
219             APPLE_YCBCR_422},
220     {WINED3DFMT_YUY2,               GL_LUMINANCE_ALPHA,               GL_LUMINANCE_ALPHA,                     0,
221             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
222             WINED3DFMT_FLAG_FILTERING,
223             WINED3D_GL_EXT_NONE},
224     {WINED3DFMT_YUY2,               GL_RGB,                           GL_RGB,                                 0,
225             GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE,
226             WINED3DFMT_FLAG_FILTERING,
227             APPLE_YCBCR_422},
228     {WINED3DFMT_YV12,               GL_ALPHA,                         GL_ALPHA,                               0,
229             GL_ALPHA,               GL_UNSIGNED_BYTE,
230             WINED3DFMT_FLAG_FILTERING,
231             WINED3D_GL_EXT_NONE},
232     {WINED3DFMT_DXT1,               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
233             GL_RGBA,                GL_UNSIGNED_BYTE,
234             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
235             EXT_TEXTURE_COMPRESSION_S3TC},
236     {WINED3DFMT_DXT2,               GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
237             GL_RGBA,                GL_UNSIGNED_BYTE,
238             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
239             EXT_TEXTURE_COMPRESSION_S3TC},
240     {WINED3DFMT_DXT3,               GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
241             GL_RGBA,                GL_UNSIGNED_BYTE,
242             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
243             EXT_TEXTURE_COMPRESSION_S3TC},
244     {WINED3DFMT_DXT4,               GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
245             GL_RGBA,                GL_UNSIGNED_BYTE,
246             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
247             EXT_TEXTURE_COMPRESSION_S3TC},
248     {WINED3DFMT_DXT5,               GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
249             GL_RGBA,                GL_UNSIGNED_BYTE,
250             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
251             EXT_TEXTURE_COMPRESSION_S3TC},
252     /* IEEE formats */
253     {WINED3DFMT_R32_FLOAT,          GL_RGB32F_ARB,                    GL_RGB32F_ARB,                          0,
254             GL_RED,                 GL_FLOAT,
255             WINED3DFMT_FLAG_RENDERTARGET,
256             ARB_TEXTURE_FLOAT},
257     {WINED3DFMT_R32_FLOAT,          GL_R32F,                          GL_R32F,                                0,
258             GL_RED,                 GL_FLOAT,
259             WINED3DFMT_FLAG_RENDERTARGET,
260             ARB_TEXTURE_RG},
261     {WINED3DFMT_R32G32_FLOAT,       GL_RGB32F_ARB,                    GL_RGB32F_ARB,                          0,
262             GL_RGB,                 GL_FLOAT,
263             WINED3DFMT_FLAG_RENDERTARGET,
264             ARB_TEXTURE_FLOAT},
265     {WINED3DFMT_R32G32_FLOAT,       GL_RG32F,                         GL_RG32F,                               0,
266             GL_RG,                  GL_FLOAT,
267             WINED3DFMT_FLAG_RENDERTARGET,
268             ARB_TEXTURE_RG},
269     {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB,                   GL_RGBA32F_ARB,                         0,
270             GL_RGBA,                GL_FLOAT,
271             WINED3DFMT_FLAG_RENDERTARGET,
272             ARB_TEXTURE_FLOAT},
273     /* Float */
274     {WINED3DFMT_R16_FLOAT,          GL_RGB16F_ARB,                    GL_RGB16F_ARB,                          0,
275             GL_RED,                 GL_HALF_FLOAT_ARB,
276             WINED3DFMT_FLAG_RENDERTARGET,
277             ARB_TEXTURE_FLOAT},
278     {WINED3DFMT_R16_FLOAT,          GL_R16F,                          GL_R16F,                                0,
279             GL_RED,                 GL_HALF_FLOAT_ARB,
280             WINED3DFMT_FLAG_RENDERTARGET,
281             ARB_TEXTURE_RG},
282     {WINED3DFMT_R16G16_FLOAT,       GL_RGB16F_ARB,                    GL_RGB16F_ARB,                          0,
283             GL_RGB,                 GL_HALF_FLOAT_ARB,
284             WINED3DFMT_FLAG_RENDERTARGET,
285             ARB_TEXTURE_FLOAT},
286     {WINED3DFMT_R16G16_FLOAT,       GL_RG16F,                         GL_RG16F,                               0,
287             GL_RG,                  GL_HALF_FLOAT_ARB,
288             WINED3DFMT_FLAG_RENDERTARGET,
289             ARB_TEXTURE_RG},
290     {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB,                   GL_RGBA16F_ARB,                         0,
291             GL_RGBA,                GL_HALF_FLOAT_ARB,
292             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
293             ARB_TEXTURE_FLOAT},
294     /* Palettized formats */
295     {WINED3DFMT_P8,                 GL_RGBA,                          GL_RGBA,                                0,
296             GL_RGBA,                GL_UNSIGNED_BYTE,
297             0,
298             ARB_FRAGMENT_PROGRAM},
299     {WINED3DFMT_P8,                 GL_COLOR_INDEX8_EXT,              GL_COLOR_INDEX8_EXT,                    0,
300             GL_COLOR_INDEX,         GL_UNSIGNED_BYTE,
301             0,
302             EXT_PALETTED_TEXTURE},
303     /* Standard ARGB formats */
304     {WINED3DFMT_R8G8B8,             GL_RGB8,                          GL_RGB8,                                0,
305             GL_BGR,                 GL_UNSIGNED_BYTE,
306             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
307             WINED3D_GL_EXT_NONE},
308     {WINED3DFMT_A8R8G8B8,           GL_RGBA8,                         GL_SRGB8_ALPHA8_EXT,                    0,
309             GL_BGRA,                GL_UNSIGNED_INT_8_8_8_8_REV,
310             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
311             WINED3D_GL_EXT_NONE},
312     {WINED3DFMT_X8R8G8B8,           GL_RGB8,                          GL_SRGB8_EXT,                           0,
313             GL_BGRA,                GL_UNSIGNED_INT_8_8_8_8_REV,
314             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
315             WINED3D_GL_EXT_NONE},
316     {WINED3DFMT_R5G6B5,             GL_RGB5,                          GL_RGB5,                                GL_RGB8,
317             GL_RGB,                 GL_UNSIGNED_SHORT_5_6_5,
318             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
319             WINED3D_GL_EXT_NONE},
320     {WINED3DFMT_X1R5G5B5,           GL_RGB5,                          GL_RGB5_A1,                             0,
321             GL_BGRA,                GL_UNSIGNED_SHORT_1_5_5_5_REV,
322             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
323             WINED3D_GL_EXT_NONE},
324     {WINED3DFMT_A1R5G5B5,           GL_RGB5_A1,                       GL_RGB5_A1,                             0,
325             GL_BGRA,                GL_UNSIGNED_SHORT_1_5_5_5_REV,
326             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
327             WINED3D_GL_EXT_NONE},
328     {WINED3DFMT_A4R4G4B4,           GL_RGBA4,                         GL_SRGB8_ALPHA8_EXT,                    0,
329             GL_BGRA,                GL_UNSIGNED_SHORT_4_4_4_4_REV,
330             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
331             WINED3D_GL_EXT_NONE},
332     {WINED3DFMT_R3G3B2,             GL_R3_G3_B2,                      GL_R3_G3_B2,                            0,
333             GL_RGB,                 GL_UNSIGNED_BYTE_3_3_2,
334             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
335             WINED3D_GL_EXT_NONE},
336     {WINED3DFMT_A8_UNORM,           GL_ALPHA8,                        GL_ALPHA8,                              0,
337             GL_ALPHA,               GL_UNSIGNED_BYTE,
338             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
339             WINED3D_GL_EXT_NONE},
340     {WINED3DFMT_X4R4G4B4,           GL_RGB4,                          GL_RGB4,                                0,
341             GL_BGRA,                GL_UNSIGNED_SHORT_4_4_4_4_REV,
342             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
343             WINED3D_GL_EXT_NONE},
344     {WINED3DFMT_R10G10B10A2_UNORM,  GL_RGB10_A2,                      GL_RGB10_A2,                            0,
345             GL_RGBA,                GL_UNSIGNED_INT_2_10_10_10_REV,
346             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
347             WINED3D_GL_EXT_NONE},
348     {WINED3DFMT_R8G8B8A8_UNORM,     GL_RGBA8,                         GL_RGBA8,                               0,
349             GL_RGBA,                GL_UNSIGNED_INT_8_8_8_8_REV,
350             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
351             WINED3D_GL_EXT_NONE},
352     {WINED3DFMT_X8B8G8R8,           GL_RGB8,                          GL_RGB8,                                0,
353             GL_RGBA,                GL_UNSIGNED_INT_8_8_8_8_REV,
354             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
355             WINED3D_GL_EXT_NONE},
356     {WINED3DFMT_R16G16_UNORM,       GL_RGB16_EXT,                     GL_RGB16_EXT,                           GL_RGBA16_EXT,
357             GL_RGB,                 GL_UNSIGNED_SHORT,
358             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
359             WINED3D_GL_EXT_NONE},
360     {WINED3DFMT_A2R10G10B10,        GL_RGB10_A2,                      GL_RGB10_A2,                            0,
361             GL_BGRA,                GL_UNSIGNED_INT_2_10_10_10_REV,
362             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
363             WINED3D_GL_EXT_NONE},
364     {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16_EXT,                    GL_RGBA16_EXT,                          0,
365             GL_RGBA,                GL_UNSIGNED_SHORT,
366             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
367             WINED3D_GL_EXT_NONE},
368     /* Luminance */
369     {WINED3DFMT_L8,                 GL_LUMINANCE8,                    GL_SLUMINANCE8_EXT,                     0,
370             GL_LUMINANCE,           GL_UNSIGNED_BYTE,
371             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
372             WINED3D_GL_EXT_NONE},
373     {WINED3DFMT_A8L8,               GL_LUMINANCE8_ALPHA8,             GL_SLUMINANCE8_ALPHA8_EXT,              0,
374             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
375             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
376             WINED3D_GL_EXT_NONE},
377     {WINED3DFMT_A4L4,               GL_LUMINANCE4_ALPHA4,             GL_LUMINANCE4_ALPHA4,                   0,
378             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
379             0,
380             WINED3D_GL_EXT_NONE},
381     /* Bump mapping stuff */
382     {WINED3DFMT_R8G8_SNORM,         GL_RGB8,                          GL_RGB8,                                0,
383             GL_BGR,                 GL_UNSIGNED_BYTE,
384             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
385             WINED3D_GL_EXT_NONE},
386     {WINED3DFMT_R8G8_SNORM,         GL_DSDT8_NV,                      GL_DSDT8_NV,                            0,
387             GL_DSDT_NV,             GL_BYTE,
388             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
389             NV_TEXTURE_SHADER},
390     {WINED3DFMT_L6V5U5,             GL_RGB5,                          GL_RGB5,                                0,
391             GL_RGB,                 GL_UNSIGNED_SHORT_5_6_5,
392             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
393             WINED3D_GL_EXT_NONE},
394     {WINED3DFMT_L6V5U5,             GL_DSDT8_MAG8_NV,                 GL_DSDT8_MAG8_NV,                       0,
395             GL_DSDT_MAG_NV,         GL_BYTE,
396             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
397             NV_TEXTURE_SHADER},
398     {WINED3DFMT_X8L8V8U8,           GL_RGB8,                          GL_RGB8,                                0,
399             GL_BGRA,                GL_UNSIGNED_INT_8_8_8_8_REV,
400             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
401             WINED3D_GL_EXT_NONE},
402     {WINED3DFMT_X8L8V8U8,           GL_DSDT8_MAG8_INTENSITY8_NV,      GL_DSDT8_MAG8_INTENSITY8_NV,            0,
403             GL_DSDT_MAG_VIB_NV,     GL_UNSIGNED_INT_8_8_S8_S8_REV_NV,
404             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
405             NV_TEXTURE_SHADER},
406     {WINED3DFMT_R8G8B8A8_SNORM,     GL_RGBA8,                         GL_RGBA8,                               0,
407             GL_BGRA,                GL_UNSIGNED_BYTE,
408             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
409             WINED3D_GL_EXT_NONE},
410     {WINED3DFMT_R8G8B8A8_SNORM,     GL_SIGNED_RGBA8_NV,               GL_SIGNED_RGBA8_NV,                     0,
411             GL_RGBA,                GL_BYTE,
412             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
413             NV_TEXTURE_SHADER},
414     {WINED3DFMT_R16G16_SNORM,       GL_RGB16_EXT,                     GL_RGB16_EXT,                           0,
415             GL_BGR,                 GL_UNSIGNED_SHORT,
416             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
417             WINED3D_GL_EXT_NONE},
418     {WINED3DFMT_R16G16_SNORM,       GL_SIGNED_HILO16_NV,              GL_SIGNED_HILO16_NV,                    0,
419             GL_HILO_NV,             GL_SHORT,
420             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
421             NV_TEXTURE_SHADER},
422     /* Depth stencil formats */
423     {WINED3DFMT_D16_LOCKABLE,       GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
424             GL_DEPTH_COMPONENT,     GL_UNSIGNED_SHORT,
425             WINED3DFMT_FLAG_DEPTH,
426             ARB_DEPTH_TEXTURE},
427     {WINED3DFMT_D32,                GL_DEPTH_COMPONENT32_ARB,         GL_DEPTH_COMPONENT32_ARB,               0,
428             GL_DEPTH_COMPONENT,     GL_UNSIGNED_INT,
429             WINED3DFMT_FLAG_DEPTH,
430             ARB_DEPTH_TEXTURE},
431     {WINED3DFMT_D15S1,              GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
432             GL_DEPTH_COMPONENT,     GL_UNSIGNED_SHORT,
433             WINED3DFMT_FLAG_DEPTH,
434             ARB_DEPTH_TEXTURE},
435     {WINED3DFMT_D15S1,              GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
436             GL_DEPTH_STENCIL_EXT,   GL_UNSIGNED_INT_24_8_EXT,
437             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
438             EXT_PACKED_DEPTH_STENCIL},
439     {WINED3DFMT_D24S8,              GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
440             GL_DEPTH_COMPONENT,     GL_UNSIGNED_INT,
441             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
442             ARB_DEPTH_TEXTURE},
443     {WINED3DFMT_D24S8,              GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
444             GL_DEPTH_STENCIL_EXT,   GL_UNSIGNED_INT_24_8_EXT,
445             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
446             EXT_PACKED_DEPTH_STENCIL},
447     {WINED3DFMT_D24X8,              GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
448             GL_DEPTH_COMPONENT,     GL_UNSIGNED_INT,
449             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
450             ARB_DEPTH_TEXTURE},
451     {WINED3DFMT_D24X4S4,            GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
452             GL_DEPTH_COMPONENT,     GL_UNSIGNED_INT,
453             WINED3DFMT_FLAG_DEPTH,
454             ARB_DEPTH_TEXTURE},
455     {WINED3DFMT_D24X4S4,            GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
456             GL_DEPTH_STENCIL_EXT,   GL_UNSIGNED_INT_24_8_EXT,
457             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
458             EXT_PACKED_DEPTH_STENCIL},
459     {WINED3DFMT_D16_UNORM,          GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
460             GL_DEPTH_COMPONENT,     GL_UNSIGNED_SHORT,
461             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
462             ARB_DEPTH_TEXTURE},
463     {WINED3DFMT_L16,                GL_LUMINANCE16_EXT,               GL_LUMINANCE16_EXT,                     0,
464             GL_LUMINANCE,           GL_UNSIGNED_SHORT,
465             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
466             WINED3D_GL_EXT_NONE},
467     {WINED3DFMT_D32F_LOCKABLE,      GL_DEPTH_COMPONENT32F,            GL_DEPTH_COMPONENT32F,                  0,
468             GL_DEPTH_COMPONENT,     GL_FLOAT,
469             WINED3DFMT_FLAG_DEPTH,
470             ARB_DEPTH_BUFFER_FLOAT},
471     {WINED3DFMT_D24FS8,             GL_DEPTH32F_STENCIL8,             GL_DEPTH32F_STENCIL8,                   0,
472             GL_DEPTH_STENCIL_EXT,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
473             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
474             ARB_DEPTH_BUFFER_FLOAT},
475     /* Vendor-specific formats */
476     {WINED3DFMT_ATI2N,              GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
477             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
478             0,
479             ATI_TEXTURE_COMPRESSION_3DC},
480     {WINED3DFMT_ATI2N,              GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT,     0,
481             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
482             0,
483             EXT_TEXTURE_COMPRESSION_RGTC},
484 };
485
486 static inline int getFmtIdx(WINED3DFORMAT fmt) {
487     /* First check if the format is at the position of its value.
488      * This will catch the argb formats before the loop is entered
489      */
490     if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
491         return fmt;
492     } else {
493         unsigned int i;
494         for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
495             if(formats[i].format == fmt) {
496                 return i;
497             }
498         }
499     }
500     return -1;
501 }
502
503 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
504 {
505     UINT format_count = sizeof(formats) / sizeof(*formats);
506     UINT i;
507
508     gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->gl_formats));
509     if (!gl_info->gl_formats)
510     {
511         ERR("Failed to allocate memory.\n");
512         return FALSE;
513     }
514
515     for (i = 0; i < format_count; ++i)
516     {
517         struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
518         desc->format = formats[i].format;
519         desc->red_mask = formats[i].redMask;
520         desc->green_mask = formats[i].greenMask;
521         desc->blue_mask = formats[i].blueMask;
522         desc->alpha_mask = formats[i].alphaMask;
523         desc->byte_count = formats[i].bpp;
524         desc->depth_size = formats[i].depthSize;
525         desc->stencil_size = formats[i].stencilSize;
526         if (formats[i].isFourcc) desc->Flags |= WINED3DFMT_FLAG_FOURCC;
527     }
528
529     return TRUE;
530 }
531
532 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
533 {
534     unsigned int i;
535
536     for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
537     {
538         struct GlPixelFormatDesc *format_desc;
539         int fmt_idx = getFmtIdx(format_compression_info[i].format);
540
541         if (fmt_idx == -1)
542         {
543             ERR("Format %s (%#x) not found.\n",
544                     debug_d3dformat(format_compression_info[i].format), format_compression_info[i].format);
545             return FALSE;
546         }
547
548         format_desc = &gl_info->gl_formats[fmt_idx];
549         format_desc->block_width = format_compression_info[i].block_width;
550         format_desc->block_height = format_compression_info[i].block_height;
551         format_desc->block_byte_count = format_compression_info[i].block_byte_count;
552         format_desc->Flags |= WINED3DFMT_FLAG_COMPRESSED;
553     }
554
555     return TRUE;
556 }
557
558 #define GLINFO_LOCATION (*gl_info)
559
560 /* Context activation is done by the caller. */
561 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPixelFormatDesc *format_desc)
562 {
563     /* Check if the default internal format is supported as a frame buffer
564      * target, otherwise fall back to the render target internal.
565      *
566      * Try to stick to the standard format if possible, this limits precision differences. */
567     GLenum status;
568     GLuint tex;
569
570     ENTER_GL();
571
572     while(glGetError());
573     glDisable(GL_BLEND);
574
575     glGenTextures(1, &tex);
576     glBindTexture(GL_TEXTURE_2D, tex);
577
578     glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glInternal, 16, 16, 0,
579             format_desc->glFormat, format_desc->glType, NULL);
580     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
581     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
582
583     GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
584
585     status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
586     checkGLcall("Framebuffer format check");
587
588     if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
589     {
590         TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(format_desc->format));
591         format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
592         format_desc->rtInternal = format_desc->glInternal;
593     }
594     else
595     {
596         if (!format_desc->rtInternal)
597         {
598             if (format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)
599             {
600                 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
601                         " and no fallback specified.\n", debug_d3dformat(format_desc->format));
602                 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
603             }
604             else
605             {
606                 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format_desc->format));
607             }
608             format_desc->rtInternal = format_desc->glInternal;
609         }
610         else
611         {
612             TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
613                     debug_d3dformat(format_desc->format));
614
615             while(glGetError());
616
617             GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0));
618
619             glTexImage2D(GL_TEXTURE_2D, 0, format_desc->rtInternal, 16, 16, 0,
620                     format_desc->glFormat, format_desc->glType, NULL);
621             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
622             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
623
624             GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
625
626             status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
627             checkGLcall("Framebuffer format check");
628
629             if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
630             {
631                 TRACE("Format %s rtInternal format is supported as FBO color attachment\n",
632                         debug_d3dformat(format_desc->format));
633             }
634             else
635             {
636                 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
637                         debug_d3dformat(format_desc->format));
638                 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
639             }
640         }
641     }
642
643     if (status == GL_FRAMEBUFFER_COMPLETE_EXT && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
644     {
645         GLuint rb;
646
647         if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
648         {
649             GL_EXTCALL(glGenRenderbuffersEXT(1, &rb));
650             GL_EXTCALL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb));
651             GL_EXTCALL(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, 16, 16));
652             GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
653                     GL_RENDERBUFFER_EXT, rb));
654             GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
655                     GL_RENDERBUFFER_EXT, rb));
656             checkGLcall("RB attachment");
657         }
658
659         glEnable(GL_BLEND);
660         glClear(GL_COLOR_BUFFER_BIT);
661         if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION_EXT)
662         {
663             while(glGetError());
664             TRACE("Format doesn't support post-pixelshader blending.\n");
665             format_desc->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
666         }
667
668         if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
669         {
670             GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
671                     GL_RENDERBUFFER_EXT, 0));
672             GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
673                     GL_RENDERBUFFER_EXT, 0));
674             GL_EXTCALL(glDeleteRenderbuffersEXT(1, &rb));
675             checkGLcall("RB cleanup");
676         }
677     }
678
679     glDeleteTextures(1, &tex);
680
681     LEAVE_GL();
682 }
683
684 /* Context activation is done by the caller. */
685 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
686 {
687     unsigned int i;
688     GLuint fbo;
689
690     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
691     {
692         ENTER_GL();
693
694         GL_EXTCALL(glGenFramebuffersEXT(1, &fbo));
695         GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
696
697         LEAVE_GL();
698     }
699
700     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
701     {
702         struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
703
704         if (!desc->glInternal) continue;
705
706         if (desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
707         {
708             TRACE("Skipping format %s because it's a depth/stencil format.\n",
709                     debug_d3dformat(desc->format));
710             continue;
711         }
712
713         if (desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
714         {
715             TRACE("Skipping format %s because it's a compressed format.\n",
716                     debug_d3dformat(desc->format));
717             continue;
718         }
719
720         if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
721         {
722             TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc->format));
723             check_fbo_compat(gl_info, desc);
724         }
725         else
726         {
727             desc->rtInternal = desc->glInternal;
728         }
729     }
730
731     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
732     {
733         ENTER_GL();
734
735         GL_EXTCALL(glDeleteFramebuffersEXT(1, &fbo));
736
737         LEAVE_GL();
738     }
739 }
740
741 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
742 {
743     unsigned int i;
744
745     for (i = 0; i < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); ++i)
746     {
747         int fmt_idx = getFmtIdx(gl_formats_template[i].fmt);
748         struct GlPixelFormatDesc *desc;
749
750         if (fmt_idx == -1)
751         {
752             ERR("Format %s (%#x) not found.\n",
753                     debug_d3dformat(gl_formats_template[i].fmt), gl_formats_template[i].fmt);
754             return FALSE;
755         }
756
757         if (!GL_SUPPORT(gl_formats_template[i].extension)) continue;
758
759         desc = &gl_info->gl_formats[fmt_idx];
760         desc->glInternal = gl_formats_template[i].glInternal;
761         desc->glGammaInternal = gl_formats_template[i].glGammaInternal;
762         desc->rtInternal = gl_formats_template[i].rtInternal;
763         desc->glFormat = gl_formats_template[i].glFormat;
764         desc->glType = gl_formats_template[i].glType;
765         desc->color_fixup = COLOR_FIXUP_IDENTITY;
766         desc->Flags |= gl_formats_template[i].Flags;
767         desc->heightscale = 1.0f;
768     }
769
770     return TRUE;
771 }
772
773 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
774 {
775     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
776     c1 >>= 8; c2 >>= 8;
777     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
778     c1 >>= 8; c2 >>= 8;
779     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
780     c1 >>= 8; c2 >>= 8;
781     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
782     return TRUE;
783 }
784
785 /* A context is provided by the caller */
786 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
787 {
788     GLuint tex, fbo, buffer;
789     const DWORD data[] = {0x00000000, 0xffffffff};
790     DWORD readback[16 * 1];
791     BOOL ret = FALSE;
792
793     /* Render a filtered texture and see what happens. This is intended to detect the lack of
794      * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
795      * falling back to software. If this changes in the future this code will get fooled and
796      * apps might hit the software path due to incorrectly advertised caps.
797      *
798      * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
799      * disable fallback, if Apple or ATI ever change the driver behavior they will break more
800      * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
801      */
802
803     ENTER_GL();
804     while(glGetError());
805
806     glGenTextures(1, &buffer);
807     glBindTexture(GL_TEXTURE_2D, buffer);
808     memset(readback, 0x7e, sizeof(readback));
809     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
810     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
811     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
812     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
813     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
814     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
815
816     glGenTextures(1, &tex);
817     glBindTexture(GL_TEXTURE_2D, tex);
818     glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
819     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
820     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
821     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
822     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
823     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
824     glEnable(GL_TEXTURE_2D);
825
826     GL_EXTCALL(glGenFramebuffersEXT(1, &fbo));
827     GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
828     GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, buffer, 0));
829     glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
830
831     glViewport(0, 0, 16, 1);
832     glDisable(GL_LIGHTING);
833     glMatrixMode(GL_MODELVIEW);
834     glLoadIdentity();
835     glMatrixMode(GL_PROJECTION);
836     glLoadIdentity();
837
838     glClearColor(0, 1, 0, 0);
839     glClear(GL_COLOR_BUFFER_BIT);
840
841     glBegin(GL_TRIANGLE_STRIP);
842     glTexCoord2f(0.0, 0.0);
843     glVertex2f(-1.0f, -1.0f);
844     glTexCoord2f(1.0, 0.0);
845     glVertex2f(1.0f, -1.0f);
846     glTexCoord2f(0.0, 1.0);
847     glVertex2f(-1.0f, 1.0f);
848     glTexCoord2f(1.0, 1.0);
849     glVertex2f(1.0f, 1.0f);
850     glEnd();
851
852     glBindTexture(GL_TEXTURE_2D, buffer);
853     memset(readback, 0x7f, sizeof(readback));
854     glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
855     if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
856        color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
857     {
858         TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
859               readback[6], readback[9]);
860         ret = FALSE;
861     }
862     else
863     {
864         TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
865               readback[6], readback[9]);
866         ret = TRUE;
867     }
868
869     GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
870     GL_EXTCALL(glDeleteFramebuffersEXT(1, &fbo));
871     glDeleteTextures(1, &tex);
872     glDeleteTextures(1, &buffer);
873
874     if(glGetError())
875     {
876         FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
877         ret = FALSE;
878     }
879     LEAVE_GL();
880     return ret;
881 }
882
883 static void init_format_filter_info(struct wined3d_gl_info *gl_info)
884 {
885     unsigned int fmt_idx, i;
886     WINED3DFORMAT fmts16[] = {
887         WINED3DFMT_R16_FLOAT,
888         WINED3DFMT_R16G16_FLOAT,
889         WINED3DFMT_R16G16B16A16_FLOAT,
890     };
891     BOOL filtered;
892     struct GlPixelFormatDesc *desc;
893
894     if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
895     {
896         WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
897         if(gl_info->gl_vendor == VENDOR_NVIDIA && GL_SUPPORT(ARB_TEXTURE_FLOAT))
898         {
899             TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
900             filtered = TRUE;
901         }
902         else if(GL_LIMITS(glsl_varyings > 44))
903         {
904             TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
905             filtered = TRUE;
906         }
907         else
908         {
909             TRACE("Assuming no float16 blending\n");
910             filtered = FALSE;
911         }
912
913         if(filtered)
914         {
915             for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
916             {
917                 fmt_idx = getFmtIdx(fmts16[i]);
918                 gl_info->gl_formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
919             }
920         }
921         return;
922     }
923
924     for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
925     {
926         fmt_idx = getFmtIdx(fmts16[i]);
927         desc = &gl_info->gl_formats[fmt_idx];
928         if(!desc->glInternal) continue; /* Not supported by GL */
929
930         filtered = check_filter(gl_info, gl_info->gl_formats[fmt_idx].glInternal);
931         if(filtered)
932         {
933             TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
934             desc->Flags |= WINED3DFMT_FLAG_FILTERING;
935         }
936         else
937         {
938             TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
939         }
940     }
941 }
942
943 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
944 {
945     int idx;
946
947     idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
948     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
949             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
950
951     idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
952     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
953             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
954
955     idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
956     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
957             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
958
959     idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
960     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
961             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
962
963     idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
964     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
965             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
966
967     /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
968      * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
969      * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
970      * the only driver that implements it(fglrx) has a buggy implementation.
971      *
972      * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
973      * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
974      * conversion for this format.
975      */
976     if (!GL_SUPPORT(NV_TEXTURE_SHADER))
977     {
978         idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
979         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
980                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
981         idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
982         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
983                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
984     }
985     else
986     {
987         idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
988         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
989                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
990         idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
991         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
992                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
993     }
994
995     if (!GL_SUPPORT(NV_TEXTURE_SHADER))
996     {
997         /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
998          * with each other
999          */
1000         idx = getFmtIdx(WINED3DFMT_L6V5U5);
1001         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1002                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1003         idx = getFmtIdx(WINED3DFMT_X8L8V8U8);
1004         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1005                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1006         idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1007         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1008                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1009     }
1010     else
1011     {
1012         /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1013          * are converted at surface loading time, but they do not need any modification in
1014          * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1015          * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1016          */
1017     }
1018
1019     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC))
1020     {
1021         idx = getFmtIdx(WINED3DFMT_ATI2N);
1022         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1023                 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1024     }
1025     else if (GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC))
1026     {
1027         idx = getFmtIdx(WINED3DFMT_ATI2N);
1028         gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
1029                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1030     }
1031
1032     if (!GL_SUPPORT(APPLE_YCBCR_422))
1033     {
1034         idx = getFmtIdx(WINED3DFMT_YUY2);
1035         gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
1036
1037         idx = getFmtIdx(WINED3DFMT_UYVY);
1038         gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
1039     }
1040
1041     idx = getFmtIdx(WINED3DFMT_YV12);
1042     gl_info->gl_formats[idx].heightscale = 1.5f;
1043     gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
1044
1045     if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
1046     {
1047         idx = getFmtIdx(WINED3DFMT_A8R8G8B8);
1048         gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
1049     }
1050
1051     if (GL_SUPPORT(ARB_HALF_FLOAT_VERTEX))
1052     {
1053         /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1054          * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1055         idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1056         gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1057
1058         idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1059         gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1060     }
1061 }
1062
1063 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1064 {
1065     unsigned int i;
1066
1067     for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1068     {
1069         struct GlPixelFormatDesc *format_desc;
1070         int fmt_idx = getFmtIdx(format_vertex_info[i].format);
1071
1072         if (fmt_idx == -1)
1073         {
1074             ERR("Format %s (%#x) not found.\n",
1075                     debug_d3dformat(format_vertex_info[i].format), format_vertex_info[i].format);
1076             return FALSE;
1077         }
1078
1079         format_desc = &gl_info->gl_formats[fmt_idx];
1080         format_desc->emit_idx = format_vertex_info[i].emit_idx;
1081         format_desc->component_count = format_vertex_info[i].component_count;
1082         format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1083         format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1084         format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
1085         format_desc->component_size = format_vertex_info[i].component_size;
1086     }
1087
1088     return TRUE;
1089 }
1090
1091 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1092 {
1093     if (!init_format_base_info(gl_info)) return FALSE;
1094
1095     if (!init_format_compression_info(gl_info))
1096     {
1097         HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1098         return FALSE;
1099     }
1100
1101     return TRUE;
1102 }
1103
1104 /* Context activation is done by the caller. */
1105 BOOL initPixelFormats(struct wined3d_gl_info *gl_info)
1106 {
1107     if (!init_format_base_info(gl_info)) return FALSE;
1108
1109     if (!init_format_compression_info(gl_info)) goto fail;
1110     if (!init_format_texture_info(gl_info)) goto fail;
1111     if (!init_format_vertex_info(gl_info)) goto fail;
1112
1113     apply_format_fixups(gl_info);
1114     init_format_fbo_compat_info(gl_info);
1115     init_format_filter_info(gl_info);
1116
1117     return TRUE;
1118
1119 fail:
1120     HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1121     return FALSE;
1122 }
1123
1124 #undef GLINFO_LOCATION
1125
1126 #define GLINFO_LOCATION This->adapter->gl_info
1127
1128 const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info)
1129 {
1130     int idx = getFmtIdx(fmt);
1131
1132     if(idx == -1) {
1133         FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
1134         /* Get the caller a valid pointer */
1135         idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1136     }
1137
1138     return &gl_info->gl_formats[idx];
1139 }
1140
1141 /*****************************************************************************
1142  * Trace formatting of useful values
1143  */
1144 const char* debug_d3dformat(WINED3DFORMAT fmt) {
1145   switch (fmt) {
1146 #define FMT_TO_STR(fmt) case fmt: return #fmt
1147     FMT_TO_STR(WINED3DFMT_UNKNOWN);
1148     FMT_TO_STR(WINED3DFMT_R8G8B8);
1149     FMT_TO_STR(WINED3DFMT_A8R8G8B8);
1150     FMT_TO_STR(WINED3DFMT_X8R8G8B8);
1151     FMT_TO_STR(WINED3DFMT_R5G6B5);
1152     FMT_TO_STR(WINED3DFMT_X1R5G5B5);
1153     FMT_TO_STR(WINED3DFMT_A1R5G5B5);
1154     FMT_TO_STR(WINED3DFMT_A4R4G4B4);
1155     FMT_TO_STR(WINED3DFMT_R3G3B2);
1156     FMT_TO_STR(WINED3DFMT_A8R3G3B2);
1157     FMT_TO_STR(WINED3DFMT_X4R4G4B4);
1158     FMT_TO_STR(WINED3DFMT_X8B8G8R8);
1159     FMT_TO_STR(WINED3DFMT_A2R10G10B10);
1160     FMT_TO_STR(WINED3DFMT_A8P8);
1161     FMT_TO_STR(WINED3DFMT_P8);
1162     FMT_TO_STR(WINED3DFMT_L8);
1163     FMT_TO_STR(WINED3DFMT_A8L8);
1164     FMT_TO_STR(WINED3DFMT_A4L4);
1165     FMT_TO_STR(WINED3DFMT_L6V5U5);
1166     FMT_TO_STR(WINED3DFMT_X8L8V8U8);
1167     FMT_TO_STR(WINED3DFMT_W11V11U10);
1168     FMT_TO_STR(WINED3DFMT_A2W10V10U10);
1169     FMT_TO_STR(WINED3DFMT_UYVY);
1170     FMT_TO_STR(WINED3DFMT_YUY2);
1171     FMT_TO_STR(WINED3DFMT_YV12);
1172     FMT_TO_STR(WINED3DFMT_DXT1);
1173     FMT_TO_STR(WINED3DFMT_DXT2);
1174     FMT_TO_STR(WINED3DFMT_DXT3);
1175     FMT_TO_STR(WINED3DFMT_DXT4);
1176     FMT_TO_STR(WINED3DFMT_DXT5);
1177     FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1178     FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1179     FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1180     FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1181     FMT_TO_STR(WINED3DFMT_D32);
1182     FMT_TO_STR(WINED3DFMT_D15S1);
1183     FMT_TO_STR(WINED3DFMT_D24S8);
1184     FMT_TO_STR(WINED3DFMT_D24X8);
1185     FMT_TO_STR(WINED3DFMT_D24X4S4);
1186     FMT_TO_STR(WINED3DFMT_L16);
1187     FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
1188     FMT_TO_STR(WINED3DFMT_D24FS8);
1189     FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1190     FMT_TO_STR(WINED3DFMT_CxV8U8);
1191     FMT_TO_STR(WINED3DFMT_ATI2N);
1192     FMT_TO_STR(WINED3DFMT_NVHU);
1193     FMT_TO_STR(WINED3DFMT_NVHS);
1194     FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1195     FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1196     FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1197     FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1198     FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1199     FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1200     FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1201     FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1202     FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1203     FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1204     FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1205     FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1206     FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1207     FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1208     FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1209     FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1210     FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1211     FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1212     FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1213     FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1214     FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1215     FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1216     FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1217     FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1218     FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1219     FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1220     FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1221     FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1222     FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1223     FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1224     FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1225     FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1226     FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1227     FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1228     FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1229     FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1230     FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1231     FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1232     FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1233     FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1234     FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1235     FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1236     FMT_TO_STR(WINED3DFMT_R32_UINT);
1237     FMT_TO_STR(WINED3DFMT_R32_SINT);
1238     FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1239     FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1240     FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1241     FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1242     FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1243     FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1244     FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1245     FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1246     FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1247     FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1248     FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1249     FMT_TO_STR(WINED3DFMT_D16_UNORM);
1250     FMT_TO_STR(WINED3DFMT_R16_UNORM);
1251     FMT_TO_STR(WINED3DFMT_R16_UINT);
1252     FMT_TO_STR(WINED3DFMT_R16_SNORM);
1253     FMT_TO_STR(WINED3DFMT_R16_SINT);
1254     FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1255     FMT_TO_STR(WINED3DFMT_R8_UNORM);
1256     FMT_TO_STR(WINED3DFMT_R8_UINT);
1257     FMT_TO_STR(WINED3DFMT_R8_SNORM);
1258     FMT_TO_STR(WINED3DFMT_R8_SINT);
1259     FMT_TO_STR(WINED3DFMT_A8_UNORM);
1260     FMT_TO_STR(WINED3DFMT_R1_UNORM);
1261     FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1262     FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1263     FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1264     FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1265     FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1266     FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1267     FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1268     FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1269     FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1270     FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1271     FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1272     FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1273     FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1274     FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1275     FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1276     FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1277     FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1278     FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1279     FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1280     FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1281     FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1282     FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1283 #undef FMT_TO_STR
1284   default:
1285     {
1286       char fourcc[5];
1287       fourcc[0] = (char)(fmt);
1288       fourcc[1] = (char)(fmt >> 8);
1289       fourcc[2] = (char)(fmt >> 16);
1290       fourcc[3] = (char)(fmt >> 24);
1291       fourcc[4] = 0;
1292       if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
1293         FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
1294       else
1295         FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
1296     }
1297     return "unrecognized";
1298   }
1299 }
1300
1301 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
1302   switch (devtype) {
1303 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1304     DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1305     DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1306     DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1307 #undef DEVTYPE_TO_STR
1308   default:
1309     FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1310     return "unrecognized";
1311   }
1312 }
1313
1314 const char *debug_d3dusage(DWORD usage)
1315 {
1316     char buf[284];
1317
1318     buf[0] = '\0';
1319 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1320     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1321     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1322     WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1323     WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1324     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1325     WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1326     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1327     WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1328     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1329     WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1330     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1331 #undef WINED3DUSAGE_TO_STR
1332     if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1333
1334     return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1335 }
1336
1337 const char *debug_d3dusagequery(DWORD usagequery)
1338 {
1339     char buf[238];
1340
1341     buf[0] = '\0';
1342 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1343     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1344     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1345     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1346     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1347     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1348     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1349     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1350 #undef WINED3DUSAGEQUERY_TO_STR
1351     if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1352
1353     return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1354 }
1355
1356 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1357     switch (method) {
1358 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1359         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1360         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1361         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1362         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1363         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1364         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1365         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1366 #undef WINED3DDECLMETHOD_TO_STR
1367         default:
1368             FIXME("Unrecognized %u declaration method!\n", method);
1369             return "unrecognized";
1370     }
1371 }
1372
1373 const char* debug_d3ddeclusage(BYTE usage) {
1374     switch (usage) {
1375 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1376         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1377         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1378         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1379         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1380         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1381         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1382         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1383         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1384         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1385         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1386         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1387         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1388         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1389         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1390 #undef WINED3DDECLUSAGE_TO_STR
1391         default:
1392             FIXME("Unrecognized %u declaration usage!\n", usage);
1393             return "unrecognized";
1394     }
1395 }
1396
1397 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1398   switch (res) {
1399 #define RES_TO_STR(res) case res: return #res
1400     RES_TO_STR(WINED3DRTYPE_SURFACE);
1401     RES_TO_STR(WINED3DRTYPE_VOLUME);
1402     RES_TO_STR(WINED3DRTYPE_TEXTURE);
1403     RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1404     RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1405     RES_TO_STR(WINED3DRTYPE_BUFFER);
1406 #undef  RES_TO_STR
1407   default:
1408     FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1409     return "unrecognized";
1410   }
1411 }
1412
1413 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1414   switch (PrimitiveType) {
1415 #define PRIM_TO_STR(prim) case prim: return #prim
1416     PRIM_TO_STR(WINED3DPT_UNDEFINED);
1417     PRIM_TO_STR(WINED3DPT_POINTLIST);
1418     PRIM_TO_STR(WINED3DPT_LINELIST);
1419     PRIM_TO_STR(WINED3DPT_LINESTRIP);
1420     PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1421     PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1422     PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1423     PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1424     PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1425     PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1426     PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1427 #undef  PRIM_TO_STR
1428   default:
1429     FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1430     return "unrecognized";
1431   }
1432 }
1433
1434 const char* debug_d3drenderstate(DWORD state) {
1435   switch (state) {
1436 #define D3DSTATE_TO_STR(u) case u: return #u
1437     D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE             );
1438     D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS                 );
1439     D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS            );
1440     D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE        );
1441     D3DSTATE_TO_STR(WINED3DRS_WRAPU                     );
1442     D3DSTATE_TO_STR(WINED3DRS_WRAPV                     );
1443     D3DSTATE_TO_STR(WINED3DRS_ZENABLE                   );
1444     D3DSTATE_TO_STR(WINED3DRS_FILLMODE                  );
1445     D3DSTATE_TO_STR(WINED3DRS_SHADEMODE                 );
1446     D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN               );
1447     D3DSTATE_TO_STR(WINED3DRS_MONOENABLE                );
1448     D3DSTATE_TO_STR(WINED3DRS_ROP2                      );
1449     D3DSTATE_TO_STR(WINED3DRS_PLANEMASK                 );
1450     D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE              );
1451     D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE           );
1452     D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL                 );
1453     D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG                );
1454     D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN                );
1455     D3DSTATE_TO_STR(WINED3DRS_SRCBLEND                  );
1456     D3DSTATE_TO_STR(WINED3DRS_DESTBLEND                 );
1457     D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND           );
1458     D3DSTATE_TO_STR(WINED3DRS_CULLMODE                  );
1459     D3DSTATE_TO_STR(WINED3DRS_ZFUNC                     );
1460     D3DSTATE_TO_STR(WINED3DRS_ALPHAREF                  );
1461     D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC                 );
1462     D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE              );
1463     D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE          );
1464     D3DSTATE_TO_STR(WINED3DRS_FOGENABLE                 );
1465     D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE            );
1466     D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE                  );
1467     D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL                  );
1468     D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX                 );
1469     D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA             );
1470     D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR                  );
1471     D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE              );
1472     D3DSTATE_TO_STR(WINED3DRS_FOGSTART                  );
1473     D3DSTATE_TO_STR(WINED3DRS_FOGEND                    );
1474     D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY                );
1475     D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE             );
1476     D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS             );
1477     D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE            );
1478     D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR               );
1479     D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU           );
1480     D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV           );
1481     D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS             );
1482     D3DSTATE_TO_STR(WINED3DRS_ZBIAS                     );
1483     D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE            );
1484     D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY                );
1485     D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH                );
1486     D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1487     D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE             );
1488     D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL               );
1489     D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL              );
1490     D3DSTATE_TO_STR(WINED3DRS_STENCILPASS               );
1491     D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC               );
1492     D3DSTATE_TO_STR(WINED3DRS_STENCILREF                );
1493     D3DSTATE_TO_STR(WINED3DRS_STENCILMASK               );
1494     D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK          );
1495     D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR             );
1496     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00          );
1497     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01          );
1498     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02          );
1499     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03          );
1500     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04          );
1501     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05          );
1502     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06          );
1503     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07          );
1504     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08          );
1505     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09          );
1506     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10          );
1507     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11          );
1508     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12          );
1509     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13          );
1510     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14          );
1511     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15          );
1512     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16          );
1513     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17          );
1514     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18          );
1515     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19          );
1516     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20          );
1517     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21          );
1518     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22          );
1519     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23          );
1520     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24          );
1521     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25          );
1522     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26          );
1523     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27          );
1524     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28          );
1525     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29          );
1526     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30          );
1527     D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31          );
1528     D3DSTATE_TO_STR(WINED3DRS_WRAP0                     );
1529     D3DSTATE_TO_STR(WINED3DRS_WRAP1                     );
1530     D3DSTATE_TO_STR(WINED3DRS_WRAP2                     );
1531     D3DSTATE_TO_STR(WINED3DRS_WRAP3                     );
1532     D3DSTATE_TO_STR(WINED3DRS_WRAP4                     );
1533     D3DSTATE_TO_STR(WINED3DRS_WRAP5                     );
1534     D3DSTATE_TO_STR(WINED3DRS_WRAP6                     );
1535     D3DSTATE_TO_STR(WINED3DRS_WRAP7                     );
1536     D3DSTATE_TO_STR(WINED3DRS_CLIPPING                  );
1537     D3DSTATE_TO_STR(WINED3DRS_LIGHTING                  );
1538     D3DSTATE_TO_STR(WINED3DRS_EXTENTS                   );
1539     D3DSTATE_TO_STR(WINED3DRS_AMBIENT                   );
1540     D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE             );
1541     D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX               );
1542     D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER               );
1543     D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS          );
1544     D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE       );
1545     D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE     );
1546     D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE    );
1547     D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE     );
1548     D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE    );
1549     D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND               );
1550     D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE           );
1551     D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING  );
1552     D3DSTATE_TO_STR(WINED3DRS_POINTSIZE                 );
1553     D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN             );
1554     D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE         );
1555     D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE          );
1556     D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A              );
1557     D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B              );
1558     D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C              );
1559     D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS      );
1560     D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK           );
1561     D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE            );
1562     D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS             );
1563     D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN         );
1564     D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX             );
1565     D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE  );
1566     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE          );
1567     D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR               );
1568     D3DSTATE_TO_STR(WINED3DRS_BLENDOP                   );
1569     D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE            );
1570     D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE              );
1571     D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE         );
1572     D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS       );
1573     D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE     );
1574     D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL      );
1575     D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL      );
1576     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X            );
1577     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y            );
1578     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z            );
1579     D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W            );
1580     D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1581     D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE       );
1582     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL           );
1583     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL          );
1584     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS           );
1585     D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC           );
1586     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1         );
1587     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2         );
1588     D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3         );
1589     D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR               );
1590     D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE           );
1591     D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS                 );
1592     D3DSTATE_TO_STR(WINED3DRS_WRAP8                     );
1593     D3DSTATE_TO_STR(WINED3DRS_WRAP9                     );
1594     D3DSTATE_TO_STR(WINED3DRS_WRAP10                    );
1595     D3DSTATE_TO_STR(WINED3DRS_WRAP11                    );
1596     D3DSTATE_TO_STR(WINED3DRS_WRAP12                    );
1597     D3DSTATE_TO_STR(WINED3DRS_WRAP13                    );
1598     D3DSTATE_TO_STR(WINED3DRS_WRAP14                    );
1599     D3DSTATE_TO_STR(WINED3DRS_WRAP15                    );
1600     D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE  );
1601     D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA             );
1602     D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA            );
1603     D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA              );
1604 #undef D3DSTATE_TO_STR
1605   default:
1606     FIXME("Unrecognized %u render state!\n", state);
1607     return "unrecognized";
1608   }
1609 }
1610
1611 const char* debug_d3dsamplerstate(DWORD state) {
1612   switch (state) {
1613 #define D3DSTATE_TO_STR(u) case u: return #u
1614     D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR  );
1615     D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU     );
1616     D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV     );
1617     D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW     );
1618     D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER    );
1619     D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER    );
1620     D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER    );
1621     D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1622     D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL  );
1623     D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1624     D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE  );
1625     D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1626     D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET   );
1627 #undef D3DSTATE_TO_STR
1628   default:
1629     FIXME("Unrecognized %u sampler state!\n", state);
1630     return "unrecognized";
1631   }
1632 }
1633
1634 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1635     switch (filter_type) {
1636 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1637         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1638         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1639         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1640         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1641         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1642         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1643         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1644         D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1645 #undef D3DTEXTUREFILTERTYPE_TO_STR
1646         default:
1647             FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1648             return "unrecognized";
1649     }
1650 }
1651
1652 const char* debug_d3dtexturestate(DWORD state) {
1653   switch (state) {
1654 #define D3DSTATE_TO_STR(u) case u: return #u
1655     D3DSTATE_TO_STR(WINED3DTSS_COLOROP               );
1656     D3DSTATE_TO_STR(WINED3DTSS_COLORARG1             );
1657     D3DSTATE_TO_STR(WINED3DTSS_COLORARG2             );
1658     D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP               );
1659     D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1             );
1660     D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2             );
1661     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00          );
1662     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01          );
1663     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10          );
1664     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11          );
1665     D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX         );
1666     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE         );
1667     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET        );
1668     D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1669     D3DSTATE_TO_STR(WINED3DTSS_COLORARG0             );
1670     D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0             );
1671     D3DSTATE_TO_STR(WINED3DTSS_RESULTARG             );
1672     D3DSTATE_TO_STR(WINED3DTSS_CONSTANT              );
1673 #undef D3DSTATE_TO_STR
1674   default:
1675     FIXME("Unrecognized %u texture state!\n", state);
1676     return "unrecognized";
1677   }
1678 }
1679
1680 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1681     switch (d3dtop) {
1682 #define D3DTOP_TO_STR(u) case u: return #u
1683         D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1684         D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1685         D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1686         D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1687         D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1688         D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1689         D3DTOP_TO_STR(WINED3DTOP_ADD);
1690         D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1691         D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1692         D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1693         D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1694         D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1695         D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1696         D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1697         D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1698         D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1699         D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1700         D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1701         D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1702         D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1703         D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1704         D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1705         D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1706         D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1707         D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1708         D3DTOP_TO_STR(WINED3DTOP_LERP);
1709 #undef D3DTOP_TO_STR
1710         default:
1711             FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1712             return "unrecognized";
1713     }
1714 }
1715
1716 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1717     switch (tstype) {
1718 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1719     TSTYPE_TO_STR(WINED3DTS_VIEW);
1720     TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1721     TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1722     TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1723     TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1724     TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1725     TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1726     TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1727     TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1728     TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1729     TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1730 #undef TSTYPE_TO_STR
1731     default:
1732         if (tstype > 256 && tstype < 512) {
1733             FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1734             return ("WINED3DTS_WORLDMATRIX > 0");
1735         }
1736         FIXME("Unrecognized %u WINED3DTS\n", tstype);
1737         return "unrecognized";
1738     }
1739 }
1740
1741 const char* debug_d3dpool(WINED3DPOOL Pool) {
1742   switch (Pool) {
1743 #define POOL_TO_STR(p) case p: return #p
1744     POOL_TO_STR(WINED3DPOOL_DEFAULT);
1745     POOL_TO_STR(WINED3DPOOL_MANAGED);
1746     POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1747     POOL_TO_STR(WINED3DPOOL_SCRATCH);
1748 #undef  POOL_TO_STR
1749   default:
1750     FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1751     return "unrecognized";
1752   }
1753 }
1754
1755 const char *debug_fbostatus(GLenum status) {
1756     switch(status) {
1757 #define FBOSTATUS_TO_STR(u) case u: return #u
1758         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1759         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1760         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1761         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1762         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1763         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1764         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1765         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
1766         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1767 #undef FBOSTATUS_TO_STR
1768         default:
1769             FIXME("Unrecognied FBO status 0x%08x\n", status);
1770             return "unrecognized";
1771     }
1772 }
1773
1774 const char *debug_glerror(GLenum error) {
1775     switch(error) {
1776 #define GLERROR_TO_STR(u) case u: return #u
1777         GLERROR_TO_STR(GL_NO_ERROR);
1778         GLERROR_TO_STR(GL_INVALID_ENUM);
1779         GLERROR_TO_STR(GL_INVALID_VALUE);
1780         GLERROR_TO_STR(GL_INVALID_OPERATION);
1781         GLERROR_TO_STR(GL_STACK_OVERFLOW);
1782         GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1783         GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1784         GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1785 #undef GLERROR_TO_STR
1786         default:
1787             FIXME("Unrecognied GL error 0x%08x\n", error);
1788             return "unrecognized";
1789     }
1790 }
1791
1792 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1793     switch(basis) {
1794         case WINED3DBASIS_BEZIER:       return "WINED3DBASIS_BEZIER";
1795         case WINED3DBASIS_BSPLINE:      return "WINED3DBASIS_BSPLINE";
1796         case WINED3DBASIS_INTERPOLATE:  return "WINED3DBASIS_INTERPOLATE";
1797         default:                        return "unrecognized";
1798     }
1799 }
1800
1801 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1802     switch(degree) {
1803         case WINED3DDEGREE_LINEAR:      return "WINED3DDEGREE_LINEAR";
1804         case WINED3DDEGREE_QUADRATIC:   return "WINED3DDEGREE_QUADRATIC";
1805         case WINED3DDEGREE_CUBIC:       return "WINED3DDEGREE_CUBIC";
1806         case WINED3DDEGREE_QUINTIC:     return "WINED3DDEGREE_QUINTIC";
1807         default:                        return "unrecognized";
1808     }
1809 }
1810
1811 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
1812 {
1813     switch(source)
1814     {
1815 #define WINED3D_TO_STR(x) case x: return #x
1816         WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1817         WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1818         WINED3D_TO_STR(CHANNEL_SOURCE_X);
1819         WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1820         WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1821         WINED3D_TO_STR(CHANNEL_SOURCE_W);
1822         WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1823         WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1824 #undef WINED3D_TO_STR
1825         default:
1826             FIXME("Unrecognized fixup_channel_source %#x\n", source);
1827             return "unrecognized";
1828     }
1829 }
1830
1831 static const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1832 {
1833     switch(yuv_fixup)
1834     {
1835 #define WINED3D_TO_STR(x) case x: return #x
1836         WINED3D_TO_STR(YUV_FIXUP_YUY2);
1837         WINED3D_TO_STR(YUV_FIXUP_UYVY);
1838         WINED3D_TO_STR(YUV_FIXUP_YV12);
1839 #undef WINED3D_TO_STR
1840         default:
1841             FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1842             return "unrecognized";
1843     }
1844 }
1845
1846 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1847 {
1848     if (is_yuv_fixup(fixup))
1849     {
1850         TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1851         return;
1852     }
1853
1854     TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1855     TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1856     TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1857     TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1858 }
1859
1860 const char *debug_surflocation(DWORD flag) {
1861     char buf[128];
1862
1863     buf[0] = 0;
1864     if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
1865     if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
1866     if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
1867     if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
1868     return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
1869 }
1870
1871 /*****************************************************************************
1872  * Useful functions mapping GL <-> D3D values
1873  */
1874 GLenum StencilOp(DWORD op) {
1875     switch(op) {
1876     case WINED3DSTENCILOP_KEEP    : return GL_KEEP;
1877     case WINED3DSTENCILOP_ZERO    : return GL_ZERO;
1878     case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1879     case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1880     case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1881     case WINED3DSTENCILOP_INVERT  : return GL_INVERT;
1882     case WINED3DSTENCILOP_INCR    : return GL_INCR_WRAP_EXT;
1883     case WINED3DSTENCILOP_DECR    : return GL_DECR_WRAP_EXT;
1884     default:
1885         FIXME("Unrecognized stencil op %d\n", op);
1886         return GL_KEEP;
1887     }
1888 }
1889
1890 GLenum CompareFunc(DWORD func) {
1891     switch ((WINED3DCMPFUNC)func) {
1892     case WINED3DCMP_NEVER        : return GL_NEVER;
1893     case WINED3DCMP_LESS         : return GL_LESS;
1894     case WINED3DCMP_EQUAL        : return GL_EQUAL;
1895     case WINED3DCMP_LESSEQUAL    : return GL_LEQUAL;
1896     case WINED3DCMP_GREATER      : return GL_GREATER;
1897     case WINED3DCMP_NOTEQUAL     : return GL_NOTEQUAL;
1898     case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1899     case WINED3DCMP_ALWAYS       : return GL_ALWAYS;
1900     default:
1901         FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1902         return 0;
1903     }
1904 }
1905
1906 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1907     if (op == WINED3DTOP_DISABLE) return FALSE;
1908     if (This->stateBlock->textures[stage]) return FALSE;
1909
1910     if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1911             && op != WINED3DTOP_SELECTARG2) return TRUE;
1912     if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1913             && op != WINED3DTOP_SELECTARG1) return TRUE;
1914     if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1915             && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1916
1917     return FALSE;
1918 }
1919
1920 /* Setup this textures matrix according to the texture flags*/
1921 /* GL locking is done by the caller (state handler) */
1922 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
1923         WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
1924 {
1925     float mat[16];
1926
1927     glMatrixMode(GL_TEXTURE);
1928     checkGLcall("glMatrixMode(GL_TEXTURE)");
1929
1930     if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1931         glLoadIdentity();
1932         checkGLcall("glLoadIdentity()");
1933         return;
1934     }
1935
1936     if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1937         ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1938         return;
1939     }
1940
1941     memcpy(mat, smat, 16 * sizeof(float));
1942
1943     if (flags & WINED3DTTFF_PROJECTED) {
1944         if(!ffp_proj_control) {
1945             switch (flags & ~WINED3DTTFF_PROJECTED) {
1946             case WINED3DTTFF_COUNT2:
1947                 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1948                 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1949                 break;
1950             case WINED3DTTFF_COUNT3:
1951                 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1952                 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1953                 break;
1954             }
1955         }
1956     } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1957         if(!calculatedCoords) {
1958             switch(vtx_fmt)
1959             {
1960                 case WINED3DFMT_R32_FLOAT:
1961                     /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1962                      * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1963                      * the input value to the transformation will be 0, so the matrix value is irrelevant
1964                      */
1965                     mat[12] = mat[4];
1966                     mat[13] = mat[5];
1967                     mat[14] = mat[6];
1968                     mat[15] = mat[7];
1969                     break;
1970                 case WINED3DFMT_R32G32_FLOAT:
1971                     /* See above, just 3rd and 4th coord
1972                     */
1973                     mat[12] = mat[8];
1974                     mat[13] = mat[9];
1975                     mat[14] = mat[10];
1976                     mat[15] = mat[11];
1977                     break;
1978                 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
1979                 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
1980
1981                 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1982                  * into a bad place. The division elimination below will apply to make sure the
1983                  * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1984                  */
1985                 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
1986                     break;
1987                 default:
1988                     FIXME("Unexpected fixed function texture coord input\n");
1989             }
1990         }
1991         if(!ffp_proj_control) {
1992             switch (flags & ~WINED3DTTFF_PROJECTED) {
1993                 /* case WINED3DTTFF_COUNT1: Won't ever get here */
1994                 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
1995                 /* OpenGL divides the first 3 vertex coord by the 4th by default,
1996                 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
1997                 * the 4th coord evaluates to 1.0 to eliminate that.
1998                 *
1999                 * If the fixed function pipeline is used, the 4th value remains unused,
2000                 * so there is no danger in doing this. With vertex shaders we have a
2001                 * problem. Should an app hit that problem, the code here would have to
2002                 * check for pixel shaders, and the shader has to undo the default gl divide.
2003                 *
2004                 * A more serious problem occurs if the app passes 4 coordinates in, and the
2005                 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2006                 * or a replacement shader
2007                 */
2008                 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2009             }
2010         }
2011     }
2012
2013     glLoadMatrixf(mat);
2014     checkGLcall("glLoadMatrixf(mat)");
2015 }
2016 #undef GLINFO_LOCATION
2017
2018 /* This small helper function is used to convert a bitmask into the number of masked bits */
2019 unsigned int count_bits(unsigned int mask)
2020 {
2021     unsigned int count;
2022     for (count = 0; mask; ++count)
2023     {
2024         mask &= mask - 1;
2025     }
2026     return count;
2027 }
2028
2029 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2030  * The later function requires individual color components. */
2031 BOOL getColorBits(const struct GlPixelFormatDesc *format_desc,
2032         short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2033 {
2034     TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2035     switch(format_desc->format)
2036     {
2037         case WINED3DFMT_X8R8G8B8:
2038         case WINED3DFMT_R8G8B8:
2039         case WINED3DFMT_A8R8G8B8:
2040         case WINED3DFMT_R8G8B8A8_UNORM:
2041         case WINED3DFMT_A2R10G10B10:
2042         case WINED3DFMT_X1R5G5B5:
2043         case WINED3DFMT_A1R5G5B5:
2044         case WINED3DFMT_R5G6B5:
2045         case WINED3DFMT_X4R4G4B4:
2046         case WINED3DFMT_A4R4G4B4:
2047         case WINED3DFMT_R3G3B2:
2048         case WINED3DFMT_A8P8:
2049         case WINED3DFMT_P8:
2050             break;
2051         default:
2052             ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
2053             return FALSE;
2054     }
2055
2056     *redSize = count_bits(format_desc->red_mask);
2057     *greenSize = count_bits(format_desc->green_mask);
2058     *blueSize = count_bits(format_desc->blue_mask);
2059     *alphaSize = count_bits(format_desc->alpha_mask);
2060     *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2061
2062     TRACE("Returning red:  %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
2063             *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
2064     return TRUE;
2065 }
2066
2067 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2068 BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize)
2069 {
2070     TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2071     switch(format_desc->format)
2072     {
2073         case WINED3DFMT_D16_LOCKABLE:
2074         case WINED3DFMT_D16_UNORM:
2075         case WINED3DFMT_D15S1:
2076         case WINED3DFMT_D24X8:
2077         case WINED3DFMT_D24X4S4:
2078         case WINED3DFMT_D24S8:
2079         case WINED3DFMT_D24FS8:
2080         case WINED3DFMT_D32:
2081         case WINED3DFMT_D32F_LOCKABLE:
2082             break;
2083         default:
2084             FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
2085             return FALSE;
2086     }
2087
2088     *depthSize = format_desc->depth_size;
2089     *stencilSize = format_desc->stencil_size;
2090
2091     TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
2092             *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
2093     return TRUE;
2094 }
2095
2096 /* DirectDraw stuff */
2097 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2098     switch(depth) {
2099         case 8:  return WINED3DFMT_P8;
2100         case 15: return WINED3DFMT_X1R5G5B5;
2101         case 16: return WINED3DFMT_R5G6B5;
2102         case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
2103         case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
2104         default: return WINED3DFMT_UNKNOWN;
2105     }
2106 }
2107
2108 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2109     WINED3DMATRIX temp;
2110
2111     /* Now do the multiplication 'by hand'.
2112        I know that all this could be optimised, but this will be done later :-) */
2113     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);
2114     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);
2115     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);
2116     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);
2117
2118     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);
2119     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);
2120     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);
2121     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);
2122
2123     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);
2124     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);
2125     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);
2126     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);
2127
2128     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);
2129     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);
2130     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);
2131     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);
2132
2133     /* And copy the new matrix in the good storage.. */
2134     memcpy(dest, &temp, 16 * sizeof(float));
2135 }
2136
2137 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2138     DWORD size = 0;
2139     int i;
2140     int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2141
2142     if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2143     if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2144     if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2145     if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2146     switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2147         case WINED3DFVF_XYZ:    size += 3 * sizeof(float); break;
2148         case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2149         case WINED3DFVF_XYZB1:  size += 4 * sizeof(float); break;
2150         case WINED3DFVF_XYZB2:  size += 5 * sizeof(float); break;
2151         case WINED3DFVF_XYZB3:  size += 6 * sizeof(float); break;
2152         case WINED3DFVF_XYZB4:  size += 7 * sizeof(float); break;
2153         case WINED3DFVF_XYZB5:  size += 8 * sizeof(float); break;
2154         case WINED3DFVF_XYZW:   size += 4 * sizeof(float); break;
2155         default: ERR("Unexpected position mask\n");
2156     }
2157     for (i = 0; i < numTextures; i++) {
2158         size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2159     }
2160
2161     return size;
2162 }
2163
2164 /***********************************************************************
2165  * CalculateTexRect
2166  *
2167  * Calculates the dimensions of the opengl texture used for blits.
2168  * Handled oversized opengl textures and updates the source rectangle
2169  * accordingly
2170  *
2171  * Params:
2172  *  This: Surface to operate on
2173  *  Rect: Requested rectangle
2174  *
2175  * Returns:
2176  *  TRUE if the texture part can be loaded,
2177  *  FALSE otherwise
2178  *
2179  *********************************************************************/
2180 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
2181
2182 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
2183     int x1 = Rect->left, x2 = Rect->right;
2184     int y1 = Rect->top, y2 = Rect->bottom;
2185     GLint maxSize = GL_LIMITS(texture_size);
2186
2187     TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2188           Rect->left, Rect->top, Rect->right, Rect->bottom);
2189
2190     /* The sizes might be reversed */
2191     if(Rect->left > Rect->right) {
2192         x1 = Rect->right;
2193         x2 = Rect->left;
2194     }
2195     if(Rect->top > Rect->bottom) {
2196         y1 = Rect->bottom;
2197         y2 = Rect->top;
2198     }
2199
2200     /* No oversized texture? This is easy */
2201     if(!(This->Flags & SFLAG_OVERSIZE)) {
2202         /* Which rect from the texture do I need? */
2203         if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
2204         {
2205             glTexCoord[0] = (float) Rect->left;
2206             glTexCoord[2] = (float) Rect->top;
2207             glTexCoord[1] = (float) Rect->right;
2208             glTexCoord[3] = (float) Rect->bottom;
2209         } else {
2210             glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2211             glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2212             glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2213             glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2214         }
2215
2216         return TRUE;
2217     } else {
2218         /* Check if we can succeed at all */
2219         if( (x2 - x1) > maxSize ||
2220             (y2 - y1) > maxSize ) {
2221             TRACE("Requested rectangle is too large for gl\n");
2222             return FALSE;
2223         }
2224
2225         /* A part of the texture has to be picked. First, check if
2226          * some texture part is loaded already, if yes try to re-use it.
2227          * If the texture is dirty, or the part can't be used,
2228          * re-position the part to load
2229          */
2230         if(This->Flags & SFLAG_INTEXTURE) {
2231             if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2232                This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2233                 /* Ok, the rectangle is ok, re-use it */
2234                 TRACE("Using existing gl Texture\n");
2235             } else {
2236                 /* Rectangle is not ok, dirtify the texture to reload it */
2237                 TRACE("Dirtifying texture to force reload\n");
2238                 This->Flags &= ~SFLAG_INTEXTURE;
2239             }
2240         }
2241
2242         /* Now if we are dirty(no else if!) */
2243         if(!(This->Flags & SFLAG_INTEXTURE)) {
2244             /* Set the new rectangle. Use the following strategy:
2245              * 1) Use as big textures as possible.
2246              * 2) Place the texture part in the way that the requested
2247              *    part is in the middle of the texture(well, almost)
2248              * 3) If the texture is moved over the edges of the
2249              *    surface, replace it nicely
2250              * 4) If the coord is not limiting the texture size,
2251              *    use the whole size
2252              */
2253             if((This->pow2Width) > maxSize) {
2254                 This->glRect.left = x1 - maxSize / 2;
2255                 if(This->glRect.left < 0) {
2256                     This->glRect.left = 0;
2257                 }
2258                 This->glRect.right = This->glRect.left + maxSize;
2259                 if(This->glRect.right > This->currentDesc.Width) {
2260                     This->glRect.right = This->currentDesc.Width;
2261                     This->glRect.left = This->glRect.right - maxSize;
2262                 }
2263             } else {
2264                 This->glRect.left = 0;
2265                 This->glRect.right = This->pow2Width;
2266             }
2267
2268             if(This->pow2Height > maxSize) {
2269                 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2270                 if(This->glRect.top < 0) This->glRect.top = 0;
2271                 This->glRect.bottom = This->glRect.left + maxSize;
2272                 if(This->glRect.bottom > This->currentDesc.Height) {
2273                     This->glRect.bottom = This->currentDesc.Height;
2274                     This->glRect.top = This->glRect.bottom - maxSize;
2275                 }
2276             } else {
2277                 This->glRect.top = 0;
2278                 This->glRect.bottom = This->pow2Height;
2279             }
2280             TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2281                    This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2282         }
2283
2284         /* Re-calculate the rect to draw */
2285         Rect->left -= This->glRect.left;
2286         Rect->right -= This->glRect.left;
2287         Rect->top -= This->glRect.top;
2288         Rect->bottom -= This->glRect.top;
2289
2290         /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2291          * or the pow2Width / pow2Height of the surface.
2292          *
2293          * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
2294          * as regular GL_TEXTURE_2D.
2295          */
2296         glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2297         glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2298         glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2299         glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2300     }
2301     return TRUE;
2302 }
2303 #undef GLINFO_LOCATION
2304
2305 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2306 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2307 #define ARG1 0x01
2308 #define ARG2 0x02
2309 #define ARG0 0x04
2310     static const unsigned char args[WINED3DTOP_LERP + 1] = {
2311         /* undefined                        */  0,
2312         /* D3DTOP_DISABLE                   */  0,
2313         /* D3DTOP_SELECTARG1                */  ARG1,
2314         /* D3DTOP_SELECTARG2                */  ARG2,
2315         /* D3DTOP_MODULATE                  */  ARG1 | ARG2,
2316         /* D3DTOP_MODULATE2X                */  ARG1 | ARG2,
2317         /* D3DTOP_MODULATE4X                */  ARG1 | ARG2,
2318         /* D3DTOP_ADD                       */  ARG1 | ARG2,
2319         /* D3DTOP_ADDSIGNED                 */  ARG1 | ARG2,
2320         /* D3DTOP_ADDSIGNED2X               */  ARG1 | ARG2,
2321         /* D3DTOP_SUBTRACT                  */  ARG1 | ARG2,
2322         /* D3DTOP_ADDSMOOTH                 */  ARG1 | ARG2,
2323         /* D3DTOP_BLENDDIFFUSEALPHA         */  ARG1 | ARG2,
2324         /* D3DTOP_BLENDTEXTUREALPHA         */  ARG1 | ARG2,
2325         /* D3DTOP_BLENDFACTORALPHA          */  ARG1 | ARG2,
2326         /* D3DTOP_BLENDTEXTUREALPHAPM       */  ARG1 | ARG2,
2327         /* D3DTOP_BLENDCURRENTALPHA         */  ARG1 | ARG2,
2328         /* D3DTOP_PREMODULATE               */  ARG1 | ARG2,
2329         /* D3DTOP_MODULATEALPHA_ADDCOLOR    */  ARG1 | ARG2,
2330         /* D3DTOP_MODULATECOLOR_ADDALPHA    */  ARG1 | ARG2,
2331         /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */  ARG1 | ARG2,
2332         /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */  ARG1 | ARG2,
2333         /* D3DTOP_BUMPENVMAP                */  ARG1 | ARG2,
2334         /* D3DTOP_BUMPENVMAPLUMINANCE       */  ARG1 | ARG2,
2335         /* D3DTOP_DOTPRODUCT3               */  ARG1 | ARG2,
2336         /* D3DTOP_MULTIPLYADD               */  ARG1 | ARG2 | ARG0,
2337         /* D3DTOP_LERP                      */  ARG1 | ARG2 | ARG0
2338     };
2339     unsigned int i;
2340     DWORD ttff;
2341     DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2342     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2343
2344     for(i = 0; i < GL_LIMITS(texture_stages); i++) {
2345         IWineD3DBaseTextureImpl *texture;
2346         settings->op[i].padding = 0;
2347         if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2348             settings->op[i].cop = WINED3DTOP_DISABLE;
2349             settings->op[i].aop = WINED3DTOP_DISABLE;
2350             settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2351             settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2352             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2353             settings->op[i].dst = resultreg;
2354             settings->op[i].tex_type = tex_1d;
2355             settings->op[i].projected = proj_none;
2356             i++;
2357             break;
2358         }
2359
2360         texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2361         if(texture) {
2362             settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2363             if(ignore_textype) {
2364                 settings->op[i].tex_type = tex_1d;
2365             } else {
2366                 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2367                     case GL_TEXTURE_1D:
2368                         settings->op[i].tex_type = tex_1d;
2369                         break;
2370                     case GL_TEXTURE_2D:
2371                         settings->op[i].tex_type = tex_2d;
2372                         break;
2373                     case GL_TEXTURE_3D:
2374                         settings->op[i].tex_type = tex_3d;
2375                         break;
2376                     case GL_TEXTURE_CUBE_MAP_ARB:
2377                         settings->op[i].tex_type = tex_cube;
2378                         break;
2379                     case GL_TEXTURE_RECTANGLE_ARB:
2380                         settings->op[i].tex_type = tex_rect;
2381                         break;
2382                 }
2383             }
2384         } else {
2385             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2386             settings->op[i].tex_type = tex_1d;
2387         }
2388
2389         cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2390         aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2391
2392         carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2393         carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2394         carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2395
2396         if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2397             carg0 = ARG_UNUSED;
2398             carg2 = ARG_UNUSED;
2399             carg1 = WINED3DTA_CURRENT;
2400             cop = WINED3DTOP_SELECTARG1;
2401         }
2402
2403         if(cop == WINED3DTOP_DOTPRODUCT3) {
2404             /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2405              * the color result to the alpha component of the destination
2406              */
2407             aop = cop;
2408             aarg1 = carg1;
2409             aarg2 = carg2;
2410             aarg0 = carg0;
2411         } else {
2412             aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2413             aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2414             aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2415         }
2416
2417         if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2418         {
2419             UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2420
2421             if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2422             {
2423                 IWineD3DSurfaceImpl *surf;
2424                 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2425
2426                 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2427                 {
2428                     if (aop == WINED3DTOP_DISABLE)
2429                     {
2430                        aarg1 = WINED3DTA_TEXTURE;
2431                        aop = WINED3DTOP_SELECTARG1;
2432                     }
2433                     else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2434                     {
2435                         if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2436                         {
2437                             aarg2 = WINED3DTA_TEXTURE;
2438                             aop = WINED3DTOP_MODULATE;
2439                         }
2440                         else aarg1 = WINED3DTA_TEXTURE;
2441                     }
2442                     else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2443                     {
2444                         if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2445                         {
2446                             aarg1 = WINED3DTA_TEXTURE;
2447                             aop = WINED3DTOP_MODULATE;
2448                         }
2449                         else aarg2 = WINED3DTA_TEXTURE;
2450                     }
2451                 }
2452             }
2453         }
2454
2455         if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2456                aarg0 = ARG_UNUSED;
2457                aarg2 = ARG_UNUSED;
2458                aarg1 = WINED3DTA_CURRENT;
2459                aop = WINED3DTOP_SELECTARG1;
2460         }
2461
2462         if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2463            aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2464             ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2465             if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2466                 settings->op[i].projected = proj_count3;
2467             } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2468                 settings->op[i].projected = proj_count4;
2469             } else {
2470                 settings->op[i].projected = proj_none;
2471             }
2472         } else {
2473             settings->op[i].projected = proj_none;
2474         }
2475
2476         settings->op[i].cop = cop;
2477         settings->op[i].aop = aop;
2478         settings->op[i].carg0 = carg0;
2479         settings->op[i].carg1 = carg1;
2480         settings->op[i].carg2 = carg2;
2481         settings->op[i].aarg0 = aarg0;
2482         settings->op[i].aarg1 = aarg1;
2483         settings->op[i].aarg2 = aarg2;
2484
2485         if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2486             settings->op[i].dst = tempreg;
2487         } else {
2488             settings->op[i].dst = resultreg;
2489         }
2490     }
2491
2492     /* Clear unsupported stages */
2493     for(; i < MAX_TEXTURES; i++) {
2494         memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2495     }
2496
2497     if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2498         settings->fog = FOG_OFF;
2499     } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2500         if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2501             settings->fog = FOG_LINEAR;
2502         } else {
2503             switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2504                 case WINED3DFOG_NONE:
2505                 case WINED3DFOG_LINEAR:
2506                     settings->fog = FOG_LINEAR;
2507                     break;
2508                 case WINED3DFOG_EXP:
2509                     settings->fog = FOG_EXP;
2510                     break;
2511                 case WINED3DFOG_EXP2:
2512                     settings->fog = FOG_EXP2;
2513                     break;
2514             }
2515         }
2516     } else {
2517         switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2518             case WINED3DFOG_LINEAR:
2519                 settings->fog = FOG_LINEAR;
2520                 break;
2521             case WINED3DFOG_EXP:
2522                 settings->fog = FOG_EXP;
2523                 break;
2524             case WINED3DFOG_EXP2:
2525                 settings->fog = FOG_EXP2;
2526                 break;
2527         }
2528     }
2529     if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2530         settings->sRGB_write = 1;
2531     } else {
2532         settings->sRGB_write = 0;
2533     }
2534     if(device->vs_clipping || !use_vs(stateblock)) {
2535         /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2536          * the fixed function vertex pipeline is used(which always supports clipplanes)
2537          */
2538         settings->emul_clipplanes = 0;
2539     } else {
2540         settings->emul_clipplanes = 1;
2541     }
2542 }
2543 #undef GLINFO_LOCATION
2544
2545 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2546         const struct ffp_frag_settings *settings)
2547 {
2548     struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2549     return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2550 }
2551
2552 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2553 {
2554     /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2555      * whereas desc points to an extended structure with implementation specific parts. */
2556     if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2557     {
2558         ERR("Failed to insert ffp frag shader.\n");
2559     }
2560 }
2561
2562 /* Activates the texture dimension according to the bound D3D texture.
2563  * Does not care for the colorop or correct gl texture unit(when using nvrc)
2564  * Requires the caller to activate the correct unit before
2565  */
2566 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2567 /* GL locking is done by the caller (state handler) */
2568 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2569 {
2570     if(stateblock->textures[stage]) {
2571         switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2572             case GL_TEXTURE_2D:
2573                 glDisable(GL_TEXTURE_3D);
2574                 checkGLcall("glDisable(GL_TEXTURE_3D)");
2575                 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2576                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2577                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2578                 }
2579                 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2580                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
2581                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2582                 }
2583                 glEnable(GL_TEXTURE_2D);
2584                 checkGLcall("glEnable(GL_TEXTURE_2D)");
2585                 break;
2586             case GL_TEXTURE_RECTANGLE_ARB:
2587                 glDisable(GL_TEXTURE_2D);
2588                 checkGLcall("glDisable(GL_TEXTURE_2D)");
2589                 glDisable(GL_TEXTURE_3D);
2590                 checkGLcall("glDisable(GL_TEXTURE_3D)");
2591                 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2592                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2593                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2594                 }
2595                 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2596                 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2597                 break;
2598             case GL_TEXTURE_3D:
2599                 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2600                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2601                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2602                 }
2603                 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2604                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
2605                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2606                 }
2607                 glDisable(GL_TEXTURE_2D);
2608                 checkGLcall("glDisable(GL_TEXTURE_2D)");
2609                 glEnable(GL_TEXTURE_3D);
2610                 checkGLcall("glEnable(GL_TEXTURE_3D)");
2611                 break;
2612             case GL_TEXTURE_CUBE_MAP_ARB:
2613                 glDisable(GL_TEXTURE_2D);
2614                 checkGLcall("glDisable(GL_TEXTURE_2D)");
2615                 glDisable(GL_TEXTURE_3D);
2616                 checkGLcall("glDisable(GL_TEXTURE_3D)");
2617                 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2618                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
2619                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2620                 }
2621                 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2622                 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2623               break;
2624         }
2625     } else {
2626         glEnable(GL_TEXTURE_2D);
2627         checkGLcall("glEnable(GL_TEXTURE_2D)");
2628         glDisable(GL_TEXTURE_3D);
2629         checkGLcall("glDisable(GL_TEXTURE_3D)");
2630         if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2631             glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2632             checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2633         }
2634         if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2635             glDisable(GL_TEXTURE_RECTANGLE_ARB);
2636             checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2637         }
2638         /* Binding textures is done by samplers. A dummy texture will be bound */
2639     }
2640 }
2641
2642 /* GL locking is done by the caller (state handler) */
2643 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2644 {
2645     DWORD sampler = state - STATE_SAMPLER(0);
2646     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2647
2648     /* No need to enable / disable anything here for unused samplers. The tex_colorop
2649     * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2650     * will take care of this business
2651     */
2652     if(mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= GL_LIMITS(textures)) return;
2653     if(sampler >= stateblock->lowest_disabled_stage) return;
2654     if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2655
2656     texture_activate_dimensions(sampler, stateblock, context);
2657 }
2658 #undef GLINFO_LOCATION
2659
2660 void *wined3d_rb_alloc(size_t size)
2661 {
2662     return HeapAlloc(GetProcessHeap(), 0, size);
2663 }
2664
2665 void *wined3d_rb_realloc(void *ptr, size_t size)
2666 {
2667     return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
2668 }
2669
2670 void wined3d_rb_free(void *ptr)
2671 {
2672     HeapFree(GetProcessHeap(), 0, ptr);
2673 }
2674
2675 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
2676 {
2677     const struct ffp_frag_settings *ka = key;
2678     const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
2679
2680     return memcmp(ka, kb, sizeof(*ka));
2681 }
2682
2683 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
2684 {
2685     wined3d_rb_alloc,
2686     wined3d_rb_realloc,
2687     wined3d_rb_free,
2688     ffp_frag_program_key_compare,
2689 };
2690
2691 UINT wined3d_log2i(UINT32 x)
2692 {
2693     static const UINT l[] =
2694     {
2695         ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2696           4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2697           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2698           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2699           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2700           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2701           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2702           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2703           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2704           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2705           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2706           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2707           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2708           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2709           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2710           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2711     };
2712     UINT32 i;
2713
2714     return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
2715 }