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
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wined3d_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
31 struct StaticPixelFormatDesc
34 DWORD alphaMask, redMask, greenMask, blueMask;
36 short depthSize, stencilSize;
40 /*****************************************************************************
43 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
44 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
45 * high masks do not fit into the 32 bit values needed for ddraw. It is only
46 * used for ddraw mostly, and to figure out if the format has alpha at all, so
47 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
48 * formats are not usable in 2D rendering because ddraw doesn't support them.
50 static const struct StaticPixelFormatDesc formats[] =
52 /* WINED3DFORMAT alphamask redmask greenmask bluemask bpp depth stencil isFourcc */
53 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, FALSE},
54 /* FourCC formats, kept here to have WINED3DFMT_R8G8B8(=20) at position 20 */
55 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
56 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
57 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
58 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
59 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
60 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
61 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
62 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
63 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
64 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
65 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
67 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
68 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
69 {WINED3DFMT_R32G32B32_FLOAT, 0x0, 0x0, 0x0, 0x0, 12, 0, 0, FALSE},
70 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0, FALSE},
72 {WINED3DFMT_CxV8U8, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
74 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
75 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
76 {WINED3DFMT_R16G16_SINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
77 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
78 {WINED3DFMT_R16G16B16A16_SINT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
79 /* Palettized formats */
80 {WINED3DFMT_A8P8, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
81 {WINED3DFMT_P8, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
82 /* Standard ARGB formats. */
83 {WINED3DFMT_R8G8B8, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0, FALSE},
84 {WINED3DFMT_A8R8G8B8, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0, FALSE},
85 {WINED3DFMT_X8R8G8B8, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0, FALSE},
86 {WINED3DFMT_R5G6B5, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0, FALSE},
87 {WINED3DFMT_X1R5G5B5, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0, FALSE},
88 {WINED3DFMT_A1R5G5B5, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0, FALSE},
89 {WINED3DFMT_A4R4G4B4, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0, FALSE},
90 {WINED3DFMT_R3G3B2, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0, FALSE},
91 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
92 {WINED3DFMT_A8R3G3B2, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0, FALSE},
93 {WINED3DFMT_X4R4G4B4, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0, FALSE},
94 {WINED3DFMT_R10G10B10A2_UNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
95 {WINED3DFMT_R10G10B10A2_UINT, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
96 {WINED3DFMT_R10G10B10A2_SNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
97 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
98 {WINED3DFMT_R8G8B8A8_UINT, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
99 {WINED3DFMT_X8B8G8R8, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
100 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0, FALSE},
101 {WINED3DFMT_A2R10G10B10, 0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0, FALSE},
102 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0, FALSE},
104 {WINED3DFMT_L8, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
105 {WINED3DFMT_A8L8, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
106 {WINED3DFMT_A4L4, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
107 /* Bump mapping stuff */
108 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
109 {WINED3DFMT_L6V5U5, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
110 {WINED3DFMT_X8L8V8U8, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
111 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
112 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
113 {WINED3DFMT_W11V11U10, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
114 {WINED3DFMT_A2W10V10U10, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
115 /* Depth stencil formats */
116 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
117 {WINED3DFMT_D32, 0x0, 0x0, 0x0, 0x0, 4, 32, 0, FALSE},
118 {WINED3DFMT_D15S1, 0x0, 0x0, 0x0, 0x0, 2, 15, 1, FALSE},
119 {WINED3DFMT_D24S8, 0x0, 0x0, 0x0, 0x0, 4, 24, 8, FALSE},
120 {WINED3DFMT_D24X8, 0x0, 0x0, 0x0, 0x0, 4, 24, 0, FALSE},
121 {WINED3DFMT_D24X4S4, 0x0, 0x0, 0x0, 0x0, 4, 24, 4, FALSE},
122 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
123 {WINED3DFMT_L16, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
124 {WINED3DFMT_D32F_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 4, 32, 0, FALSE},
125 {WINED3DFMT_D24FS8, 0x0, 0x0, 0x0, 0x0, 4, 24, 8, FALSE},
126 /* Is this a vertex buffer? */
127 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, FALSE},
128 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
129 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
130 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
131 /* Vendor-specific formats */
132 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
133 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
134 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
137 struct wined3d_format_compression_info
139 WINED3DFORMAT format;
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;
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_A8R8G8B8, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
173 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
174 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
175 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
176 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
177 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
178 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
179 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
180 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
181 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
182 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
183 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
184 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
189 GLint glInternal, glGammaInternal, rtInternal, glFormat, glType;
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
200 static const GlPixelFormatDescTemplate gl_formats_template[] = {
201 /* WINED3DFORMAT internal srgbInternal rtInternal
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
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,
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,
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},
253 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
255 WINED3DFMT_FLAG_RENDERTARGET,
257 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
259 WINED3DFMT_FLAG_RENDERTARGET,
261 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
263 WINED3DFMT_FLAG_RENDERTARGET,
265 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
267 WINED3DFMT_FLAG_RENDERTARGET,
269 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
271 WINED3DFMT_FLAG_RENDERTARGET,
274 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
275 GL_RED, GL_HALF_FLOAT_ARB,
276 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
278 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
279 GL_RED, GL_HALF_FLOAT_ARB,
280 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
282 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
283 GL_RGB, GL_HALF_FLOAT_ARB,
284 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
286 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
287 GL_RG, GL_HALF_FLOAT_ARB,
288 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
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_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
294 /* Palettized formats */
295 {WINED3DFMT_P8, GL_RGBA, GL_RGBA, 0,
296 GL_RGBA, GL_UNSIGNED_BYTE,
298 ARB_FRAGMENT_PROGRAM},
299 {WINED3DFMT_P8, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
300 GL_COLOR_INDEX, GL_UNSIGNED_BYTE,
302 EXT_PALETTED_TEXTURE},
303 /* Standard ARGB formats */
304 {WINED3DFMT_R8G8B8, GL_RGB8, GL_RGB8, 0,
305 GL_BGR, GL_UNSIGNED_BYTE,
306 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
307 WINED3D_GL_EXT_NONE},
308 {WINED3DFMT_A8R8G8B8, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
309 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
310 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
311 WINED3D_GL_EXT_NONE},
312 {WINED3DFMT_X8R8G8B8, GL_RGB8, GL_SRGB8_EXT, 0,
313 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
314 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
315 WINED3D_GL_EXT_NONE},
316 {WINED3DFMT_R5G6B5, GL_RGB5, GL_RGB5, GL_RGB8,
317 GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
318 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
319 WINED3D_GL_EXT_NONE},
320 {WINED3DFMT_X1R5G5B5, GL_RGB5, GL_RGB5_A1, 0,
321 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
322 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
323 WINED3D_GL_EXT_NONE},
324 {WINED3DFMT_A1R5G5B5, GL_RGB5_A1, GL_RGB5_A1, 0,
325 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
326 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
327 WINED3D_GL_EXT_NONE},
328 {WINED3DFMT_A4R4G4B4, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
329 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
330 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
331 WINED3D_GL_EXT_NONE},
332 {WINED3DFMT_R3G3B2, GL_R3_G3_B2, GL_R3_G3_B2, 0,
333 GL_RGB, GL_UNSIGNED_BYTE_3_3_2,
334 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
335 WINED3D_GL_EXT_NONE},
336 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
337 GL_ALPHA, GL_UNSIGNED_BYTE,
338 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
339 WINED3D_GL_EXT_NONE},
340 {WINED3DFMT_X4R4G4B4, GL_RGB4, GL_RGB4, 0,
341 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
342 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
343 WINED3D_GL_EXT_NONE},
344 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
345 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV,
346 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
347 WINED3D_GL_EXT_NONE},
348 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
349 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
350 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
351 WINED3D_GL_EXT_NONE},
352 {WINED3DFMT_X8B8G8R8, GL_RGB8, GL_RGB8, 0,
353 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
354 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
355 WINED3D_GL_EXT_NONE},
356 {WINED3DFMT_R16G16_UNORM, GL_RGB16_EXT, GL_RGB16_EXT, 0,
357 GL_RGB, GL_UNSIGNED_SHORT,
358 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
359 WINED3D_GL_EXT_NONE},
360 {WINED3DFMT_A2R10G10B10, GL_RGB10_A2, GL_RGB10_A2, 0,
361 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV,
362 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
363 WINED3D_GL_EXT_NONE},
364 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16_EXT, GL_RGBA16_EXT, 0,
365 GL_RGBA, GL_UNSIGNED_SHORT,
366 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
367 WINED3D_GL_EXT_NONE},
369 {WINED3DFMT_L8, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
370 GL_LUMINANCE, GL_UNSIGNED_BYTE,
371 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
372 WINED3D_GL_EXT_NONE},
373 {WINED3DFMT_A8L8, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
374 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
375 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
376 WINED3D_GL_EXT_NONE},
377 {WINED3DFMT_A4L4, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
378 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
380 WINED3D_GL_EXT_NONE},
381 /* Bump mapping stuff */
382 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
383 GL_BGR, GL_UNSIGNED_BYTE,
384 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
385 WINED3D_GL_EXT_NONE},
386 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
388 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
390 {WINED3DFMT_L6V5U5, GL_RGB5, GL_RGB5, 0,
391 GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
392 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
393 WINED3D_GL_EXT_NONE},
394 {WINED3DFMT_L6V5U5, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
395 GL_DSDT_MAG_NV, GL_BYTE,
396 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
398 {WINED3DFMT_X8L8V8U8, GL_RGB8, GL_RGB8, 0,
399 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
400 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
401 WINED3D_GL_EXT_NONE},
402 {WINED3DFMT_X8L8V8U8, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
403 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV,
404 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
406 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
407 GL_BGRA, GL_UNSIGNED_BYTE,
408 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
409 WINED3D_GL_EXT_NONE},
410 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
412 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
414 {WINED3DFMT_R16G16_SNORM, GL_RGB16_EXT, GL_RGB16_EXT, 0,
415 GL_BGR, GL_UNSIGNED_SHORT,
416 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
417 WINED3D_GL_EXT_NONE},
418 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
419 GL_HILO_NV, GL_SHORT,
420 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
422 /* Depth stencil formats */
423 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
424 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
425 WINED3DFMT_FLAG_DEPTH,
427 {WINED3DFMT_D32, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
428 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
429 WINED3DFMT_FLAG_DEPTH,
431 {WINED3DFMT_D15S1, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
432 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
433 WINED3DFMT_FLAG_DEPTH,
435 {WINED3DFMT_D15S1, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
436 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
437 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
438 EXT_PACKED_DEPTH_STENCIL},
439 {WINED3DFMT_D24S8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
440 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
441 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
443 {WINED3DFMT_D24S8, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
444 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
445 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
446 EXT_PACKED_DEPTH_STENCIL},
447 {WINED3DFMT_D24X8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
448 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
449 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
451 {WINED3DFMT_D24X4S4, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
452 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
453 WINED3DFMT_FLAG_DEPTH,
455 {WINED3DFMT_D24X4S4, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
456 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
457 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
458 EXT_PACKED_DEPTH_STENCIL},
459 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
460 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
461 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
463 {WINED3DFMT_L16, GL_LUMINANCE16_EXT, GL_LUMINANCE16_EXT, 0,
464 GL_LUMINANCE, GL_UNSIGNED_SHORT,
465 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
466 WINED3D_GL_EXT_NONE},
467 {WINED3DFMT_D32F_LOCKABLE, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
468 GL_DEPTH_COMPONENT, GL_FLOAT,
469 WINED3DFMT_FLAG_DEPTH,
470 ARB_DEPTH_BUFFER_FLOAT},
471 {WINED3DFMT_D24FS8, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
472 GL_DEPTH_STENCIL_EXT, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
473 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
474 ARB_DEPTH_BUFFER_FLOAT},
475 /* Vendor-specific formats */
476 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
477 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
479 ATI_TEXTURE_COMPRESSION_3DC},
480 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, 0,
481 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
483 EXT_TEXTURE_COMPRESSION_RGTC},
486 static inline int getFmtIdx(WINED3DFORMAT fmt) {
487 /* First check if the format is at the position of its value.
488 * This will catch the argb formats before the loop is entered
490 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
494 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
495 if(formats[i].format == fmt) {
503 static BOOL init_format_base_info(WineD3D_GL_Info *gl_info)
505 UINT format_count = sizeof(formats) / sizeof(*formats);
508 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->gl_formats));
509 if (!gl_info->gl_formats)
511 ERR("Failed to allocate memory.\n");
515 for (i = 0; i < format_count; ++i)
517 struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
518 desc->format = formats[i].format;
519 desc->red_mask = formats[i].redMask;
520 desc->green_mask = formats[i].greenMask;
521 desc->blue_mask = formats[i].blueMask;
522 desc->alpha_mask = formats[i].alphaMask;
523 desc->byte_count = formats[i].bpp;
524 desc->depth_size = formats[i].depthSize;
525 desc->stencil_size = formats[i].stencilSize;
526 if (formats[i].isFourcc) desc->Flags |= WINED3DFMT_FLAG_FOURCC;
532 static BOOL init_format_compression_info(WineD3D_GL_Info *gl_info)
536 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
538 struct GlPixelFormatDesc *format_desc;
539 int fmt_idx = getFmtIdx(format_compression_info[i].format);
543 ERR("Format %s (%#x) not found.\n",
544 debug_d3dformat(format_compression_info[i].format), format_compression_info[i].format);
548 format_desc = &gl_info->gl_formats[fmt_idx];
549 format_desc->block_width = format_compression_info[i].block_width;
550 format_desc->block_height = format_compression_info[i].block_height;
551 format_desc->block_byte_count = format_compression_info[i].block_byte_count;
552 format_desc->Flags |= WINED3DFMT_FLAG_COMPRESSED;
558 #define GLINFO_LOCATION (*gl_info)
560 static BOOL check_fbo_compat(const WineD3D_GL_Info *gl_info, GLint internal_format, GLenum format, GLenum type)
568 glGenTextures(1, &tex);
569 glBindTexture(GL_TEXTURE_2D, tex);
570 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, 16, 16, 0, format, type, NULL);
571 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
572 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
574 GL_EXTCALL(glGenFramebuffersEXT(1, &fb));
575 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb));
576 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
578 status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
579 GL_EXTCALL(glDeleteFramebuffersEXT(1, &fb));
580 glDeleteTextures(1, &tex);
582 checkGLcall("Framebuffer format check");
586 return status == GL_FRAMEBUFFER_COMPLETE_EXT;
589 static void init_format_fbo_compat_info(WineD3D_GL_Info *gl_info)
593 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
595 struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
597 if (!desc->glInternal) continue;
599 if (desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
601 TRACE("Skipping format %s because it's a depth/stencil format.\n",
602 debug_d3dformat(desc->format));
606 if (desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
608 TRACE("Skipping format %s because it's a compressed format.\n",
609 debug_d3dformat(desc->format));
613 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
615 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc->format));
617 /* Check if the default internal format is supported as a frame buffer target, otherwise
618 * fall back to the render target internal.
620 * Try to stick to the standard format if possible, this limits precision differences. */
621 if (check_fbo_compat(gl_info, desc->glInternal, desc->glFormat, desc->glType))
623 TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(desc->format));
624 desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
625 desc->rtInternal = desc->glInternal;
629 if (!desc->rtInternal)
631 if (desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)
633 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
634 " and no fallback specified.\n", debug_d3dformat(desc->format));
635 desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
639 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(desc->format));
641 desc->rtInternal = desc->glInternal;
645 TRACE("Format %s is not supported as FBO color attachment, using rtInternal format as fallback.\n",
646 debug_d3dformat(desc->format));
652 desc->rtInternal = desc->glInternal;
657 static BOOL init_format_texture_info(WineD3D_GL_Info *gl_info)
661 for (i = 0; i < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); ++i)
663 int fmt_idx = getFmtIdx(gl_formats_template[i].fmt);
664 struct GlPixelFormatDesc *desc;
668 ERR("Format %s (%#x) not found.\n",
669 debug_d3dformat(gl_formats_template[i].fmt), gl_formats_template[i].fmt);
673 if (!GL_SUPPORT(gl_formats_template[i].extension)) continue;
675 desc = &gl_info->gl_formats[fmt_idx];
676 desc->glInternal = gl_formats_template[i].glInternal;
677 desc->glGammaInternal = gl_formats_template[i].glGammaInternal;
678 desc->rtInternal = gl_formats_template[i].rtInternal;
679 desc->glFormat = gl_formats_template[i].glFormat;
680 desc->glType = gl_formats_template[i].glType;
681 desc->color_fixup = COLOR_FIXUP_IDENTITY;
682 desc->Flags |= gl_formats_template[i].Flags;
683 desc->heightscale = 1.0;
689 static void apply_format_fixups(WineD3D_GL_Info *gl_info)
693 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
694 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
695 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
697 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
698 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
699 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
701 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
702 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
703 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
705 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
706 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
707 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
709 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
710 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
711 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
713 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
714 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
715 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
716 * the only driver that implements it(fglrx) has a buggy implementation.
718 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
719 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
720 * conversion for this format.
722 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
724 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
725 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
726 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
727 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
728 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
729 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
733 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
734 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
735 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
736 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
737 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
738 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
741 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
743 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
746 idx = getFmtIdx(WINED3DFMT_L6V5U5);
747 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
748 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
749 idx = getFmtIdx(WINED3DFMT_X8L8V8U8);
750 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
751 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
752 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
753 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
754 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
758 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
759 * are converted at surface loading time, but they do not need any modification in
760 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
761 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
765 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC))
767 idx = getFmtIdx(WINED3DFMT_ATI2N);
768 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
769 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
771 else if (GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC))
773 idx = getFmtIdx(WINED3DFMT_ATI2N);
774 gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
775 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
778 if (!GL_SUPPORT(APPLE_YCBCR_422))
780 idx = getFmtIdx(WINED3DFMT_YUY2);
781 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
783 idx = getFmtIdx(WINED3DFMT_UYVY);
784 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
787 idx = getFmtIdx(WINED3DFMT_YV12);
788 gl_info->gl_formats[idx].heightscale = 1.5;
789 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
791 if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
793 idx = getFmtIdx(WINED3DFMT_A8R8G8B8);
794 gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
797 if (GL_SUPPORT(ARB_HALF_FLOAT_VERTEX))
799 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
800 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
801 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
802 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
804 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
805 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
809 static BOOL init_format_vertex_info(WineD3D_GL_Info *gl_info)
813 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
815 struct GlPixelFormatDesc *format_desc;
816 int fmt_idx = getFmtIdx(format_vertex_info[i].format);
820 ERR("Format %s (%#x) not found.\n",
821 debug_d3dformat(format_vertex_info[i].format), format_vertex_info[i].format);
825 format_desc = &gl_info->gl_formats[fmt_idx];
826 format_desc->emit_idx = format_vertex_info[i].emit_idx;
827 format_desc->component_count = format_vertex_info[i].component_count;
828 format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
829 format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
830 format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
831 format_desc->component_size = format_vertex_info[i].component_size;
837 BOOL initPixelFormatsNoGL(WineD3D_GL_Info *gl_info)
839 if (!init_format_base_info(gl_info)) return FALSE;
841 if (!init_format_compression_info(gl_info))
843 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
850 BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
852 if (!init_format_base_info(gl_info)) return FALSE;
854 if (!init_format_compression_info(gl_info)) goto fail;
855 if (!init_format_texture_info(gl_info)) goto fail;
856 if (!init_format_vertex_info(gl_info)) goto fail;
858 apply_format_fixups(gl_info);
859 init_format_fbo_compat_info(gl_info);
864 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
868 #undef GLINFO_LOCATION
870 #define GLINFO_LOCATION This->adapter->gl_info
872 const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const WineD3D_GL_Info *gl_info)
874 int idx = getFmtIdx(fmt);
877 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
878 /* Get the caller a valid pointer */
879 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
882 return &gl_info->gl_formats[idx];
885 /*****************************************************************************
886 * Trace formatting of useful values
888 const char* debug_d3dformat(WINED3DFORMAT fmt) {
890 #define FMT_TO_STR(fmt) case fmt: return #fmt
891 FMT_TO_STR(WINED3DFMT_UNKNOWN);
892 FMT_TO_STR(WINED3DFMT_R8G8B8);
893 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
894 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
895 FMT_TO_STR(WINED3DFMT_R5G6B5);
896 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
897 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
898 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
899 FMT_TO_STR(WINED3DFMT_R3G3B2);
900 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
901 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
902 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
903 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
904 FMT_TO_STR(WINED3DFMT_A8P8);
905 FMT_TO_STR(WINED3DFMT_P8);
906 FMT_TO_STR(WINED3DFMT_L8);
907 FMT_TO_STR(WINED3DFMT_A8L8);
908 FMT_TO_STR(WINED3DFMT_A4L4);
909 FMT_TO_STR(WINED3DFMT_L6V5U5);
910 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
911 FMT_TO_STR(WINED3DFMT_W11V11U10);
912 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
913 FMT_TO_STR(WINED3DFMT_UYVY);
914 FMT_TO_STR(WINED3DFMT_YUY2);
915 FMT_TO_STR(WINED3DFMT_YV12);
916 FMT_TO_STR(WINED3DFMT_DXT1);
917 FMT_TO_STR(WINED3DFMT_DXT2);
918 FMT_TO_STR(WINED3DFMT_DXT3);
919 FMT_TO_STR(WINED3DFMT_DXT4);
920 FMT_TO_STR(WINED3DFMT_DXT5);
921 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
922 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
923 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
924 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
925 FMT_TO_STR(WINED3DFMT_D32);
926 FMT_TO_STR(WINED3DFMT_D15S1);
927 FMT_TO_STR(WINED3DFMT_D24S8);
928 FMT_TO_STR(WINED3DFMT_D24X8);
929 FMT_TO_STR(WINED3DFMT_D24X4S4);
930 FMT_TO_STR(WINED3DFMT_L16);
931 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
932 FMT_TO_STR(WINED3DFMT_D24FS8);
933 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
934 FMT_TO_STR(WINED3DFMT_CxV8U8);
935 FMT_TO_STR(WINED3DFMT_ATI2N);
936 FMT_TO_STR(WINED3DFMT_NVHU);
937 FMT_TO_STR(WINED3DFMT_NVHS);
938 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
939 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
940 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
941 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
942 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
943 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
944 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
945 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
946 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
947 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
948 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
949 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
950 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
951 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
952 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
953 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
954 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
955 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
956 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
957 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
958 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
959 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
960 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
961 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
962 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
963 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
964 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
965 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
966 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
967 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
968 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
969 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
970 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
971 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
972 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
973 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
974 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
975 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
976 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
977 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
978 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
979 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
980 FMT_TO_STR(WINED3DFMT_R32_UINT);
981 FMT_TO_STR(WINED3DFMT_R32_SINT);
982 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
983 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
984 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
985 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
986 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
987 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
988 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
989 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
990 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
991 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
992 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
993 FMT_TO_STR(WINED3DFMT_D16_UNORM);
994 FMT_TO_STR(WINED3DFMT_R16_UNORM);
995 FMT_TO_STR(WINED3DFMT_R16_UINT);
996 FMT_TO_STR(WINED3DFMT_R16_SNORM);
997 FMT_TO_STR(WINED3DFMT_R16_SINT);
998 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
999 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1000 FMT_TO_STR(WINED3DFMT_R8_UINT);
1001 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1002 FMT_TO_STR(WINED3DFMT_R8_SINT);
1003 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1004 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1005 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1006 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1007 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1008 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1009 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1010 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1011 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1012 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1013 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1014 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1015 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1016 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1017 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1018 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1019 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1020 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1021 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1022 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1023 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1024 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1025 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1026 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1031 fourcc[0] = (char)(fmt);
1032 fourcc[1] = (char)(fmt >> 8);
1033 fourcc[2] = (char)(fmt >> 16);
1034 fourcc[3] = (char)(fmt >> 24);
1036 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
1037 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
1039 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
1041 return "unrecognized";
1045 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
1047 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1048 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1049 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1050 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1051 #undef DEVTYPE_TO_STR
1053 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1054 return "unrecognized";
1058 const char *debug_d3dusage(DWORD usage)
1063 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1064 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1065 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1066 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1067 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1068 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1069 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1070 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1071 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1072 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1073 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1074 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1075 #undef WINED3DUSAGE_TO_STR
1076 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1078 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1081 const char *debug_d3dusagequery(DWORD usagequery)
1086 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1087 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1088 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1089 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1090 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1091 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1092 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1093 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1094 #undef WINED3DUSAGEQUERY_TO_STR
1095 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1097 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1100 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1102 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1103 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1104 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1105 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1106 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1107 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1108 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1109 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1110 #undef WINED3DDECLMETHOD_TO_STR
1112 FIXME("Unrecognized %u declaration method!\n", method);
1113 return "unrecognized";
1117 const char* debug_d3ddeclusage(BYTE usage) {
1119 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1120 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1121 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1122 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1123 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1124 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1125 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1126 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1127 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1128 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1129 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1130 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1131 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1132 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1133 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1134 #undef WINED3DDECLUSAGE_TO_STR
1136 FIXME("Unrecognized %u declaration usage!\n", usage);
1137 return "unrecognized";
1141 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1143 #define RES_TO_STR(res) case res: return #res
1144 RES_TO_STR(WINED3DRTYPE_SURFACE);
1145 RES_TO_STR(WINED3DRTYPE_VOLUME);
1146 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1147 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1148 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1149 RES_TO_STR(WINED3DRTYPE_BUFFER);
1152 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1153 return "unrecognized";
1157 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1158 switch (PrimitiveType) {
1159 #define PRIM_TO_STR(prim) case prim: return #prim
1160 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1161 PRIM_TO_STR(WINED3DPT_POINTLIST);
1162 PRIM_TO_STR(WINED3DPT_LINELIST);
1163 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1164 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1165 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1166 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1167 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1168 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1169 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1170 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1173 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1174 return "unrecognized";
1178 const char* debug_d3drenderstate(DWORD state) {
1180 #define D3DSTATE_TO_STR(u) case u: return #u
1181 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
1182 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1183 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
1184 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1185 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1186 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1187 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1188 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1189 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1190 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1191 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1192 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1193 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1194 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1195 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1196 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1197 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
1198 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
1199 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1200 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1201 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
1202 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1203 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1204 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1205 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1206 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1207 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1208 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1209 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1210 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1211 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1212 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1213 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1214 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1215 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1216 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1217 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1218 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1219 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1220 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1221 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1222 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
1223 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
1224 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
1225 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1226 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1227 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1228 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1229 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1230 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1231 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1232 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1233 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1234 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1235 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1236 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1237 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1238 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1239 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1240 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
1241 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
1242 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
1243 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
1244 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
1245 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
1246 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
1247 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
1248 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
1249 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
1250 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
1251 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
1252 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
1253 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
1254 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
1255 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
1256 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
1257 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
1258 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
1259 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
1260 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
1261 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
1262 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
1263 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
1264 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
1265 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
1266 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
1267 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
1268 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
1269 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
1270 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
1271 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
1272 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1273 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1274 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1275 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1276 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1277 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1278 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1279 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1280 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1281 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1282 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1283 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1284 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1285 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1286 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1287 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1288 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1289 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1290 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1291 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1292 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1293 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1294 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1295 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1296 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1297 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1298 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1299 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1300 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1301 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1302 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1303 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1304 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1305 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1306 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1307 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1308 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1309 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1310 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1311 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1312 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1313 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1314 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1315 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1316 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1317 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1318 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1319 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1320 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1321 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1322 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1323 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1324 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1325 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1326 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1327 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1328 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1329 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1330 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1331 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1332 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1333 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1334 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1335 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1336 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1337 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1338 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1339 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1340 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1341 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1342 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1343 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1344 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1345 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1346 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1347 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1348 #undef D3DSTATE_TO_STR
1350 FIXME("Unrecognized %u render state!\n", state);
1351 return "unrecognized";
1355 const char* debug_d3dsamplerstate(DWORD state) {
1357 #define D3DSTATE_TO_STR(u) case u: return #u
1358 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1359 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1360 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1361 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1362 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1363 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1364 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1365 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1366 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1367 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1368 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1369 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1370 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1371 #undef D3DSTATE_TO_STR
1373 FIXME("Unrecognized %u sampler state!\n", state);
1374 return "unrecognized";
1378 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1379 switch (filter_type) {
1380 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1381 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1382 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1383 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1384 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1385 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1386 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1387 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1388 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1389 #undef D3DTEXTUREFILTERTYPE_TO_STR
1391 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1392 return "unrecognized";
1396 const char* debug_d3dtexturestate(DWORD state) {
1398 #define D3DSTATE_TO_STR(u) case u: return #u
1399 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1400 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1401 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1402 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1403 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1404 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1405 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1406 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1407 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1408 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1409 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1410 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1411 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1412 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1413 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1414 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1415 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1416 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1417 #undef D3DSTATE_TO_STR
1419 FIXME("Unrecognized %u texture state!\n", state);
1420 return "unrecognized";
1424 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1426 #define D3DTOP_TO_STR(u) case u: return #u
1427 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1428 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1429 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1430 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1431 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1432 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1433 D3DTOP_TO_STR(WINED3DTOP_ADD);
1434 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1435 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1436 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1437 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1438 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1439 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1440 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1441 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1442 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1443 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1444 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1445 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1446 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1447 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1448 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1449 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1450 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1451 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1452 D3DTOP_TO_STR(WINED3DTOP_LERP);
1453 #undef D3DTOP_TO_STR
1455 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1456 return "unrecognized";
1460 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1462 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1463 TSTYPE_TO_STR(WINED3DTS_VIEW);
1464 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1465 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1466 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1467 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1468 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1469 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1470 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1471 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1472 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1473 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1474 #undef TSTYPE_TO_STR
1476 if (tstype > 256 && tstype < 512) {
1477 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1478 return ("WINED3DTS_WORLDMATRIX > 0");
1480 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1481 return "unrecognized";
1485 const char* debug_d3dpool(WINED3DPOOL Pool) {
1487 #define POOL_TO_STR(p) case p: return #p
1488 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1489 POOL_TO_STR(WINED3DPOOL_MANAGED);
1490 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1491 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1494 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1495 return "unrecognized";
1499 const char *debug_fbostatus(GLenum status) {
1501 #define FBOSTATUS_TO_STR(u) case u: return #u
1502 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1503 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1504 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1505 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1506 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1507 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1508 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1509 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
1510 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1511 #undef FBOSTATUS_TO_STR
1513 FIXME("Unrecognied FBO status 0x%08x\n", status);
1514 return "unrecognized";
1518 const char *debug_glerror(GLenum error) {
1520 #define GLERROR_TO_STR(u) case u: return #u
1521 GLERROR_TO_STR(GL_NO_ERROR);
1522 GLERROR_TO_STR(GL_INVALID_ENUM);
1523 GLERROR_TO_STR(GL_INVALID_VALUE);
1524 GLERROR_TO_STR(GL_INVALID_OPERATION);
1525 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1526 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1527 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1528 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1529 #undef GLERROR_TO_STR
1531 FIXME("Unrecognied GL error 0x%08x\n", error);
1532 return "unrecognized";
1536 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1538 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1539 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1540 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1541 default: return "unrecognized";
1545 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1547 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1548 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1549 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1550 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1551 default: return "unrecognized";
1555 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
1559 #define WINED3D_TO_STR(x) case x: return #x
1560 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1561 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1562 WINED3D_TO_STR(CHANNEL_SOURCE_X);
1563 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1564 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1565 WINED3D_TO_STR(CHANNEL_SOURCE_W);
1566 WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1567 WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1568 #undef WINED3D_TO_STR
1570 FIXME("Unrecognized fixup_channel_source %#x\n", source);
1571 return "unrecognized";
1575 static const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1579 #define WINED3D_TO_STR(x) case x: return #x
1580 WINED3D_TO_STR(YUV_FIXUP_YUY2);
1581 WINED3D_TO_STR(YUV_FIXUP_UYVY);
1582 WINED3D_TO_STR(YUV_FIXUP_YV12);
1583 #undef WINED3D_TO_STR
1585 FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1586 return "unrecognized";
1590 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1592 if (is_yuv_fixup(fixup))
1594 TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1598 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1599 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1600 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1601 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1604 const char *debug_surflocation(DWORD flag) {
1608 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
1609 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
1610 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
1611 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
1612 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
1615 /*****************************************************************************
1616 * Useful functions mapping GL <-> D3D values
1618 GLenum StencilOp(DWORD op) {
1620 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1621 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1622 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1623 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1624 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1625 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1626 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1627 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1629 FIXME("Unrecognized stencil op %d\n", op);
1634 GLenum CompareFunc(DWORD func) {
1635 switch ((WINED3DCMPFUNC)func) {
1636 case WINED3DCMP_NEVER : return GL_NEVER;
1637 case WINED3DCMP_LESS : return GL_LESS;
1638 case WINED3DCMP_EQUAL : return GL_EQUAL;
1639 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1640 case WINED3DCMP_GREATER : return GL_GREATER;
1641 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1642 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1643 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1645 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1650 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1651 if (op == WINED3DTOP_DISABLE) return FALSE;
1652 if (This->stateBlock->textures[stage]) return FALSE;
1654 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1655 && op != WINED3DTOP_SELECTARG2) return TRUE;
1656 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1657 && op != WINED3DTOP_SELECTARG1) return TRUE;
1658 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1659 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1664 /* Setup this textures matrix according to the texture flags*/
1665 /* GL locking is done by the caller (state handler) */
1666 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
1667 WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
1671 glMatrixMode(GL_TEXTURE);
1672 checkGLcall("glMatrixMode(GL_TEXTURE)");
1674 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1676 checkGLcall("glLoadIdentity()");
1680 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1681 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1685 memcpy(mat, smat, 16 * sizeof(float));
1687 if (flags & WINED3DTTFF_PROJECTED) {
1688 if(!ffp_proj_control) {
1689 switch (flags & ~WINED3DTTFF_PROJECTED) {
1690 case WINED3DTTFF_COUNT2:
1691 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1692 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1694 case WINED3DTTFF_COUNT3:
1695 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1696 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1700 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1701 if(!calculatedCoords) {
1704 case WINED3DFMT_R32_FLOAT:
1705 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1706 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1707 * the input value to the transformation will be 0, so the matrix value is irrelevant
1714 case WINED3DFMT_R32G32_FLOAT:
1715 /* See above, just 3rd and 4th coord
1722 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
1723 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
1725 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1726 * into a bad place. The division elimination below will apply to make sure the
1727 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1729 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
1732 FIXME("Unexpected fixed function texture coord input\n");
1735 if(!ffp_proj_control) {
1736 switch (flags & ~WINED3DTTFF_PROJECTED) {
1737 /* case WINED3DTTFF_COUNT1: Won't ever get here */
1738 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
1739 /* OpenGL divides the first 3 vertex coord by the 4th by default,
1740 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
1741 * the 4th coord evaluates to 1.0 to eliminate that.
1743 * If the fixed function pipeline is used, the 4th value remains unused,
1744 * so there is no danger in doing this. With vertex shaders we have a
1745 * problem. Should an app hit that problem, the code here would have to
1746 * check for pixel shaders, and the shader has to undo the default gl divide.
1748 * A more serious problem occurs if the app passes 4 coordinates in, and the
1749 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
1750 * or a replacement shader
1752 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
1758 checkGLcall("glLoadMatrixf(mat)");
1760 #undef GLINFO_LOCATION
1762 /* This small helper function is used to convert a bitmask into the number of masked bits */
1763 unsigned int count_bits(unsigned int mask)
1766 for (count = 0; mask; ++count)
1773 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
1774 * The later function requires individual color components. */
1775 BOOL getColorBits(const struct GlPixelFormatDesc *format_desc,
1776 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
1778 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
1779 switch(format_desc->format)
1781 case WINED3DFMT_X8R8G8B8:
1782 case WINED3DFMT_R8G8B8:
1783 case WINED3DFMT_A8R8G8B8:
1784 case WINED3DFMT_R8G8B8A8_UNORM:
1785 case WINED3DFMT_A2R10G10B10:
1786 case WINED3DFMT_X1R5G5B5:
1787 case WINED3DFMT_A1R5G5B5:
1788 case WINED3DFMT_R5G6B5:
1789 case WINED3DFMT_X4R4G4B4:
1790 case WINED3DFMT_A4R4G4B4:
1791 case WINED3DFMT_R3G3B2:
1792 case WINED3DFMT_A8P8:
1796 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
1800 *redSize = count_bits(format_desc->red_mask);
1801 *greenSize = count_bits(format_desc->green_mask);
1802 *blueSize = count_bits(format_desc->blue_mask);
1803 *alphaSize = count_bits(format_desc->alpha_mask);
1804 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
1806 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
1807 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
1811 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
1812 BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize)
1814 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
1815 switch(format_desc->format)
1817 case WINED3DFMT_D16_LOCKABLE:
1818 case WINED3DFMT_D16_UNORM:
1819 case WINED3DFMT_D15S1:
1820 case WINED3DFMT_D24X8:
1821 case WINED3DFMT_D24X4S4:
1822 case WINED3DFMT_D24S8:
1823 case WINED3DFMT_D24FS8:
1824 case WINED3DFMT_D32:
1825 case WINED3DFMT_D32F_LOCKABLE:
1828 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
1832 *depthSize = format_desc->depth_size;
1833 *stencilSize = format_desc->stencil_size;
1835 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
1836 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
1840 /* DirectDraw stuff */
1841 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
1843 case 8: return WINED3DFMT_P8;
1844 case 15: return WINED3DFMT_X1R5G5B5;
1845 case 16: return WINED3DFMT_R5G6B5;
1846 case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
1847 case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
1848 default: return WINED3DFMT_UNKNOWN;
1852 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
1855 /* Now do the multiplication 'by hand'.
1856 I know that all this could be optimised, but this will be done later :-) */
1857 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);
1858 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);
1859 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);
1860 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);
1862 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);
1863 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);
1864 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);
1865 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);
1867 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);
1868 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);
1869 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);
1870 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);
1872 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);
1873 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);
1874 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);
1875 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);
1877 /* And copy the new matrix in the good storage.. */
1878 memcpy(dest, &temp, 16 * sizeof(float));
1881 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
1884 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
1886 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
1887 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
1888 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
1889 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
1890 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
1891 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
1892 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
1893 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
1894 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
1895 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
1896 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
1897 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
1898 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
1899 default: ERR("Unexpected position mask\n");
1901 for (i = 0; i < numTextures; i++) {
1902 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
1908 /***********************************************************************
1911 * Calculates the dimensions of the opengl texture used for blits.
1912 * Handled oversized opengl textures and updates the source rectangle
1916 * This: Surface to operate on
1917 * Rect: Requested rectangle
1920 * TRUE if the texture part can be loaded,
1923 *********************************************************************/
1924 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
1926 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
1927 int x1 = Rect->left, x2 = Rect->right;
1928 int y1 = Rect->top, y2 = Rect->bottom;
1929 GLint maxSize = GL_LIMITS(texture_size);
1931 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
1932 Rect->left, Rect->top, Rect->right, Rect->bottom);
1934 /* The sizes might be reversed */
1935 if(Rect->left > Rect->right) {
1939 if(Rect->top > Rect->bottom) {
1944 /* No oversized texture? This is easy */
1945 if(!(This->Flags & SFLAG_OVERSIZE)) {
1946 /* Which rect from the texture do I need? */
1947 if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
1948 glTexCoord[0] = (float) Rect->left;
1949 glTexCoord[2] = (float) Rect->top;
1950 glTexCoord[1] = (float) Rect->right;
1951 glTexCoord[3] = (float) Rect->bottom;
1953 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
1954 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
1955 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
1956 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
1961 /* Check if we can succeed at all */
1962 if( (x2 - x1) > maxSize ||
1963 (y2 - y1) > maxSize ) {
1964 TRACE("Requested rectangle is too large for gl\n");
1968 /* A part of the texture has to be picked. First, check if
1969 * some texture part is loaded already, if yes try to re-use it.
1970 * If the texture is dirty, or the part can't be used,
1971 * re-position the part to load
1973 if(This->Flags & SFLAG_INTEXTURE) {
1974 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
1975 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
1976 /* Ok, the rectangle is ok, re-use it */
1977 TRACE("Using existing gl Texture\n");
1979 /* Rectangle is not ok, dirtify the texture to reload it */
1980 TRACE("Dirtifying texture to force reload\n");
1981 This->Flags &= ~SFLAG_INTEXTURE;
1985 /* Now if we are dirty(no else if!) */
1986 if(!(This->Flags & SFLAG_INTEXTURE)) {
1987 /* Set the new rectangle. Use the following strategy:
1988 * 1) Use as big textures as possible.
1989 * 2) Place the texture part in the way that the requested
1990 * part is in the middle of the texture(well, almost)
1991 * 3) If the texture is moved over the edges of the
1992 * surface, replace it nicely
1993 * 4) If the coord is not limiting the texture size,
1994 * use the whole size
1996 if((This->pow2Width) > maxSize) {
1997 This->glRect.left = x1 - maxSize / 2;
1998 if(This->glRect.left < 0) {
1999 This->glRect.left = 0;
2001 This->glRect.right = This->glRect.left + maxSize;
2002 if(This->glRect.right > This->currentDesc.Width) {
2003 This->glRect.right = This->currentDesc.Width;
2004 This->glRect.left = This->glRect.right - maxSize;
2007 This->glRect.left = 0;
2008 This->glRect.right = This->pow2Width;
2011 if(This->pow2Height > maxSize) {
2012 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2013 if(This->glRect.top < 0) This->glRect.top = 0;
2014 This->glRect.bottom = This->glRect.left + maxSize;
2015 if(This->glRect.bottom > This->currentDesc.Height) {
2016 This->glRect.bottom = This->currentDesc.Height;
2017 This->glRect.top = This->glRect.bottom - maxSize;
2020 This->glRect.top = 0;
2021 This->glRect.bottom = This->pow2Height;
2023 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2024 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2027 /* Re-calculate the rect to draw */
2028 Rect->left -= This->glRect.left;
2029 Rect->right -= This->glRect.left;
2030 Rect->top -= This->glRect.top;
2031 Rect->bottom -= This->glRect.top;
2033 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2034 * or the pow2Width / pow2Height of the surface.
2036 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
2037 * as regular GL_TEXTURE_2D.
2039 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2040 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2041 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2042 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2046 #undef GLINFO_LOCATION
2048 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2049 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2053 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2055 /* D3DTOP_DISABLE */ 0,
2056 /* D3DTOP_SELECTARG1 */ ARG1,
2057 /* D3DTOP_SELECTARG2 */ ARG2,
2058 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2059 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2060 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2061 /* D3DTOP_ADD */ ARG1 | ARG2,
2062 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2063 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2064 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2065 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2066 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2067 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2068 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2069 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2070 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2071 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2072 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2073 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2074 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2075 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2076 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2077 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2078 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2079 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2080 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2084 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2086 for(i = 0; i < GL_LIMITS(texture_stages); i++) {
2087 IWineD3DBaseTextureImpl *texture;
2088 settings->op[i].padding = 0;
2089 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2090 settings->op[i].cop = WINED3DTOP_DISABLE;
2091 settings->op[i].aop = WINED3DTOP_DISABLE;
2092 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2093 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2094 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2095 settings->op[i].dst = resultreg;
2096 settings->op[i].tex_type = tex_1d;
2097 settings->op[i].projected = proj_none;
2102 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2104 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2105 if(ignore_textype) {
2106 settings->op[i].tex_type = tex_1d;
2108 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2110 settings->op[i].tex_type = tex_1d;
2113 settings->op[i].tex_type = tex_2d;
2116 settings->op[i].tex_type = tex_3d;
2118 case GL_TEXTURE_CUBE_MAP_ARB:
2119 settings->op[i].tex_type = tex_cube;
2121 case GL_TEXTURE_RECTANGLE_ARB:
2122 settings->op[i].tex_type = tex_rect;
2127 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2128 settings->op[i].tex_type = tex_1d;
2131 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2132 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2134 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2135 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2136 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2138 if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
2139 carg1, carg2, carg0)) {
2142 carg1 = WINED3DTA_CURRENT;
2143 cop = WINED3DTOP_SELECTARG1;
2146 if(cop == WINED3DTOP_DOTPRODUCT3) {
2147 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2148 * the color result to the alpha component of the destination
2155 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2156 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2157 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2160 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2162 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2164 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2166 IWineD3DSurfaceImpl *surf;
2167 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2169 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2171 if (aop == WINED3DTOP_DISABLE)
2173 aarg1 = WINED3DTA_TEXTURE;
2174 aop = WINED3DTOP_SELECTARG1;
2176 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2178 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2180 aarg2 = WINED3DTA_TEXTURE;
2181 aop = WINED3DTOP_MODULATE;
2183 else aarg1 = WINED3DTA_TEXTURE;
2185 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2187 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2189 aarg1 = WINED3DTA_TEXTURE;
2190 aop = WINED3DTOP_MODULATE;
2192 else aarg2 = WINED3DTA_TEXTURE;
2198 if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
2199 aarg1, aarg2, aarg0)) {
2202 aarg1 = WINED3DTA_CURRENT;
2203 aop = WINED3DTOP_SELECTARG1;
2206 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2207 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2208 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2209 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2210 settings->op[i].projected = proj_count3;
2211 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2212 settings->op[i].projected = proj_count4;
2214 settings->op[i].projected = proj_none;
2217 settings->op[i].projected = proj_none;
2220 settings->op[i].cop = cop;
2221 settings->op[i].aop = aop;
2222 settings->op[i].carg0 = carg0;
2223 settings->op[i].carg1 = carg1;
2224 settings->op[i].carg2 = carg2;
2225 settings->op[i].aarg0 = aarg0;
2226 settings->op[i].aarg1 = aarg1;
2227 settings->op[i].aarg2 = aarg2;
2229 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2230 settings->op[i].dst = tempreg;
2232 settings->op[i].dst = resultreg;
2236 /* Clear unsupported stages */
2237 for(; i < MAX_TEXTURES; i++) {
2238 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2241 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2242 settings->fog = FOG_OFF;
2243 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2244 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2245 settings->fog = FOG_LINEAR;
2247 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2248 case WINED3DFOG_NONE:
2249 case WINED3DFOG_LINEAR:
2250 settings->fog = FOG_LINEAR;
2252 case WINED3DFOG_EXP:
2253 settings->fog = FOG_EXP;
2255 case WINED3DFOG_EXP2:
2256 settings->fog = FOG_EXP2;
2261 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2262 case WINED3DFOG_LINEAR:
2263 settings->fog = FOG_LINEAR;
2265 case WINED3DFOG_EXP:
2266 settings->fog = FOG_EXP;
2268 case WINED3DFOG_EXP2:
2269 settings->fog = FOG_EXP2;
2273 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2274 settings->sRGB_write = 1;
2276 settings->sRGB_write = 0;
2279 #undef GLINFO_LOCATION
2281 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2282 const struct ffp_frag_settings *settings)
2284 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2285 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2288 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2290 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2291 * whereas desc points to an extended structure with implementation specific parts. */
2292 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2294 ERR("Failed to insert ffp frag shader.\n");
2298 /* Activates the texture dimension according to the bound D3D texture.
2299 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2300 * Requires the caller to activate the correct unit before
2302 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2303 /* GL locking is done by the caller (state handler) */
2304 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2305 if(stateblock->textures[stage]) {
2306 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2308 glDisable(GL_TEXTURE_3D);
2309 checkGLcall("glDisable(GL_TEXTURE_3D)");
2310 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2311 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2312 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2314 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2315 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2316 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2318 glEnable(GL_TEXTURE_2D);
2319 checkGLcall("glEnable(GL_TEXTURE_2D)");
2321 case GL_TEXTURE_RECTANGLE_ARB:
2322 glDisable(GL_TEXTURE_2D);
2323 checkGLcall("glDisable(GL_TEXTURE_2D)");
2324 glDisable(GL_TEXTURE_3D);
2325 checkGLcall("glDisable(GL_TEXTURE_3D)");
2326 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2327 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2328 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2330 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2331 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2334 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2335 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2336 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2338 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2339 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2340 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2342 glDisable(GL_TEXTURE_2D);
2343 checkGLcall("glDisable(GL_TEXTURE_2D)");
2344 glEnable(GL_TEXTURE_3D);
2345 checkGLcall("glEnable(GL_TEXTURE_3D)");
2347 case GL_TEXTURE_CUBE_MAP_ARB:
2348 glDisable(GL_TEXTURE_2D);
2349 checkGLcall("glDisable(GL_TEXTURE_2D)");
2350 glDisable(GL_TEXTURE_3D);
2351 checkGLcall("glDisable(GL_TEXTURE_3D)");
2352 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2353 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2354 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2356 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2357 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2361 glEnable(GL_TEXTURE_2D);
2362 checkGLcall("glEnable(GL_TEXTURE_2D)");
2363 glDisable(GL_TEXTURE_3D);
2364 checkGLcall("glDisable(GL_TEXTURE_3D)");
2365 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2366 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2367 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2369 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2370 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2371 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2373 /* Binding textures is done by samplers. A dummy texture will be bound */
2377 /* GL locking is done by the caller (state handler) */
2378 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2379 DWORD sampler = state - STATE_SAMPLER(0);
2380 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2382 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2383 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2384 * will take care of this business
2386 if(mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= GL_LIMITS(textures)) return;
2387 if(sampler >= stateblock->lowest_disabled_stage) return;
2388 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2390 texture_activate_dimensions(sampler, stateblock, context);
2392 #undef GLINFO_LOCATION
2394 void *wined3d_rb_alloc(size_t size)
2396 return HeapAlloc(GetProcessHeap(), 0, size);
2399 void *wined3d_rb_realloc(void *ptr, size_t size)
2401 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
2404 void wined3d_rb_free(void *ptr)
2406 HeapFree(GetProcessHeap(), 0, ptr);
2409 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
2411 const struct ffp_frag_settings *ka = key;
2412 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
2414 return memcmp(ka, kb, sizeof(*ka));
2417 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
2422 ffp_frag_program_key_compare,
2425 UINT wined3d_log2i(UINT32 x)
2427 static const BYTE l[] =
2429 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2430 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2431 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2432 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2433 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2434 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2435 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2436 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2437 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2438 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2439 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2440 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2441 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2442 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2443 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2444 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2448 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];