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