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_BUFFER);
1002 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1003 return "unrecognized";
1007 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1008 switch (PrimitiveType) {
1009 #define PRIM_TO_STR(prim) case prim: return #prim
1010 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1011 PRIM_TO_STR(WINED3DPT_POINTLIST);
1012 PRIM_TO_STR(WINED3DPT_LINELIST);
1013 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1014 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1015 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1016 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1017 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1018 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1019 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1020 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1023 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1024 return "unrecognized";
1028 const char* debug_d3drenderstate(DWORD state) {
1030 #define D3DSTATE_TO_STR(u) case u: return #u
1031 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
1032 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1033 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
1034 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1035 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1036 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1037 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1038 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1039 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1040 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1041 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1042 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1043 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1044 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1045 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1046 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1047 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
1048 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
1049 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1050 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1051 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
1052 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1053 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1054 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1055 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1056 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1057 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1058 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1059 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1060 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1061 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1062 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1063 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1064 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1065 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1066 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1067 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1068 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1069 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1070 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1071 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1072 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
1073 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
1074 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
1075 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1076 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1077 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1078 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1079 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1080 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1081 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1082 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1083 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1084 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1085 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1086 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1087 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1088 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1089 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1090 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
1091 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
1092 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
1093 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
1094 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
1095 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
1096 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
1097 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
1098 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
1099 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
1100 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
1101 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
1102 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
1103 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
1104 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
1105 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
1106 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
1107 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
1108 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
1109 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
1110 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
1111 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
1112 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
1113 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
1114 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
1115 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
1116 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
1117 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
1118 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
1119 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
1120 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
1121 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
1122 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1123 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1124 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1125 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1126 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1127 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1128 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1129 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1130 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1131 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1132 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1133 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1134 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1135 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1136 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1137 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1138 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1139 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1140 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1141 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1142 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1143 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1144 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1145 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1146 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1147 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1148 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1149 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1150 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1151 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1152 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1153 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1154 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1155 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1156 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1157 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1158 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1159 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1160 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1161 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1162 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1163 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1164 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1165 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1166 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1167 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1168 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1169 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1170 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1171 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1172 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1173 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1174 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1175 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1176 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1177 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1178 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1179 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1180 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1181 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1182 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1183 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1184 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1185 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1186 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1187 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1188 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1189 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1190 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1191 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1192 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1193 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1194 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1195 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1196 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1197 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1198 #undef D3DSTATE_TO_STR
1200 FIXME("Unrecognized %u render state!\n", state);
1201 return "unrecognized";
1205 const char* debug_d3dsamplerstate(DWORD state) {
1207 #define D3DSTATE_TO_STR(u) case u: return #u
1208 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1209 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1210 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1211 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1212 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1213 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1214 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1215 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1216 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1217 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1218 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1219 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1220 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1221 #undef D3DSTATE_TO_STR
1223 FIXME("Unrecognized %u sampler state!\n", state);
1224 return "unrecognized";
1228 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1229 switch (filter_type) {
1230 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1231 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1232 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1233 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1234 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1235 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1236 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1237 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1238 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1239 #undef D3DTEXTUREFILTERTYPE_TO_STR
1241 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1242 return "unrecognized";
1246 const char* debug_d3dtexturestate(DWORD state) {
1248 #define D3DSTATE_TO_STR(u) case u: return #u
1249 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1250 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1251 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1252 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1253 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1254 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1255 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1256 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1257 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1258 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1259 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1260 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1261 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1262 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1263 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1264 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1265 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1266 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1267 #undef D3DSTATE_TO_STR
1269 FIXME("Unrecognized %u texture state!\n", state);
1270 return "unrecognized";
1274 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1276 #define D3DTOP_TO_STR(u) case u: return #u
1277 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1278 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1279 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1280 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1281 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1282 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1283 D3DTOP_TO_STR(WINED3DTOP_ADD);
1284 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1285 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1286 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1287 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1288 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1289 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1290 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1291 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1292 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1293 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1294 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1295 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1296 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1297 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1298 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1299 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1300 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1301 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1302 D3DTOP_TO_STR(WINED3DTOP_LERP);
1303 #undef D3DTOP_TO_STR
1305 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1306 return "unrecognized";
1310 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1312 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1313 TSTYPE_TO_STR(WINED3DTS_VIEW);
1314 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1315 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1316 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1317 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1318 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1319 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1320 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1321 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1322 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1323 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1324 #undef TSTYPE_TO_STR
1326 if (tstype > 256 && tstype < 512) {
1327 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1328 return ("WINED3DTS_WORLDMATRIX > 0");
1330 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1331 return "unrecognized";
1335 const char* debug_d3dpool(WINED3DPOOL Pool) {
1337 #define POOL_TO_STR(p) case p: return #p
1338 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1339 POOL_TO_STR(WINED3DPOOL_MANAGED);
1340 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1341 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1344 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1345 return "unrecognized";
1349 const char *debug_fbostatus(GLenum status) {
1351 #define FBOSTATUS_TO_STR(u) case u: return #u
1352 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1353 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1354 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1355 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1356 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1357 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1358 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1359 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
1360 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1361 #undef FBOSTATUS_TO_STR
1363 FIXME("Unrecognied FBO status 0x%08x\n", status);
1364 return "unrecognized";
1368 const char *debug_glerror(GLenum error) {
1370 #define GLERROR_TO_STR(u) case u: return #u
1371 GLERROR_TO_STR(GL_NO_ERROR);
1372 GLERROR_TO_STR(GL_INVALID_ENUM);
1373 GLERROR_TO_STR(GL_INVALID_VALUE);
1374 GLERROR_TO_STR(GL_INVALID_OPERATION);
1375 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1376 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1377 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1378 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1379 #undef GLERROR_TO_STR
1381 FIXME("Unrecognied GL error 0x%08x\n", error);
1382 return "unrecognized";
1386 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1388 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1389 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1390 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1391 default: return "unrecognized";
1395 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1397 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1398 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1399 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1400 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1401 default: return "unrecognized";
1405 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
1409 #define WINED3D_TO_STR(x) case x: return #x
1410 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1411 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1412 WINED3D_TO_STR(CHANNEL_SOURCE_X);
1413 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1414 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1415 WINED3D_TO_STR(CHANNEL_SOURCE_W);
1416 WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1417 WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1418 #undef WINED3D_TO_STR
1420 FIXME("Unrecognized fixup_channel_source %#x\n", source);
1421 return "unrecognized";
1425 static const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1429 #define WINED3D_TO_STR(x) case x: return #x
1430 WINED3D_TO_STR(YUV_FIXUP_YUY2);
1431 WINED3D_TO_STR(YUV_FIXUP_UYVY);
1432 WINED3D_TO_STR(YUV_FIXUP_YV12);
1433 #undef WINED3D_TO_STR
1435 FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1436 return "unrecognized";
1440 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1442 if (is_yuv_fixup(fixup))
1444 TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1448 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1449 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1450 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1451 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1454 const char *debug_surflocation(DWORD flag) {
1458 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
1459 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
1460 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
1461 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
1462 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
1465 /*****************************************************************************
1466 * Useful functions mapping GL <-> D3D values
1468 GLenum StencilOp(DWORD op) {
1470 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1471 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1472 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1473 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1474 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1475 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1476 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1477 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1479 FIXME("Unrecognized stencil op %d\n", op);
1484 GLenum CompareFunc(DWORD func) {
1485 switch ((WINED3DCMPFUNC)func) {
1486 case WINED3DCMP_NEVER : return GL_NEVER;
1487 case WINED3DCMP_LESS : return GL_LESS;
1488 case WINED3DCMP_EQUAL : return GL_EQUAL;
1489 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1490 case WINED3DCMP_GREATER : return GL_GREATER;
1491 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1492 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1493 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1495 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1500 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1501 if (op == WINED3DTOP_DISABLE) return FALSE;
1502 if (This->stateBlock->textures[stage]) return FALSE;
1504 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1505 && op != WINED3DTOP_SELECTARG2) return TRUE;
1506 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1507 && op != WINED3DTOP_SELECTARG1) return TRUE;
1508 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1509 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1514 /* Setup this textures matrix according to the texture flags*/
1515 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
1516 WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
1520 glMatrixMode(GL_TEXTURE);
1521 checkGLcall("glMatrixMode(GL_TEXTURE)");
1523 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1525 checkGLcall("glLoadIdentity()");
1529 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1530 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1534 memcpy(mat, smat, 16 * sizeof(float));
1536 if (flags & WINED3DTTFF_PROJECTED) {
1537 if(!ffp_proj_control) {
1538 switch (flags & ~WINED3DTTFF_PROJECTED) {
1539 case WINED3DTTFF_COUNT2:
1540 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1541 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1543 case WINED3DTTFF_COUNT3:
1544 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1545 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1549 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1550 if(!calculatedCoords) {
1553 case WINED3DFMT_R32_FLOAT:
1554 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1555 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1556 * the input value to the transformation will be 0, so the matrix value is irrelevant
1563 case WINED3DFMT_R32G32_FLOAT:
1564 /* See above, just 3rd and 4th coord
1571 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
1572 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
1574 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1575 * into a bad place. The division elimination below will apply to make sure the
1576 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1578 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
1581 FIXME("Unexpected fixed function texture coord input\n");
1584 if(!ffp_proj_control) {
1585 switch (flags & ~WINED3DTTFF_PROJECTED) {
1586 /* case WINED3DTTFF_COUNT1: Won't ever get here */
1587 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
1588 /* OpenGL divides the first 3 vertex coord by the 4th by default,
1589 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
1590 * the 4th coord evaluates to 1.0 to eliminate that.
1592 * If the fixed function pipeline is used, the 4th value remains unused,
1593 * so there is no danger in doing this. With vertex shaders we have a
1594 * problem. Should an app hit that problem, the code here would have to
1595 * check for pixel shaders, and the shader has to undo the default gl divide.
1597 * A more serious problem occurs if the app passes 4 coordinates in, and the
1598 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
1599 * or a replacement shader
1601 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
1607 checkGLcall("glLoadMatrixf(mat)");
1609 #undef GLINFO_LOCATION
1611 /* This small helper function is used to convert a bitmask into the number of masked bits */
1612 unsigned int count_bits(unsigned int mask)
1615 for (count = 0; mask; ++count)
1622 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
1623 * The later function requires individual color components. */
1624 BOOL getColorBits(const struct GlPixelFormatDesc *format_desc,
1625 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
1627 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
1628 switch(format_desc->format)
1630 case WINED3DFMT_X8R8G8B8:
1631 case WINED3DFMT_R8G8B8:
1632 case WINED3DFMT_A8R8G8B8:
1633 case WINED3DFMT_R8G8B8A8_UNORM:
1634 case WINED3DFMT_A2R10G10B10:
1635 case WINED3DFMT_X1R5G5B5:
1636 case WINED3DFMT_A1R5G5B5:
1637 case WINED3DFMT_R5G6B5:
1638 case WINED3DFMT_X4R4G4B4:
1639 case WINED3DFMT_A4R4G4B4:
1640 case WINED3DFMT_R3G3B2:
1641 case WINED3DFMT_A8P8:
1645 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
1649 *redSize = count_bits(format_desc->red_mask);
1650 *greenSize = count_bits(format_desc->green_mask);
1651 *blueSize = count_bits(format_desc->blue_mask);
1652 *alphaSize = count_bits(format_desc->alpha_mask);
1653 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
1655 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
1656 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
1660 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
1661 BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize)
1663 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
1664 switch(format_desc->format)
1666 case WINED3DFMT_D16_LOCKABLE:
1667 case WINED3DFMT_D16_UNORM:
1668 case WINED3DFMT_D15S1:
1669 case WINED3DFMT_D24X8:
1670 case WINED3DFMT_D24X4S4:
1671 case WINED3DFMT_D24S8:
1672 case WINED3DFMT_D24FS8:
1673 case WINED3DFMT_D32:
1674 case WINED3DFMT_D32F_LOCKABLE:
1677 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
1681 *depthSize = format_desc->depth_size;
1682 *stencilSize = format_desc->stencil_size;
1684 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
1685 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
1689 /* DirectDraw stuff */
1690 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
1692 case 8: return WINED3DFMT_P8;
1693 case 15: return WINED3DFMT_X1R5G5B5;
1694 case 16: return WINED3DFMT_R5G6B5;
1695 case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
1696 case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
1697 default: return WINED3DFMT_UNKNOWN;
1701 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
1704 /* Now do the multiplication 'by hand'.
1705 I know that all this could be optimised, but this will be done later :-) */
1706 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);
1707 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);
1708 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);
1709 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);
1711 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);
1712 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);
1713 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);
1714 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);
1716 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);
1717 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);
1718 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);
1719 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);
1721 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);
1722 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);
1723 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);
1724 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);
1726 /* And copy the new matrix in the good storage.. */
1727 memcpy(dest, &temp, 16 * sizeof(float));
1730 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
1733 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
1735 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
1736 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
1737 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
1738 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
1739 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
1740 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
1741 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
1742 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
1743 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
1744 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
1745 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
1746 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
1747 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
1748 default: ERR("Unexpected position mask\n");
1750 for (i = 0; i < numTextures; i++) {
1751 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
1757 /***********************************************************************
1760 * Calculates the dimensions of the opengl texture used for blits.
1761 * Handled oversized opengl textures and updates the source rectangle
1765 * This: Surface to operate on
1766 * Rect: Requested rectangle
1769 * TRUE if the texture part can be loaded,
1772 *********************************************************************/
1773 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
1775 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
1776 int x1 = Rect->left, x2 = Rect->right;
1777 int y1 = Rect->top, y2 = Rect->bottom;
1778 GLint maxSize = GL_LIMITS(texture_size);
1780 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
1781 Rect->left, Rect->top, Rect->right, Rect->bottom);
1783 /* The sizes might be reversed */
1784 if(Rect->left > Rect->right) {
1788 if(Rect->top > Rect->bottom) {
1793 /* No oversized texture? This is easy */
1794 if(!(This->Flags & SFLAG_OVERSIZE)) {
1795 /* Which rect from the texture do I need? */
1796 if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
1797 glTexCoord[0] = (float) Rect->left;
1798 glTexCoord[2] = (float) Rect->top;
1799 glTexCoord[1] = (float) Rect->right;
1800 glTexCoord[3] = (float) Rect->bottom;
1802 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
1803 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
1804 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
1805 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
1810 /* Check if we can succeed at all */
1811 if( (x2 - x1) > maxSize ||
1812 (y2 - y1) > maxSize ) {
1813 TRACE("Requested rectangle is too large for gl\n");
1817 /* A part of the texture has to be picked. First, check if
1818 * some texture part is loaded already, if yes try to re-use it.
1819 * If the texture is dirty, or the part can't be used,
1820 * re-position the part to load
1822 if(This->Flags & SFLAG_INTEXTURE) {
1823 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
1824 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
1825 /* Ok, the rectangle is ok, re-use it */
1826 TRACE("Using existing gl Texture\n");
1828 /* Rectangle is not ok, dirtify the texture to reload it */
1829 TRACE("Dirtifying texture to force reload\n");
1830 This->Flags &= ~SFLAG_INTEXTURE;
1834 /* Now if we are dirty(no else if!) */
1835 if(!(This->Flags & SFLAG_INTEXTURE)) {
1836 /* Set the new rectangle. Use the following strategy:
1837 * 1) Use as big textures as possible.
1838 * 2) Place the texture part in the way that the requested
1839 * part is in the middle of the texture(well, almost)
1840 * 3) If the texture is moved over the edges of the
1841 * surface, replace it nicely
1842 * 4) If the coord is not limiting the texture size,
1843 * use the whole size
1845 if((This->pow2Width) > maxSize) {
1846 This->glRect.left = x1 - maxSize / 2;
1847 if(This->glRect.left < 0) {
1848 This->glRect.left = 0;
1850 This->glRect.right = This->glRect.left + maxSize;
1851 if(This->glRect.right > This->currentDesc.Width) {
1852 This->glRect.right = This->currentDesc.Width;
1853 This->glRect.left = This->glRect.right - maxSize;
1856 This->glRect.left = 0;
1857 This->glRect.right = This->pow2Width;
1860 if(This->pow2Height > maxSize) {
1861 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
1862 if(This->glRect.top < 0) This->glRect.top = 0;
1863 This->glRect.bottom = This->glRect.left + maxSize;
1864 if(This->glRect.bottom > This->currentDesc.Height) {
1865 This->glRect.bottom = This->currentDesc.Height;
1866 This->glRect.top = This->glRect.bottom - maxSize;
1869 This->glRect.top = 0;
1870 This->glRect.bottom = This->pow2Height;
1872 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
1873 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
1876 /* Re-calculate the rect to draw */
1877 Rect->left -= This->glRect.left;
1878 Rect->right -= This->glRect.left;
1879 Rect->top -= This->glRect.top;
1880 Rect->bottom -= This->glRect.top;
1882 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
1883 * or the pow2Width / pow2Height of the surface.
1885 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
1886 * as regular GL_TEXTURE_2D.
1888 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
1889 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
1890 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
1891 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
1895 #undef GLINFO_LOCATION
1897 /* Hash table functions */
1899 struct hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
1901 struct hash_table_t *table;
1902 unsigned int initial_size = 8;
1904 table = HeapAlloc(GetProcessHeap(), 0, sizeof(struct hash_table_t) + (initial_size * sizeof(struct list)));
1907 ERR("Failed to allocate table, returning NULL.\n");
1911 table->hash_function = hash_function;
1912 table->compare_function = compare_function;
1914 table->grow_size = initial_size - (initial_size >> 2);
1915 table->shrink_size = 0;
1917 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
1918 if (!table->buckets)
1920 ERR("Failed to allocate table buckets, returning NULL.\n");
1921 HeapFree(GetProcessHeap(), 0, table);
1924 table->bucket_count = initial_size;
1926 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(struct hash_table_entry_t));
1927 if (!table->entries)
1929 ERR("Failed to allocate table entries, returning NULL.\n");
1930 HeapFree(GetProcessHeap(), 0, table->buckets);
1931 HeapFree(GetProcessHeap(), 0, table);
1934 table->entry_count = 0;
1936 list_init(&table->free_entries);
1942 void hash_table_destroy(struct hash_table_t *table, void (*free_value)(void *value, void *cb), void *cb)
1946 for (i = 0; i < table->entry_count; ++i)
1949 free_value(table->entries[i].value, cb);
1951 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
1954 HeapFree(GetProcessHeap(), 0, table->entries);
1955 HeapFree(GetProcessHeap(), 0, table->buckets);
1956 HeapFree(GetProcessHeap(), 0, table);
1959 void hash_table_for_each_entry(struct hash_table_t *table, void (*callback)(void *value, void *context), void *context)
1963 for (i = 0; i < table->entry_count; ++i)
1965 callback(table->entries[i].value, context);
1969 static inline struct hash_table_entry_t *hash_table_get_by_idx(const struct hash_table_t *table, const void *key,
1972 struct hash_table_entry_t *entry;
1974 if (table->buckets[idx].next)
1975 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), struct hash_table_entry_t, entry)
1976 if (table->compare_function(entry->key, key)) return entry;
1981 static BOOL hash_table_resize(struct hash_table_t *table, unsigned int new_bucket_count)
1983 unsigned int new_entry_count = 0;
1984 struct hash_table_entry_t *new_entries;
1985 struct list *new_buckets;
1986 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
1989 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
1992 ERR("Failed to allocate new buckets, returning FALSE.\n");
1996 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(struct hash_table_entry_t));
1999 ERR("Failed to allocate new entries, returning FALSE.\n");
2000 HeapFree(GetProcessHeap(), 0, new_buckets);
2004 for (i = 0; i < table->bucket_count; ++i)
2006 if (table->buckets[i].next)
2008 struct hash_table_entry_t *entry, *entry2;
2010 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], struct hash_table_entry_t, entry)
2013 struct hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
2014 *new_entry = *entry;
2016 j = new_entry->hash & (new_bucket_count - 1);
2018 if (!new_buckets[j].next) list_init(&new_buckets[j]);
2019 list_add_head(&new_buckets[j], &new_entry->entry);
2024 HeapFree(GetProcessHeap(), 0, table->buckets);
2025 table->buckets = new_buckets;
2027 HeapFree(GetProcessHeap(), 0, table->entries);
2028 table->entries = new_entries;
2030 table->entry_count = new_entry_count;
2031 list_init(&table->free_entries);
2033 table->bucket_count = new_bucket_count;
2034 table->grow_size = grow_size;
2035 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
2040 void hash_table_put(struct hash_table_t *table, void *key, void *value)
2044 struct hash_table_entry_t *entry;
2046 hash = table->hash_function(key);
2047 idx = hash & (table->bucket_count - 1);
2048 entry = hash_table_get_by_idx(table, key, idx);
2052 HeapFree(GetProcessHeap(), 0, key);
2053 entry->value = value;
2057 HeapFree(GetProcessHeap(), 0, entry->key);
2060 /* Remove the entry */
2061 list_remove(&entry->entry);
2062 list_add_head(&table->free_entries, &entry->entry);
2066 /* Shrink if necessary */
2067 if (table->count < table->shrink_size) {
2068 if (!hash_table_resize(table, table->bucket_count >> 1))
2070 ERR("Failed to shrink the table...\n");
2080 /* Grow if necessary */
2081 if (table->count >= table->grow_size)
2083 if (!hash_table_resize(table, table->bucket_count << 1))
2085 ERR("Failed to grow the table, returning.\n");
2089 idx = hash & (table->bucket_count - 1);
2092 /* Find an entry to insert */
2093 if (!list_empty(&table->free_entries))
2095 struct list *elem = list_head(&table->free_entries);
2098 entry = LIST_ENTRY(elem, struct hash_table_entry_t, entry);
2100 entry = table->entries + (table->entry_count++);
2103 /* Insert the entry */
2105 entry->value = value;
2107 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
2108 list_add_head(&table->buckets[idx], &entry->entry);
2113 void hash_table_remove(struct hash_table_t *table, void *key)
2115 hash_table_put(table, key, NULL);
2118 void *hash_table_get(const struct hash_table_t *table, const void *key)
2121 struct hash_table_entry_t *entry;
2123 idx = table->hash_function(key) & (table->bucket_count - 1);
2124 entry = hash_table_get_by_idx(table, key, idx);
2126 return entry ? entry->value : NULL;
2129 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2130 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2134 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2136 /* D3DTOP_DISABLE */ 0,
2137 /* D3DTOP_SELECTARG1 */ ARG1,
2138 /* D3DTOP_SELECTARG2 */ ARG2,
2139 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2140 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2141 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2142 /* D3DTOP_ADD */ ARG1 | ARG2,
2143 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2144 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2145 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2146 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2147 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2148 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2149 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2150 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2151 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2152 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2153 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2154 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2155 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2156 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2157 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2158 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2159 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2160 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2161 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2165 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2167 for(i = 0; i < GL_LIMITS(texture_stages); i++) {
2168 IWineD3DBaseTextureImpl *texture;
2169 settings->op[i].padding = 0;
2170 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2171 settings->op[i].cop = WINED3DTOP_DISABLE;
2172 settings->op[i].aop = WINED3DTOP_DISABLE;
2173 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2174 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2175 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2176 settings->op[i].dst = resultreg;
2177 settings->op[i].tex_type = tex_1d;
2178 settings->op[i].projected = proj_none;
2183 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2185 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2186 if(ignore_textype) {
2187 settings->op[i].tex_type = tex_1d;
2189 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2191 settings->op[i].tex_type = tex_1d;
2194 settings->op[i].tex_type = tex_2d;
2197 settings->op[i].tex_type = tex_3d;
2199 case GL_TEXTURE_CUBE_MAP_ARB:
2200 settings->op[i].tex_type = tex_cube;
2202 case GL_TEXTURE_RECTANGLE_ARB:
2203 settings->op[i].tex_type = tex_rect;
2208 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2209 settings->op[i].tex_type = tex_1d;
2212 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2213 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2215 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2216 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2217 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2219 if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
2220 carg1, carg2, carg0)) {
2223 carg1 = WINED3DTA_CURRENT;
2224 cop = WINED3DTOP_SELECTARG1;
2227 if(cop == WINED3DTOP_DOTPRODUCT3) {
2228 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2229 * the color result to the alpha component of the destination
2236 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2237 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2238 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2241 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2243 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2245 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2247 IWineD3DSurfaceImpl *surf;
2248 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2250 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2252 if (aop == WINED3DTOP_DISABLE)
2254 aarg1 = WINED3DTA_TEXTURE;
2255 aop = WINED3DTOP_SELECTARG1;
2257 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2259 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2261 aarg2 = WINED3DTA_TEXTURE;
2262 aop = WINED3DTOP_MODULATE;
2264 else aarg1 = WINED3DTA_TEXTURE;
2266 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2268 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2270 aarg1 = WINED3DTA_TEXTURE;
2271 aop = WINED3DTOP_MODULATE;
2273 else aarg2 = WINED3DTA_TEXTURE;
2279 if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
2280 aarg1, aarg2, aarg0)) {
2283 aarg1 = WINED3DTA_CURRENT;
2284 aop = WINED3DTOP_SELECTARG1;
2287 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2288 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2289 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2290 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2291 settings->op[i].projected = proj_count3;
2292 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2293 settings->op[i].projected = proj_count4;
2295 settings->op[i].projected = proj_none;
2298 settings->op[i].projected = proj_none;
2301 settings->op[i].cop = cop;
2302 settings->op[i].aop = aop;
2303 settings->op[i].carg0 = carg0;
2304 settings->op[i].carg1 = carg1;
2305 settings->op[i].carg2 = carg2;
2306 settings->op[i].aarg0 = aarg0;
2307 settings->op[i].aarg1 = aarg1;
2308 settings->op[i].aarg2 = aarg2;
2310 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2311 settings->op[i].dst = tempreg;
2313 settings->op[i].dst = resultreg;
2317 /* Clear unsupported stages */
2318 for(; i < MAX_TEXTURES; i++) {
2319 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2322 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2323 settings->fog = FOG_OFF;
2324 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2325 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2326 settings->fog = FOG_LINEAR;
2328 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2329 case WINED3DFOG_NONE:
2330 case WINED3DFOG_LINEAR:
2331 settings->fog = FOG_LINEAR;
2333 case WINED3DFOG_EXP:
2334 settings->fog = FOG_EXP;
2336 case WINED3DFOG_EXP2:
2337 settings->fog = FOG_EXP2;
2342 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2343 case WINED3DFOG_LINEAR:
2344 settings->fog = FOG_LINEAR;
2346 case WINED3DFOG_EXP:
2347 settings->fog = FOG_EXP;
2349 case WINED3DFOG_EXP2:
2350 settings->fog = FOG_EXP2;
2354 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2355 settings->sRGB_write = 1;
2357 settings->sRGB_write = 0;
2360 #undef GLINFO_LOCATION
2362 const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
2363 const struct ffp_frag_settings *settings)
2365 return hash_table_get(fragment_shaders, settings);
2368 void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *desc) {
2369 struct ffp_frag_settings *key = HeapAlloc(GetProcessHeap(), 0, sizeof(*key));
2370 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2371 * whereas desc points to an extended structure with implementation specific parts.
2372 * Make a copy of the key because hash_table_put takes ownership of it
2374 *key = desc->settings;
2375 hash_table_put(shaders, key, desc);
2378 /* Activates the texture dimension according to the bound D3D texture.
2379 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2380 * Requires the caller to activate the correct unit before
2382 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2383 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2384 if(stateblock->textures[stage]) {
2385 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2387 glDisable(GL_TEXTURE_3D);
2388 checkGLcall("glDisable(GL_TEXTURE_3D)");
2389 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2390 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2391 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2393 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2394 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2395 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2397 glEnable(GL_TEXTURE_2D);
2398 checkGLcall("glEnable(GL_TEXTURE_2D)");
2400 case GL_TEXTURE_RECTANGLE_ARB:
2401 glDisable(GL_TEXTURE_2D);
2402 checkGLcall("glDisable(GL_TEXTURE_2D)");
2403 glDisable(GL_TEXTURE_3D);
2404 checkGLcall("glDisable(GL_TEXTURE_3D)");
2405 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2406 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2407 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2409 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2410 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2413 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2414 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2415 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2417 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2418 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2419 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2421 glDisable(GL_TEXTURE_2D);
2422 checkGLcall("glDisable(GL_TEXTURE_2D)");
2423 glEnable(GL_TEXTURE_3D);
2424 checkGLcall("glEnable(GL_TEXTURE_3D)");
2426 case GL_TEXTURE_CUBE_MAP_ARB:
2427 glDisable(GL_TEXTURE_2D);
2428 checkGLcall("glDisable(GL_TEXTURE_2D)");
2429 glDisable(GL_TEXTURE_3D);
2430 checkGLcall("glDisable(GL_TEXTURE_3D)");
2431 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2432 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2433 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2435 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2436 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2440 glEnable(GL_TEXTURE_2D);
2441 checkGLcall("glEnable(GL_TEXTURE_2D)");
2442 glDisable(GL_TEXTURE_3D);
2443 checkGLcall("glDisable(GL_TEXTURE_3D)");
2444 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2445 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2446 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2448 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2449 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2450 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2452 /* Binding textures is done by samplers. A dummy texture will be bound */
2456 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2457 DWORD sampler = state - STATE_SAMPLER(0);
2458 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2460 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2461 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2462 * will take care of this business
2464 if(mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= GL_LIMITS(textures)) return;
2465 if(sampler >= stateblock->lowest_disabled_stage) return;
2466 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2468 texture_activate_dimensions(sampler, stateblock, context);
2470 #undef GLINFO_LOCATION
2472 unsigned int ffp_frag_program_key_hash(const void *key)
2474 const struct ffp_frag_settings *k = key;
2475 unsigned int hash = 0, i;
2478 /* This takes the texture op settings of stage 0 and 1 into account.
2479 * how exactly depends on the memory laybout of the compiler, but it
2480 * should not matter too much. Stages > 1 are used rarely, so there's
2481 * no need to process them. Even if they're used it is likely that
2482 * the ffp setup has distinct stage 0 and 1 settings.
2484 for(i = 0; i < 2; i++) {
2485 blob = (const DWORD *)&k->op[i];
2486 hash ^= blob[0] ^ blob[1];
2489 hash += ~(hash << 15);
2490 hash ^= (hash >> 10);
2491 hash += (hash << 3);
2492 hash ^= (hash >> 6);
2493 hash += ~(hash << 11);
2494 hash ^= (hash >> 16);
2499 BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb)
2501 const struct ffp_frag_settings *ka = keya;
2502 const struct ffp_frag_settings *kb = keyb;
2504 return memcmp(ka, kb, sizeof(*ka)) == 0;
2507 UINT wined3d_log2i(UINT32 x)
2509 static const BYTE l[] =
2511 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2512 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2513 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2514 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2515 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2516 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
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 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2520 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
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,
2530 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];