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