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, 0xb0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
95 {WINED3DFMT_R10G10B10A2_UINT, 0xb0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
96 {WINED3DFMT_R10G10B10A2_SNORM, 0xb0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
97 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
98 {WINED3DFMT_R8G8B8A8_UINT, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
99 {WINED3DFMT_X8B8G8R8, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
100 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0, FALSE},
101 {WINED3DFMT_A2R10G10B10, 0xb0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0, FALSE},
102 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0, FALSE},
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_vertex_info
139 WINED3DFORMAT format;
140 enum wined3d_ffp_emit_idx emit_idx;
141 GLint component_count;
144 GLboolean gl_normalized;
145 unsigned int component_size;
148 static const struct wined3d_format_vertex_info format_vertex_info[] =
150 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
151 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
152 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
153 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
154 {WINED3DFMT_A8R8G8B8, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
155 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
156 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
157 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
158 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
159 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
160 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
161 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
162 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
163 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
164 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
165 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
166 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
171 GLint glInternal, glGammaInternal, rtInternal, glFormat, glType;
173 } GlPixelFormatDescTemplate;
175 /*****************************************************************************
176 * OpenGL format template. Contains unexciting formats which do not need
177 * extension checks. The order in this table is independent of the order in
178 * the table StaticPixelFormatDesc above. Not all formats have to be in this
181 static const GlPixelFormatDescTemplate gl_formats_template[] = {
182 /* WINED3DFORMAT internal srgbInternal rtInternal
185 {WINED3DFMT_UNKNOWN, 0, 0, 0,
189 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
190 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
191 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
192 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
195 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
196 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE,
197 WINED3DFMT_FLAG_FILTERING},
198 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
199 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE,
200 WINED3DFMT_FLAG_FILTERING},
201 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
202 GL_ALPHA, GL_UNSIGNED_BYTE,
203 WINED3DFMT_FLAG_FILTERING},
204 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
205 GL_RGBA, GL_UNSIGNED_BYTE,
206 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
207 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
208 GL_RGBA, GL_UNSIGNED_BYTE,
209 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
210 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
211 GL_RGBA, GL_UNSIGNED_BYTE,
212 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
213 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
214 GL_RGBA, GL_UNSIGNED_BYTE,
215 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
216 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
217 GL_RGBA, GL_UNSIGNED_BYTE,
218 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
219 {WINED3DFMT_MULTI2_ARGB8, 0, 0, 0,
222 {WINED3DFMT_G8R8_G8B8, 0, 0, 0,
225 {WINED3DFMT_R8G8_B8G8, 0, 0, 0,
229 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
231 WINED3DFMT_FLAG_RENDERTARGET},
232 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
234 WINED3DFMT_FLAG_RENDERTARGET},
235 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
237 WINED3DFMT_FLAG_RENDERTARGET},
239 {WINED3DFMT_CxV8U8, 0, 0, 0,
243 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
244 GL_RED, GL_HALF_FLOAT_ARB,
245 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
246 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
247 GL_RG, GL_HALF_FLOAT_ARB,
248 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
249 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
250 GL_RGBA, GL_HALF_FLOAT_ARB,
251 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
252 /* Palettized formats */
253 {WINED3DFMT_A8P8, 0, 0, 0,
256 {WINED3DFMT_P8, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
257 GL_COLOR_INDEX, GL_UNSIGNED_BYTE,
259 /* Standard ARGB formats */
260 {WINED3DFMT_R8G8B8, GL_RGB8, GL_RGB8, 0,
261 GL_BGR, GL_UNSIGNED_BYTE,
262 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
263 {WINED3DFMT_A8R8G8B8, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
264 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
265 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
266 {WINED3DFMT_X8R8G8B8, GL_RGB8, GL_SRGB8_EXT, 0,
267 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
268 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
269 {WINED3DFMT_R5G6B5, GL_RGB5, GL_RGB5, GL_RGB8,
270 GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
271 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
272 {WINED3DFMT_X1R5G5B5, GL_RGB5, GL_RGB5_A1, 0,
273 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
274 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
275 {WINED3DFMT_A1R5G5B5, GL_RGB5_A1, GL_RGB5_A1, 0,
276 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
277 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
278 {WINED3DFMT_A4R4G4B4, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
279 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
280 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
281 {WINED3DFMT_R3G3B2, GL_R3_G3_B2, GL_R3_G3_B2, 0,
282 GL_RGB, GL_UNSIGNED_BYTE_3_3_2,
283 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING},
284 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
285 GL_ALPHA, GL_UNSIGNED_BYTE,
286 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING},
287 {WINED3DFMT_A8R3G3B2, 0, 0, 0,
290 {WINED3DFMT_X4R4G4B4, GL_RGB4, GL_RGB4, 0,
291 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
292 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
293 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
294 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV,
295 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
296 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
297 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
298 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
299 {WINED3DFMT_X8B8G8R8, GL_RGB8, GL_RGB8, 0,
300 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
301 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
302 {WINED3DFMT_R16G16_UNORM, GL_RGB16_EXT, GL_RGB16_EXT, 0,
303 GL_RGB, GL_UNSIGNED_SHORT,
304 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
305 {WINED3DFMT_A2R10G10B10, GL_RGB10_A2, GL_RGB10_A2, 0,
306 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV,
307 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
308 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16_EXT, GL_RGBA16_EXT, 0,
309 GL_RGBA, GL_UNSIGNED_SHORT,
310 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
312 {WINED3DFMT_L8, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
313 GL_LUMINANCE, GL_UNSIGNED_BYTE,
314 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
315 {WINED3DFMT_A8L8, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
316 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
317 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
318 {WINED3DFMT_A4L4, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
319 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
321 /* Bump mapping stuff */
322 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
324 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
325 {WINED3DFMT_L6V5U5, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
326 GL_DSDT_MAG_NV, GL_BYTE,
327 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
328 {WINED3DFMT_X8L8V8U8, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
329 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV,
330 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
331 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
333 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
334 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
335 GL_HILO_NV, GL_SHORT,
336 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
337 {WINED3DFMT_W11V11U10, 0, 0, 0,
340 {WINED3DFMT_A2W10V10U10, 0, 0, 0,
343 /* Depth stencil formats */
344 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
345 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
346 WINED3DFMT_FLAG_DEPTH},
347 {WINED3DFMT_D32, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
348 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
349 WINED3DFMT_FLAG_DEPTH},
350 {WINED3DFMT_D15S1, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
351 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
352 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
353 {WINED3DFMT_D24S8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
354 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
355 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
356 {WINED3DFMT_D24X8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
357 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
358 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH},
359 {WINED3DFMT_D24X4S4, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
360 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
361 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
362 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
363 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
364 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH},
365 {WINED3DFMT_L16, GL_LUMINANCE16_EXT, GL_LUMINANCE16_EXT, 0,
366 GL_LUMINANCE, GL_UNSIGNED_SHORT,
367 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
368 {WINED3DFMT_D32F_LOCKABLE, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
369 GL_DEPTH_COMPONENT, GL_FLOAT,
370 WINED3DFMT_FLAG_DEPTH},
371 {WINED3DFMT_D24FS8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
372 GL_DEPTH_COMPONENT, GL_FLOAT,
373 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
374 /* Is this a vertex buffer? */
375 {WINED3DFMT_VERTEXDATA, 0, 0, 0,
378 {WINED3DFMT_R16_UINT, 0, 0, 0,
381 {WINED3DFMT_R32_UINT, 0, 0, 0,
384 {WINED3DFMT_R16G16B16A16_SNORM, GL_COLOR_INDEX, GL_COLOR_INDEX, 0,
385 GL_COLOR_INDEX, GL_UNSIGNED_SHORT,
387 /* Vendor-specific formats */
388 {WINED3DFMT_ATI2N, 0, 0, 0,
389 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
391 {WINED3DFMT_NVHU, 0, 0, 0,
392 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
394 {WINED3DFMT_NVHS, 0, 0, 0,
395 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
399 static inline int getFmtIdx(WINED3DFORMAT fmt) {
400 /* First check if the format is at the position of its value.
401 * This will catch the argb formats before the loop is entered
403 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
407 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
408 if(formats[i].format == fmt) {
416 static BOOL init_format_base_info(WineD3D_GL_Info *gl_info)
418 UINT format_count = sizeof(formats) / sizeof(*formats);
421 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->gl_formats));
422 if (!gl_info->gl_formats)
424 ERR("Failed to allocate memory.\n");
428 for (i = 0; i < format_count; ++i)
430 struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
431 desc->format = formats[i].format;
432 desc->red_mask = formats[i].redMask;
433 desc->green_mask = formats[i].greenMask;
434 desc->blue_mask = formats[i].blueMask;
435 desc->alpha_mask = formats[i].alphaMask;
436 desc->byte_count = formats[i].bpp;
437 desc->depth_size = formats[i].depthSize;
438 desc->stencil_size = formats[i].stencilSize;
439 if (formats[i].isFourcc) desc->Flags |= WINED3DFMT_FLAG_FOURCC;
445 #define GLINFO_LOCATION (*gl_info)
447 static BOOL check_fbo_compat(const WineD3D_GL_Info *gl_info, GLint internal_format)
453 glGenTextures(1, &tex);
454 glBindTexture(GL_TEXTURE_2D, tex);
455 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
457 GL_EXTCALL(glGenFramebuffersEXT(1, &fb));
458 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb));
459 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
461 status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
462 GL_EXTCALL(glDeleteFramebuffersEXT(1, &fb));
463 glDeleteTextures(1, &tex);
465 checkGLcall("Framebuffer format check");
467 return status == GL_FRAMEBUFFER_COMPLETE_EXT;
470 static BOOL init_format_texture_info(WineD3D_GL_Info *gl_info)
474 for (i = 0; i < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); ++i)
476 int fmt_idx = getFmtIdx(gl_formats_template[i].fmt);
477 struct GlPixelFormatDesc *desc;
481 ERR("Format %s (%#x) not found.\n",
482 debug_d3dformat(gl_formats_template[i].fmt), gl_formats_template[i].fmt);
486 desc = &gl_info->gl_formats[fmt_idx];
487 desc->glInternal = gl_formats_template[i].glInternal;
488 desc->glGammaInternal = gl_formats_template[i].glGammaInternal;
489 desc->glFormat = gl_formats_template[i].glFormat;
490 desc->glType = gl_formats_template[i].glType;
491 desc->color_fixup = COLOR_FIXUP_IDENTITY;
492 desc->Flags |= gl_formats_template[i].Flags;
493 desc->heightscale = 1.0;
495 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && gl_formats_template[i].rtInternal)
497 /* Check if the default internal format is supported as a frame buffer target, otherwise
498 * fall back to the render target internal.
500 * Try to stick to the standard format if possible, this limits precision differences */
501 if (!check_fbo_compat(gl_info, gl_formats_template[i].glInternal))
503 TRACE("Internal format of %s not supported as FBO target, using render target internal instead\n",
504 debug_d3dformat(gl_formats_template[i].fmt));
505 desc->rtInternal = gl_formats_template[i].rtInternal;
509 TRACE("Format %s is supported as fbo target\n", debug_d3dformat(gl_formats_template[i].fmt));
510 desc->rtInternal = gl_formats_template[i].glInternal;
515 desc->rtInternal = gl_formats_template[i].glInternal;
522 static void apply_format_fixups(WineD3D_GL_Info *gl_info)
526 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
527 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
528 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
529 /* When ARB_texture_rg is supported we only require 16-bit for R16F instead of 64-bit RGBA16F */
530 if (GL_SUPPORT(ARB_TEXTURE_RG))
532 gl_info->gl_formats[idx].glInternal = GL_R16F;
533 gl_info->gl_formats[idx].glGammaInternal = GL_R16F;
536 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
537 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
538 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
539 /* When ARB_texture_rg is supported we only require 32-bit for R32F instead of 128-bit RGBA32F */
540 if (GL_SUPPORT(ARB_TEXTURE_RG))
542 gl_info->gl_formats[idx].glInternal = GL_R32F;
543 gl_info->gl_formats[idx].glGammaInternal = GL_R32F;
546 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
547 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
548 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
550 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
551 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
552 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
554 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
555 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
556 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
558 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
559 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
560 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
561 * the only driver that implements it(fglrx) has a buggy implementation.
563 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
564 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
565 * conversion for this format.
567 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
569 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
570 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
571 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
572 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
573 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
574 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
578 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
579 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
580 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
581 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
582 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
583 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
586 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
588 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
591 idx = getFmtIdx(WINED3DFMT_L6V5U5);
592 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
593 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
594 idx = getFmtIdx(WINED3DFMT_X8L8V8U8);
595 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
596 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
597 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
598 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
599 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
603 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
604 * are converted at surface loading time, but they do not need any modification in
605 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
606 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
610 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC))
612 idx = getFmtIdx(WINED3DFMT_ATI2N);
613 gl_info->gl_formats[idx].glInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
614 gl_info->gl_formats[idx].glGammaInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
615 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
616 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
618 else if (GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC))
620 idx = getFmtIdx(WINED3DFMT_ATI2N);
621 gl_info->gl_formats[idx].glInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
622 gl_info->gl_formats[idx].glGammaInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
623 gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
624 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
627 if (!GL_SUPPORT(APPLE_YCBCR_422))
629 idx = getFmtIdx(WINED3DFMT_YUY2);
630 gl_info->gl_formats[idx].glInternal = GL_LUMINANCE_ALPHA;
631 gl_info->gl_formats[idx].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
632 gl_info->gl_formats[idx].glFormat = GL_LUMINANCE_ALPHA;
633 gl_info->gl_formats[idx].glType = GL_UNSIGNED_BYTE;
634 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
636 idx = getFmtIdx(WINED3DFMT_UYVY);
637 gl_info->gl_formats[idx].glInternal = GL_LUMINANCE_ALPHA;
638 gl_info->gl_formats[idx].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
639 gl_info->gl_formats[idx].glFormat = GL_LUMINANCE_ALPHA;
640 gl_info->gl_formats[idx].glType = GL_UNSIGNED_BYTE;
641 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
644 idx = getFmtIdx(WINED3DFMT_YV12);
645 gl_info->gl_formats[idx].heightscale = 1.5;
646 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
648 if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
650 idx = getFmtIdx(WINED3DFMT_A8R8G8B8);
651 gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
654 if (GL_SUPPORT(NV_HALF_FLOAT))
656 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
657 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
658 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
659 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT_NV;
661 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
662 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT_NV;
666 static BOOL init_format_vertex_info(WineD3D_GL_Info *gl_info)
670 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
672 struct GlPixelFormatDesc *format_desc;
673 int fmt_idx = getFmtIdx(format_vertex_info[i].format);
677 ERR("Format %s (%#x) not found.\n",
678 debug_d3dformat(format_vertex_info[i].format), format_vertex_info[i].format);
682 format_desc = &gl_info->gl_formats[fmt_idx];
683 format_desc->emit_idx = format_vertex_info[i].emit_idx;
684 format_desc->component_count = format_vertex_info[i].component_count;
685 format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
686 format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
687 format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
688 format_desc->component_size = format_vertex_info[i].component_size;
694 BOOL initPixelFormatsNoGL(WineD3D_GL_Info *gl_info)
696 return init_format_base_info(gl_info);
699 BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
701 if (!init_format_base_info(gl_info)) return FALSE;
703 if (!init_format_texture_info(gl_info))
705 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
709 if (!init_format_vertex_info(gl_info))
711 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
715 apply_format_fixups(gl_info);
720 #undef GLINFO_LOCATION
722 #define GLINFO_LOCATION This->adapter->gl_info
724 const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const WineD3D_GL_Info *gl_info)
726 int idx = getFmtIdx(fmt);
729 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
730 /* Get the caller a valid pointer */
731 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
734 return &gl_info->gl_formats[idx];
737 /*****************************************************************************
738 * Trace formatting of useful values
740 const char* debug_d3dformat(WINED3DFORMAT fmt) {
742 #define FMT_TO_STR(fmt) case fmt: return #fmt
743 FMT_TO_STR(WINED3DFMT_UNKNOWN);
744 FMT_TO_STR(WINED3DFMT_R8G8B8);
745 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
746 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
747 FMT_TO_STR(WINED3DFMT_R5G6B5);
748 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
749 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
750 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
751 FMT_TO_STR(WINED3DFMT_R3G3B2);
752 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
753 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
754 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
755 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
756 FMT_TO_STR(WINED3DFMT_A8P8);
757 FMT_TO_STR(WINED3DFMT_P8);
758 FMT_TO_STR(WINED3DFMT_L8);
759 FMT_TO_STR(WINED3DFMT_A8L8);
760 FMT_TO_STR(WINED3DFMT_A4L4);
761 FMT_TO_STR(WINED3DFMT_L6V5U5);
762 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
763 FMT_TO_STR(WINED3DFMT_W11V11U10);
764 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
765 FMT_TO_STR(WINED3DFMT_UYVY);
766 FMT_TO_STR(WINED3DFMT_YUY2);
767 FMT_TO_STR(WINED3DFMT_YV12);
768 FMT_TO_STR(WINED3DFMT_DXT1);
769 FMT_TO_STR(WINED3DFMT_DXT2);
770 FMT_TO_STR(WINED3DFMT_DXT3);
771 FMT_TO_STR(WINED3DFMT_DXT4);
772 FMT_TO_STR(WINED3DFMT_DXT5);
773 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
774 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
775 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
776 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
777 FMT_TO_STR(WINED3DFMT_D32);
778 FMT_TO_STR(WINED3DFMT_D15S1);
779 FMT_TO_STR(WINED3DFMT_D24S8);
780 FMT_TO_STR(WINED3DFMT_D24X8);
781 FMT_TO_STR(WINED3DFMT_D24X4S4);
782 FMT_TO_STR(WINED3DFMT_L16);
783 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
784 FMT_TO_STR(WINED3DFMT_D24FS8);
785 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
786 FMT_TO_STR(WINED3DFMT_CxV8U8);
787 FMT_TO_STR(WINED3DFMT_ATI2N);
788 FMT_TO_STR(WINED3DFMT_NVHU);
789 FMT_TO_STR(WINED3DFMT_NVHS);
790 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
791 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
792 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
793 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
794 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
795 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
796 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
797 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
798 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
799 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
800 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
801 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
802 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
803 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
804 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
805 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
806 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
807 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
808 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
809 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
810 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
811 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
812 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
813 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
814 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
815 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
816 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
817 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
818 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
819 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
820 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
821 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
822 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
823 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
824 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
825 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
826 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
827 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
828 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
829 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
830 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
831 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
832 FMT_TO_STR(WINED3DFMT_R32_UINT);
833 FMT_TO_STR(WINED3DFMT_R32_SINT);
834 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
835 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
836 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
837 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
838 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
839 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
840 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
841 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
842 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
843 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
844 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
845 FMT_TO_STR(WINED3DFMT_D16_UNORM);
846 FMT_TO_STR(WINED3DFMT_R16_UNORM);
847 FMT_TO_STR(WINED3DFMT_R16_UINT);
848 FMT_TO_STR(WINED3DFMT_R16_SNORM);
849 FMT_TO_STR(WINED3DFMT_R16_SINT);
850 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
851 FMT_TO_STR(WINED3DFMT_R8_UNORM);
852 FMT_TO_STR(WINED3DFMT_R8_UINT);
853 FMT_TO_STR(WINED3DFMT_R8_SNORM);
854 FMT_TO_STR(WINED3DFMT_R8_SINT);
855 FMT_TO_STR(WINED3DFMT_A8_UNORM);
856 FMT_TO_STR(WINED3DFMT_R1_UNORM);
857 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
858 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
859 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
860 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
861 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
862 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
863 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
864 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
865 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
866 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
867 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
868 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
869 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
870 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
871 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
872 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
873 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
874 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
875 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
876 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
877 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
878 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
883 fourcc[0] = (char)(fmt);
884 fourcc[1] = (char)(fmt >> 8);
885 fourcc[2] = (char)(fmt >> 16);
886 fourcc[3] = (char)(fmt >> 24);
888 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
889 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
891 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
893 return "unrecognized";
897 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
899 #define DEVTYPE_TO_STR(dev) case dev: return #dev
900 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
901 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
902 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
903 #undef DEVTYPE_TO_STR
905 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
906 return "unrecognized";
910 const char* debug_d3dusage(DWORD usage) {
911 switch (usage & WINED3DUSAGE_MASK) {
912 #define WINED3DUSAGE_TO_STR(u) case u: return #u
913 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
914 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
915 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
916 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
917 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
918 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
919 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
920 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
921 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
922 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
923 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
924 #undef WINED3DUSAGE_TO_STR
925 case 0: return "none";
927 FIXME("Unrecognized %u Usage!\n", usage);
928 return "unrecognized";
932 const char* debug_d3dusagequery(DWORD usagequery) {
933 switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
934 #define WINED3DUSAGEQUERY_TO_STR(u) case u: return #u
935 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
936 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
937 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
938 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
939 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
940 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
941 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
942 #undef WINED3DUSAGEQUERY_TO_STR
943 case 0: return "none";
945 FIXME("Unrecognized %u Usage Query!\n", usagequery);
946 return "unrecognized";
950 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
952 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
953 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
954 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
955 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
956 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
957 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
958 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
959 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
960 #undef WINED3DDECLMETHOD_TO_STR
962 FIXME("Unrecognized %u declaration method!\n", method);
963 return "unrecognized";
967 const char* debug_d3ddeclusage(BYTE usage) {
969 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
970 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
971 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
972 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
973 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
974 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
975 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
976 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
977 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
978 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
979 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
980 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
981 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
982 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
983 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
984 #undef WINED3DDECLUSAGE_TO_STR
986 FIXME("Unrecognized %u declaration usage!\n", usage);
987 return "unrecognized";
991 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
993 #define RES_TO_STR(res) case res: return #res
994 RES_TO_STR(WINED3DRTYPE_SURFACE);
995 RES_TO_STR(WINED3DRTYPE_VOLUME);
996 RES_TO_STR(WINED3DRTYPE_TEXTURE);
997 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
998 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
999 RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER);
1000 RES_TO_STR(WINED3DRTYPE_INDEXBUFFER);
1001 RES_TO_STR(WINED3DRTYPE_BUFFER);
1004 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1005 return "unrecognized";
1009 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1010 switch (PrimitiveType) {
1011 #define PRIM_TO_STR(prim) case prim: return #prim
1012 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1013 PRIM_TO_STR(WINED3DPT_POINTLIST);
1014 PRIM_TO_STR(WINED3DPT_LINELIST);
1015 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1016 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1017 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1018 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1019 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1020 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1021 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1022 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1025 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1026 return "unrecognized";
1030 const char* debug_d3drenderstate(DWORD state) {
1032 #define D3DSTATE_TO_STR(u) case u: return #u
1033 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
1034 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1035 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
1036 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1037 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1038 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1039 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1040 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1041 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1042 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1043 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1044 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1045 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1046 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1047 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1048 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1049 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
1050 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
1051 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1052 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1053 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
1054 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1055 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1056 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1057 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1058 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1059 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1060 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1061 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1062 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1063 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1064 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1065 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1066 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1067 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1068 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1069 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1070 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1071 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1072 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1073 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1074 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
1075 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
1076 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
1077 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1078 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1079 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1080 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1081 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1082 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1083 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1084 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1085 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1086 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1087 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1088 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1089 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1090 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1091 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1092 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
1093 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
1094 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
1095 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
1096 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
1097 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
1098 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
1099 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
1100 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
1101 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
1102 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
1103 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
1104 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
1105 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
1106 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
1107 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
1108 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
1109 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
1110 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
1111 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
1112 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
1113 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
1114 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
1115 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
1116 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
1117 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
1118 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
1119 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
1120 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
1121 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
1122 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
1123 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
1124 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1125 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1126 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1127 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1128 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1129 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1130 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1131 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1132 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1133 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1134 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1135 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1136 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1137 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1138 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1139 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1140 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1141 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1142 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1143 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1144 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1145 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1146 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1147 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1148 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1149 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1150 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1151 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1152 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1153 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1154 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1155 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1156 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1157 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1158 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1159 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1160 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1161 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1162 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1163 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1164 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1165 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1166 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1167 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1168 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1169 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1170 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1171 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1172 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1173 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1174 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1175 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1176 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1177 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1178 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1179 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1180 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1181 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1182 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1183 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1184 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1185 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1186 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1187 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1188 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1189 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1190 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1191 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1192 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1193 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1194 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1195 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1196 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1197 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1198 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1199 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1200 #undef D3DSTATE_TO_STR
1202 FIXME("Unrecognized %u render state!\n", state);
1203 return "unrecognized";
1207 const char* debug_d3dsamplerstate(DWORD state) {
1209 #define D3DSTATE_TO_STR(u) case u: return #u
1210 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1211 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1212 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1213 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1214 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1215 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1216 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1217 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1218 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1219 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1220 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1221 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1222 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1223 #undef D3DSTATE_TO_STR
1225 FIXME("Unrecognized %u sampler state!\n", state);
1226 return "unrecognized";
1230 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1231 switch (filter_type) {
1232 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1233 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1234 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1235 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1236 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1237 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1238 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1239 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1240 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1241 #undef D3DTEXTUREFILTERTYPE_TO_STR
1243 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1244 return "unrecognized";
1248 const char* debug_d3dtexturestate(DWORD state) {
1250 #define D3DSTATE_TO_STR(u) case u: return #u
1251 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1252 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1253 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1254 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1255 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1256 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1257 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1258 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1259 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1260 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1261 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1262 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1263 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1264 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1265 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1266 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1267 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1268 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1269 #undef D3DSTATE_TO_STR
1271 FIXME("Unrecognized %u texture state!\n", state);
1272 return "unrecognized";
1276 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1278 #define D3DTOP_TO_STR(u) case u: return #u
1279 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1280 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1281 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1282 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1283 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1284 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1285 D3DTOP_TO_STR(WINED3DTOP_ADD);
1286 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1287 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1288 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1289 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1290 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1291 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1292 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1293 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1294 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1295 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1296 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1297 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1298 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1299 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1300 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1301 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1302 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1303 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1304 D3DTOP_TO_STR(WINED3DTOP_LERP);
1305 #undef D3DTOP_TO_STR
1307 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1308 return "unrecognized";
1312 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1314 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1315 TSTYPE_TO_STR(WINED3DTS_VIEW);
1316 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1317 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1318 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1319 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1320 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1321 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1322 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1323 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1324 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1325 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1326 #undef TSTYPE_TO_STR
1328 if (tstype > 256 && tstype < 512) {
1329 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1330 return ("WINED3DTS_WORLDMATRIX > 0");
1332 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1333 return "unrecognized";
1337 const char* debug_d3dpool(WINED3DPOOL Pool) {
1339 #define POOL_TO_STR(p) case p: return #p
1340 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1341 POOL_TO_STR(WINED3DPOOL_MANAGED);
1342 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1343 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1346 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1347 return "unrecognized";
1351 const char *debug_fbostatus(GLenum status) {
1353 #define FBOSTATUS_TO_STR(u) case u: return #u
1354 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1355 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1356 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1357 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1358 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1359 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1360 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1361 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
1362 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1363 #undef FBOSTATUS_TO_STR
1365 FIXME("Unrecognied FBO status 0x%08x\n", status);
1366 return "unrecognized";
1370 const char *debug_glerror(GLenum error) {
1372 #define GLERROR_TO_STR(u) case u: return #u
1373 GLERROR_TO_STR(GL_NO_ERROR);
1374 GLERROR_TO_STR(GL_INVALID_ENUM);
1375 GLERROR_TO_STR(GL_INVALID_VALUE);
1376 GLERROR_TO_STR(GL_INVALID_OPERATION);
1377 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1378 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1379 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1380 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1381 #undef GLERROR_TO_STR
1383 FIXME("Unrecognied GL error 0x%08x\n", error);
1384 return "unrecognized";
1388 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1390 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1391 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1392 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1393 default: return "unrecognized";
1397 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1399 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1400 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1401 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1402 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1403 default: return "unrecognized";
1407 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
1411 #define WINED3D_TO_STR(x) case x: return #x
1412 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1413 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1414 WINED3D_TO_STR(CHANNEL_SOURCE_X);
1415 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1416 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1417 WINED3D_TO_STR(CHANNEL_SOURCE_W);
1418 WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1419 WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1420 #undef WINED3D_TO_STR
1422 FIXME("Unrecognized fixup_channel_source %#x\n", source);
1423 return "unrecognized";
1427 static const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1431 #define WINED3D_TO_STR(x) case x: return #x
1432 WINED3D_TO_STR(YUV_FIXUP_YUY2);
1433 WINED3D_TO_STR(YUV_FIXUP_UYVY);
1434 WINED3D_TO_STR(YUV_FIXUP_YV12);
1435 #undef WINED3D_TO_STR
1437 FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1438 return "unrecognized";
1442 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1444 if (is_yuv_fixup(fixup))
1446 TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1450 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1451 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1452 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1453 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1456 const char *debug_surflocation(DWORD flag) {
1460 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
1461 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
1462 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
1463 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
1464 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
1467 /*****************************************************************************
1468 * Useful functions mapping GL <-> D3D values
1470 GLenum StencilOp(DWORD op) {
1472 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1473 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1474 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1475 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1476 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1477 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1478 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1479 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1481 FIXME("Unrecognized stencil op %d\n", op);
1486 GLenum CompareFunc(DWORD func) {
1487 switch ((WINED3DCMPFUNC)func) {
1488 case WINED3DCMP_NEVER : return GL_NEVER;
1489 case WINED3DCMP_LESS : return GL_LESS;
1490 case WINED3DCMP_EQUAL : return GL_EQUAL;
1491 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1492 case WINED3DCMP_GREATER : return GL_GREATER;
1493 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1494 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1495 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1497 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1502 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1503 if (op == WINED3DTOP_DISABLE) return FALSE;
1504 if (This->stateBlock->textures[stage]) return FALSE;
1506 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1507 && op != WINED3DTOP_SELECTARG2) return TRUE;
1508 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1509 && op != WINED3DTOP_SELECTARG1) return TRUE;
1510 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1511 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1516 /* Setup this textures matrix according to the texture flags*/
1517 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
1518 WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
1522 glMatrixMode(GL_TEXTURE);
1523 checkGLcall("glMatrixMode(GL_TEXTURE)");
1525 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1527 checkGLcall("glLoadIdentity()");
1531 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1532 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1536 memcpy(mat, smat, 16 * sizeof(float));
1538 if (flags & WINED3DTTFF_PROJECTED) {
1539 if(!ffp_proj_control) {
1540 switch (flags & ~WINED3DTTFF_PROJECTED) {
1541 case WINED3DTTFF_COUNT2:
1542 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1543 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1545 case WINED3DTTFF_COUNT3:
1546 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1547 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1551 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1552 if(!calculatedCoords) {
1555 case WINED3DFMT_R32_FLOAT:
1556 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1557 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1558 * the input value to the transformation will be 0, so the matrix value is irrelevant
1565 case WINED3DFMT_R32G32_FLOAT:
1566 /* See above, just 3rd and 4th coord
1573 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
1574 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
1576 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1577 * into a bad place. The division elimination below will apply to make sure the
1578 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1580 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
1583 FIXME("Unexpected fixed function texture coord input\n");
1586 if(!ffp_proj_control) {
1587 switch (flags & ~WINED3DTTFF_PROJECTED) {
1588 /* case WINED3DTTFF_COUNT1: Won't ever get here */
1589 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
1590 /* OpenGL divides the first 3 vertex coord by the 4th by default,
1591 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
1592 * the 4th coord evaluates to 1.0 to eliminate that.
1594 * If the fixed function pipeline is used, the 4th value remains unused,
1595 * so there is no danger in doing this. With vertex shaders we have a
1596 * problem. Should an app hit that problem, the code here would have to
1597 * check for pixel shaders, and the shader has to undo the default gl divide.
1599 * A more serious problem occurs if the app passes 4 coordinates in, and the
1600 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
1601 * or a replacement shader
1603 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
1609 checkGLcall("glLoadMatrixf(mat)");
1611 #undef GLINFO_LOCATION
1613 /* This small helper function is used to convert a bitmask into the number of masked bits */
1614 unsigned int count_bits(unsigned int mask)
1617 for (count = 0; mask; ++count)
1624 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
1625 * The later function requires individual color components. */
1626 BOOL getColorBits(const struct GlPixelFormatDesc *format_desc,
1627 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
1629 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
1630 switch(format_desc->format)
1632 case WINED3DFMT_X8R8G8B8:
1633 case WINED3DFMT_R8G8B8:
1634 case WINED3DFMT_A8R8G8B8:
1635 case WINED3DFMT_R8G8B8A8_UNORM:
1636 case WINED3DFMT_A2R10G10B10:
1637 case WINED3DFMT_X1R5G5B5:
1638 case WINED3DFMT_A1R5G5B5:
1639 case WINED3DFMT_R5G6B5:
1640 case WINED3DFMT_X4R4G4B4:
1641 case WINED3DFMT_A4R4G4B4:
1642 case WINED3DFMT_R3G3B2:
1643 case WINED3DFMT_A8P8:
1647 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
1651 *redSize = count_bits(format_desc->red_mask);
1652 *greenSize = count_bits(format_desc->green_mask);
1653 *blueSize = count_bits(format_desc->blue_mask);
1654 *alphaSize = count_bits(format_desc->alpha_mask);
1655 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
1657 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
1658 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
1662 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
1663 BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize)
1665 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
1666 switch(format_desc->format)
1668 case WINED3DFMT_D16_LOCKABLE:
1669 case WINED3DFMT_D16_UNORM:
1670 case WINED3DFMT_D15S1:
1671 case WINED3DFMT_D24X8:
1672 case WINED3DFMT_D24X4S4:
1673 case WINED3DFMT_D24S8:
1674 case WINED3DFMT_D24FS8:
1675 case WINED3DFMT_D32:
1676 case WINED3DFMT_D32F_LOCKABLE:
1679 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
1683 *depthSize = format_desc->depth_size;
1684 *stencilSize = format_desc->stencil_size;
1686 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
1687 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
1691 /* DirectDraw stuff */
1692 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
1694 case 8: return WINED3DFMT_P8;
1695 case 15: return WINED3DFMT_X1R5G5B5;
1696 case 16: return WINED3DFMT_R5G6B5;
1697 case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
1698 case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
1699 default: return WINED3DFMT_UNKNOWN;
1703 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
1706 /* Now do the multiplication 'by hand'.
1707 I know that all this could be optimised, but this will be done later :-) */
1708 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);
1709 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);
1710 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);
1711 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);
1713 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);
1714 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);
1715 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);
1716 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);
1718 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);
1719 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);
1720 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);
1721 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);
1723 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);
1724 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);
1725 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);
1726 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);
1728 /* And copy the new matrix in the good storage.. */
1729 memcpy(dest, &temp, 16 * sizeof(float));
1732 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
1735 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
1737 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
1738 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
1739 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
1740 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
1741 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
1742 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
1743 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
1744 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
1745 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
1746 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
1747 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
1748 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
1749 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
1750 default: ERR("Unexpected position mask\n");
1752 for (i = 0; i < numTextures; i++) {
1753 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
1759 /***********************************************************************
1762 * Calculates the dimensions of the opengl texture used for blits.
1763 * Handled oversized opengl textures and updates the source rectangle
1767 * This: Surface to operate on
1768 * Rect: Requested rectangle
1771 * TRUE if the texture part can be loaded,
1774 *********************************************************************/
1775 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
1777 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
1778 int x1 = Rect->left, x2 = Rect->right;
1779 int y1 = Rect->top, y2 = Rect->bottom;
1780 GLint maxSize = GL_LIMITS(texture_size);
1782 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
1783 Rect->left, Rect->top, Rect->right, Rect->bottom);
1785 /* The sizes might be reversed */
1786 if(Rect->left > Rect->right) {
1790 if(Rect->top > Rect->bottom) {
1795 /* No oversized texture? This is easy */
1796 if(!(This->Flags & SFLAG_OVERSIZE)) {
1797 /* Which rect from the texture do I need? */
1798 if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
1799 glTexCoord[0] = (float) Rect->left;
1800 glTexCoord[2] = (float) Rect->top;
1801 glTexCoord[1] = (float) Rect->right;
1802 glTexCoord[3] = (float) Rect->bottom;
1804 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
1805 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
1806 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
1807 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
1812 /* Check if we can succeed at all */
1813 if( (x2 - x1) > maxSize ||
1814 (y2 - y1) > maxSize ) {
1815 TRACE("Requested rectangle is too large for gl\n");
1819 /* A part of the texture has to be picked. First, check if
1820 * some texture part is loaded already, if yes try to re-use it.
1821 * If the texture is dirty, or the part can't be used,
1822 * re-position the part to load
1824 if(This->Flags & SFLAG_INTEXTURE) {
1825 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
1826 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
1827 /* Ok, the rectangle is ok, re-use it */
1828 TRACE("Using existing gl Texture\n");
1830 /* Rectangle is not ok, dirtify the texture to reload it */
1831 TRACE("Dirtifying texture to force reload\n");
1832 This->Flags &= ~SFLAG_INTEXTURE;
1836 /* Now if we are dirty(no else if!) */
1837 if(!(This->Flags & SFLAG_INTEXTURE)) {
1838 /* Set the new rectangle. Use the following strategy:
1839 * 1) Use as big textures as possible.
1840 * 2) Place the texture part in the way that the requested
1841 * part is in the middle of the texture(well, almost)
1842 * 3) If the texture is moved over the edges of the
1843 * surface, replace it nicely
1844 * 4) If the coord is not limiting the texture size,
1845 * use the whole size
1847 if((This->pow2Width) > maxSize) {
1848 This->glRect.left = x1 - maxSize / 2;
1849 if(This->glRect.left < 0) {
1850 This->glRect.left = 0;
1852 This->glRect.right = This->glRect.left + maxSize;
1853 if(This->glRect.right > This->currentDesc.Width) {
1854 This->glRect.right = This->currentDesc.Width;
1855 This->glRect.left = This->glRect.right - maxSize;
1858 This->glRect.left = 0;
1859 This->glRect.right = This->pow2Width;
1862 if(This->pow2Height > maxSize) {
1863 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
1864 if(This->glRect.top < 0) This->glRect.top = 0;
1865 This->glRect.bottom = This->glRect.left + maxSize;
1866 if(This->glRect.bottom > This->currentDesc.Height) {
1867 This->glRect.bottom = This->currentDesc.Height;
1868 This->glRect.top = This->glRect.bottom - maxSize;
1871 This->glRect.top = 0;
1872 This->glRect.bottom = This->pow2Height;
1874 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
1875 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
1878 /* Re-calculate the rect to draw */
1879 Rect->left -= This->glRect.left;
1880 Rect->right -= This->glRect.left;
1881 Rect->top -= This->glRect.top;
1882 Rect->bottom -= This->glRect.top;
1884 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
1885 * or the pow2Width / pow2Height of the surface.
1887 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
1888 * as regular GL_TEXTURE_2D.
1890 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
1891 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
1892 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
1893 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
1897 #undef GLINFO_LOCATION
1899 /* Hash table functions */
1901 struct hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
1903 struct hash_table_t *table;
1904 unsigned int initial_size = 8;
1906 table = HeapAlloc(GetProcessHeap(), 0, sizeof(struct hash_table_t) + (initial_size * sizeof(struct list)));
1909 ERR("Failed to allocate table, returning NULL.\n");
1913 table->hash_function = hash_function;
1914 table->compare_function = compare_function;
1916 table->grow_size = initial_size - (initial_size >> 2);
1917 table->shrink_size = 0;
1919 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
1920 if (!table->buckets)
1922 ERR("Failed to allocate table buckets, returning NULL.\n");
1923 HeapFree(GetProcessHeap(), 0, table);
1926 table->bucket_count = initial_size;
1928 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(struct hash_table_entry_t));
1929 if (!table->entries)
1931 ERR("Failed to allocate table entries, returning NULL.\n");
1932 HeapFree(GetProcessHeap(), 0, table->buckets);
1933 HeapFree(GetProcessHeap(), 0, table);
1936 table->entry_count = 0;
1938 list_init(&table->free_entries);
1944 void hash_table_destroy(struct hash_table_t *table, void (*free_value)(void *value, void *cb), void *cb)
1948 for (i = 0; i < table->entry_count; ++i)
1951 free_value(table->entries[i].value, cb);
1953 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
1956 HeapFree(GetProcessHeap(), 0, table->entries);
1957 HeapFree(GetProcessHeap(), 0, table->buckets);
1958 HeapFree(GetProcessHeap(), 0, table);
1961 void hash_table_for_each_entry(struct hash_table_t *table, void (*callback)(void *value, void *context), void *context)
1965 for (i = 0; i < table->entry_count; ++i)
1967 callback(table->entries[i].value, context);
1971 static inline struct hash_table_entry_t *hash_table_get_by_idx(const struct hash_table_t *table, const void *key,
1974 struct hash_table_entry_t *entry;
1976 if (table->buckets[idx].next)
1977 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), struct hash_table_entry_t, entry)
1978 if (table->compare_function(entry->key, key)) return entry;
1983 static BOOL hash_table_resize(struct hash_table_t *table, unsigned int new_bucket_count)
1985 unsigned int new_entry_count = 0;
1986 struct hash_table_entry_t *new_entries;
1987 struct list *new_buckets;
1988 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
1991 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
1994 ERR("Failed to allocate new buckets, returning FALSE.\n");
1998 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(struct hash_table_entry_t));
2001 ERR("Failed to allocate new entries, returning FALSE.\n");
2002 HeapFree(GetProcessHeap(), 0, new_buckets);
2006 for (i = 0; i < table->bucket_count; ++i)
2008 if (table->buckets[i].next)
2010 struct hash_table_entry_t *entry, *entry2;
2012 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], struct hash_table_entry_t, entry)
2015 struct hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
2016 *new_entry = *entry;
2018 j = new_entry->hash & (new_bucket_count - 1);
2020 if (!new_buckets[j].next) list_init(&new_buckets[j]);
2021 list_add_head(&new_buckets[j], &new_entry->entry);
2026 HeapFree(GetProcessHeap(), 0, table->buckets);
2027 table->buckets = new_buckets;
2029 HeapFree(GetProcessHeap(), 0, table->entries);
2030 table->entries = new_entries;
2032 table->entry_count = new_entry_count;
2033 list_init(&table->free_entries);
2035 table->bucket_count = new_bucket_count;
2036 table->grow_size = grow_size;
2037 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
2042 void hash_table_put(struct hash_table_t *table, void *key, void *value)
2046 struct hash_table_entry_t *entry;
2048 hash = table->hash_function(key);
2049 idx = hash & (table->bucket_count - 1);
2050 entry = hash_table_get_by_idx(table, key, idx);
2054 HeapFree(GetProcessHeap(), 0, key);
2055 entry->value = value;
2059 HeapFree(GetProcessHeap(), 0, entry->key);
2062 /* Remove the entry */
2063 list_remove(&entry->entry);
2064 list_add_head(&table->free_entries, &entry->entry);
2068 /* Shrink if necessary */
2069 if (table->count < table->shrink_size) {
2070 if (!hash_table_resize(table, table->bucket_count >> 1))
2072 ERR("Failed to shrink the table...\n");
2082 /* Grow if necessary */
2083 if (table->count >= table->grow_size)
2085 if (!hash_table_resize(table, table->bucket_count << 1))
2087 ERR("Failed to grow the table, returning.\n");
2091 idx = hash & (table->bucket_count - 1);
2094 /* Find an entry to insert */
2095 if (!list_empty(&table->free_entries))
2097 struct list *elem = list_head(&table->free_entries);
2100 entry = LIST_ENTRY(elem, struct hash_table_entry_t, entry);
2102 entry = table->entries + (table->entry_count++);
2105 /* Insert the entry */
2107 entry->value = value;
2109 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
2110 list_add_head(&table->buckets[idx], &entry->entry);
2115 void hash_table_remove(struct hash_table_t *table, void *key)
2117 hash_table_put(table, key, NULL);
2120 void *hash_table_get(const struct hash_table_t *table, const void *key)
2123 struct hash_table_entry_t *entry;
2125 idx = table->hash_function(key) & (table->bucket_count - 1);
2126 entry = hash_table_get_by_idx(table, key, idx);
2128 return entry ? entry->value : NULL;
2131 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2132 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2136 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2138 /* D3DTOP_DISABLE */ 0,
2139 /* D3DTOP_SELECTARG1 */ ARG1,
2140 /* D3DTOP_SELECTARG2 */ ARG2,
2141 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2142 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2143 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2144 /* D3DTOP_ADD */ ARG1 | ARG2,
2145 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2146 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2147 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2148 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2149 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2150 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2151 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2152 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2153 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2154 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2155 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2156 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2157 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2158 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2159 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2160 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2161 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2162 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2163 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2167 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2169 for(i = 0; i < GL_LIMITS(texture_stages); i++) {
2170 IWineD3DBaseTextureImpl *texture;
2171 settings->op[i].padding = 0;
2172 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2173 settings->op[i].cop = WINED3DTOP_DISABLE;
2174 settings->op[i].aop = WINED3DTOP_DISABLE;
2175 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2176 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2177 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2178 settings->op[i].dst = resultreg;
2179 settings->op[i].tex_type = tex_1d;
2180 settings->op[i].projected = proj_none;
2185 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2187 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2188 if(ignore_textype) {
2189 settings->op[i].tex_type = tex_1d;
2191 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2193 settings->op[i].tex_type = tex_1d;
2196 settings->op[i].tex_type = tex_2d;
2199 settings->op[i].tex_type = tex_3d;
2201 case GL_TEXTURE_CUBE_MAP_ARB:
2202 settings->op[i].tex_type = tex_cube;
2204 case GL_TEXTURE_RECTANGLE_ARB:
2205 settings->op[i].tex_type = tex_rect;
2210 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2211 settings->op[i].tex_type = tex_1d;
2214 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2215 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2217 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2218 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2219 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2221 if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
2222 carg1, carg2, carg0)) {
2225 carg1 = WINED3DTA_CURRENT;
2226 cop = WINED3DTOP_SELECTARG1;
2229 if(cop == WINED3DTOP_DOTPRODUCT3) {
2230 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2231 * the color result to the alpha component of the destination
2238 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2239 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2240 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2243 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2245 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2247 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2249 IWineD3DSurfaceImpl *surf;
2250 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2252 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2254 if (aop == WINED3DTOP_DISABLE)
2256 aarg1 = WINED3DTA_TEXTURE;
2257 aop = WINED3DTOP_SELECTARG1;
2259 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2261 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2263 aarg2 = WINED3DTA_TEXTURE;
2264 aop = WINED3DTOP_MODULATE;
2266 else aarg1 = WINED3DTA_TEXTURE;
2268 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2270 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2272 aarg1 = WINED3DTA_TEXTURE;
2273 aop = WINED3DTOP_MODULATE;
2275 else aarg2 = WINED3DTA_TEXTURE;
2281 if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
2282 aarg1, aarg2, aarg0)) {
2285 aarg1 = WINED3DTA_CURRENT;
2286 aop = WINED3DTOP_SELECTARG1;
2289 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2290 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2291 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2292 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2293 settings->op[i].projected = proj_count3;
2294 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2295 settings->op[i].projected = proj_count4;
2297 settings->op[i].projected = proj_none;
2300 settings->op[i].projected = proj_none;
2303 settings->op[i].cop = cop;
2304 settings->op[i].aop = aop;
2305 settings->op[i].carg0 = carg0;
2306 settings->op[i].carg1 = carg1;
2307 settings->op[i].carg2 = carg2;
2308 settings->op[i].aarg0 = aarg0;
2309 settings->op[i].aarg1 = aarg1;
2310 settings->op[i].aarg2 = aarg2;
2312 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2313 settings->op[i].dst = tempreg;
2315 settings->op[i].dst = resultreg;
2319 /* Clear unsupported stages */
2320 for(; i < MAX_TEXTURES; i++) {
2321 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2324 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2325 settings->fog = FOG_OFF;
2326 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2327 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2328 settings->fog = FOG_LINEAR;
2330 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2331 case WINED3DFOG_NONE:
2332 case WINED3DFOG_LINEAR:
2333 settings->fog = FOG_LINEAR;
2335 case WINED3DFOG_EXP:
2336 settings->fog = FOG_EXP;
2338 case WINED3DFOG_EXP2:
2339 settings->fog = FOG_EXP2;
2344 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2345 case WINED3DFOG_LINEAR:
2346 settings->fog = FOG_LINEAR;
2348 case WINED3DFOG_EXP:
2349 settings->fog = FOG_EXP;
2351 case WINED3DFOG_EXP2:
2352 settings->fog = FOG_EXP2;
2356 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2357 settings->sRGB_write = 1;
2359 settings->sRGB_write = 0;
2362 #undef GLINFO_LOCATION
2364 const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
2365 const struct ffp_frag_settings *settings)
2367 return hash_table_get(fragment_shaders, settings);
2370 void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *desc) {
2371 struct ffp_frag_settings *key = HeapAlloc(GetProcessHeap(), 0, sizeof(*key));
2372 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2373 * whereas desc points to an extended structure with implementation specific parts.
2374 * Make a copy of the key because hash_table_put takes ownership of it
2376 *key = desc->settings;
2377 hash_table_put(shaders, key, desc);
2380 /* Activates the texture dimension according to the bound D3D texture.
2381 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2382 * Requires the caller to activate the correct unit before
2384 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2385 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2386 if(stateblock->textures[stage]) {
2387 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2389 glDisable(GL_TEXTURE_3D);
2390 checkGLcall("glDisable(GL_TEXTURE_3D)");
2391 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2392 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2393 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2395 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2396 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2397 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2399 glEnable(GL_TEXTURE_2D);
2400 checkGLcall("glEnable(GL_TEXTURE_2D)");
2402 case GL_TEXTURE_RECTANGLE_ARB:
2403 glDisable(GL_TEXTURE_2D);
2404 checkGLcall("glDisable(GL_TEXTURE_2D)");
2405 glDisable(GL_TEXTURE_3D);
2406 checkGLcall("glDisable(GL_TEXTURE_3D)");
2407 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2408 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2409 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2411 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2412 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2415 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2416 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2417 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2419 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2420 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2421 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2423 glDisable(GL_TEXTURE_2D);
2424 checkGLcall("glDisable(GL_TEXTURE_2D)");
2425 glEnable(GL_TEXTURE_3D);
2426 checkGLcall("glEnable(GL_TEXTURE_3D)");
2428 case GL_TEXTURE_CUBE_MAP_ARB:
2429 glDisable(GL_TEXTURE_2D);
2430 checkGLcall("glDisable(GL_TEXTURE_2D)");
2431 glDisable(GL_TEXTURE_3D);
2432 checkGLcall("glDisable(GL_TEXTURE_3D)");
2433 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2434 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2435 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2437 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2438 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2442 glEnable(GL_TEXTURE_2D);
2443 checkGLcall("glEnable(GL_TEXTURE_2D)");
2444 glDisable(GL_TEXTURE_3D);
2445 checkGLcall("glDisable(GL_TEXTURE_3D)");
2446 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2447 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2448 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2450 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2451 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2452 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2454 /* Binding textures is done by samplers. A dummy texture will be bound */
2458 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2459 DWORD sampler = state - STATE_SAMPLER(0);
2460 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2462 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2463 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2464 * will take care of this business
2466 if(mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= GL_LIMITS(textures)) return;
2467 if(sampler >= stateblock->lowest_disabled_stage) return;
2468 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2470 texture_activate_dimensions(sampler, stateblock, context);
2472 #undef GLINFO_LOCATION
2474 unsigned int ffp_frag_program_key_hash(const void *key)
2476 const struct ffp_frag_settings *k = key;
2477 unsigned int hash = 0, i;
2480 /* This takes the texture op settings of stage 0 and 1 into account.
2481 * how exactly depends on the memory laybout of the compiler, but it
2482 * should not matter too much. Stages > 1 are used rarely, so there's
2483 * no need to process them. Even if they're used it is likely that
2484 * the ffp setup has distinct stage 0 and 1 settings.
2486 for(i = 0; i < 2; i++) {
2487 blob = (const DWORD *)&k->op[i];
2488 hash ^= blob[0] ^ blob[1];
2491 hash += ~(hash << 15);
2492 hash ^= (hash >> 10);
2493 hash += (hash << 3);
2494 hash ^= (hash >> 6);
2495 hash += ~(hash << 11);
2496 hash ^= (hash >> 16);
2501 BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb)
2503 const struct ffp_frag_settings *ka = keya;
2504 const struct ffp_frag_settings *kb = keyb;
2506 return memcmp(ka, kb, sizeof(*ka)) == 0;
2509 UINT wined3d_log2i(UINT32 x)
2511 static const BYTE l[] =
2513 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2514 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2515 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2516 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2517 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2518 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2519 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2520 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2521 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2522 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2523 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2524 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2525 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2526 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2527 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2528 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2532 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];