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