2 * Utility functions for the WineD3D Library
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2008 Henri Verbeet
9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wined3d_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
31 struct StaticPixelFormatDesc
34 DWORD alphaMask, redMask, greenMask, blueMask;
36 short depthSize, stencilSize;
40 /*****************************************************************************
43 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
44 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
45 * high masks do not fit into the 32 bit values needed for ddraw. It is only
46 * used for ddraw mostly, and to figure out if the format has alpha at all, so
47 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
48 * formats are not usable in 2D rendering because ddraw doesn't support them.
50 static const struct StaticPixelFormatDesc formats[] =
52 /* WINED3DFORMAT alphamask redmask greenmask bluemask bpp depth stencil isFourcc */
53 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, FALSE},
54 /* FourCC formats, kept here to have WINED3DFMT_R8G8B8(=20) at position 20 */
55 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
56 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
57 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
58 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
59 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
60 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
61 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
62 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
63 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
64 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
65 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
67 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
68 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
69 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0, FALSE},
71 {WINED3DFMT_CxV8U8, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
73 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
74 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
75 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
76 /* Palettized formats */
77 {WINED3DFMT_A8P8, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
78 {WINED3DFMT_P8, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
79 /* Standard ARGB formats. Keep WINED3DFMT_R8G8B8(=20) at position 20 */
80 {WINED3DFMT_R8G8B8, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0, FALSE},
81 {WINED3DFMT_A8R8G8B8, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0, FALSE},
82 {WINED3DFMT_X8R8G8B8, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0, FALSE},
83 {WINED3DFMT_R5G6B5, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0, FALSE},
84 {WINED3DFMT_X1R5G5B5, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0, FALSE},
85 {WINED3DFMT_A1R5G5B5, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0, FALSE},
86 {WINED3DFMT_A4R4G4B4, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0, FALSE},
87 {WINED3DFMT_R3G3B2, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0, FALSE},
88 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
89 {WINED3DFMT_A8R3G3B2, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0, FALSE},
90 {WINED3DFMT_X4R4G4B4, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0, FALSE},
91 {WINED3DFMT_R10G10B10A2_UNORM, 0xb0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
92 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
93 {WINED3DFMT_X8B8G8R8, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
94 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0, FALSE},
95 {WINED3DFMT_A2R10G10B10, 0xb0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0, FALSE},
96 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0, FALSE},
98 {WINED3DFMT_L8, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
99 {WINED3DFMT_A8L8, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
100 {WINED3DFMT_A4L4, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
101 /* Bump mapping stuff */
102 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
103 {WINED3DFMT_L6V5U5, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
104 {WINED3DFMT_X8L8V8U8, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
105 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
106 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
107 {WINED3DFMT_W11V11U10, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
108 {WINED3DFMT_A2W10V10U10, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
109 /* Depth stencil formats */
110 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
111 {WINED3DFMT_D32, 0x0, 0x0, 0x0, 0x0, 4, 32, 0, FALSE},
112 {WINED3DFMT_D15S1, 0x0, 0x0, 0x0, 0x0, 2, 15, 1, FALSE},
113 {WINED3DFMT_D24S8, 0x0, 0x0, 0x0, 0x0, 4, 24, 8, FALSE},
114 {WINED3DFMT_D24X8, 0x0, 0x0, 0x0, 0x0, 4, 24, 0, FALSE},
115 {WINED3DFMT_D24X4S4, 0x0, 0x0, 0x0, 0x0, 4, 24, 4, FALSE},
116 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
117 {WINED3DFMT_L16, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
118 {WINED3DFMT_D32F_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 4, 32, 0, FALSE},
119 {WINED3DFMT_D24FS8, 0x0, 0x0, 0x0, 0x0, 4, 24, 8, FALSE},
120 /* Is this a vertex buffer? */
121 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, FALSE},
122 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
123 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
124 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
125 /* Vendor-specific formats */
126 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
127 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
128 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
133 GLint glInternal, glGammaInternal, rtInternal, glFormat, glType;
135 } GlPixelFormatDescTemplate;
137 /*****************************************************************************
138 * OpenGL format template. Contains unexciting formats which do not need
139 * extension checks. The order in this table is independent of the order in
140 * the table StaticPixelFormatDesc above. Not all formats have to be in this
143 static const GlPixelFormatDescTemplate gl_formats_template[] = {
144 /* WINED3DFORMAT internal srgbInternal rtInternal
147 {WINED3DFMT_UNKNOWN, 0, 0, 0,
151 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
152 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
153 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
154 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
157 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
158 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE,
159 WINED3DFMT_FLAG_FILTERING},
160 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
161 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE,
162 WINED3DFMT_FLAG_FILTERING},
163 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
164 GL_ALPHA, GL_UNSIGNED_BYTE,
165 WINED3DFMT_FLAG_FILTERING},
166 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
167 GL_RGBA, GL_UNSIGNED_BYTE,
168 WINED3DFMT_FLAG_FILTERING},
169 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
170 GL_RGBA, GL_UNSIGNED_BYTE,
171 WINED3DFMT_FLAG_FILTERING},
172 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
173 GL_RGBA, GL_UNSIGNED_BYTE,
174 WINED3DFMT_FLAG_FILTERING},
175 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
176 GL_RGBA, GL_UNSIGNED_BYTE,
177 WINED3DFMT_FLAG_FILTERING},
178 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
179 GL_RGBA, GL_UNSIGNED_BYTE,
180 WINED3DFMT_FLAG_FILTERING},
181 {WINED3DFMT_MULTI2_ARGB8, 0, 0, 0,
184 {WINED3DFMT_G8R8_G8B8, 0, 0, 0,
187 {WINED3DFMT_R8G8_B8G8, 0, 0, 0,
191 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
193 WINED3DFMT_FLAG_RENDERTARGET},
194 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
196 WINED3DFMT_FLAG_RENDERTARGET},
197 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
199 WINED3DFMT_FLAG_RENDERTARGET},
201 {WINED3DFMT_CxV8U8, 0, 0, 0,
205 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
206 GL_RED, GL_HALF_FLOAT_ARB,
207 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
208 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
209 GL_RG, GL_HALF_FLOAT_ARB,
210 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
211 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
212 GL_RGBA, GL_HALF_FLOAT_ARB,
213 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
214 /* Palettized formats */
215 {WINED3DFMT_A8P8, 0, 0, 0,
218 {WINED3DFMT_P8, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
219 GL_COLOR_INDEX, GL_UNSIGNED_BYTE,
221 /* Standard ARGB formats */
222 {WINED3DFMT_R8G8B8, GL_RGB8, GL_RGB8, 0,
223 GL_BGR, GL_UNSIGNED_BYTE,
224 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
225 {WINED3DFMT_A8R8G8B8, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
226 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
227 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
228 {WINED3DFMT_X8R8G8B8, GL_RGB8, GL_SRGB8_EXT, 0,
229 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
230 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
231 {WINED3DFMT_R5G6B5, GL_RGB5, GL_RGB5, GL_RGB8,
232 GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
233 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
234 {WINED3DFMT_X1R5G5B5, GL_RGB5, GL_RGB5_A1, 0,
235 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
236 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
237 {WINED3DFMT_A1R5G5B5, GL_RGB5_A1, GL_RGB5_A1, 0,
238 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
239 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
240 {WINED3DFMT_A4R4G4B4, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
241 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
242 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
243 {WINED3DFMT_R3G3B2, GL_R3_G3_B2, GL_R3_G3_B2, 0,
244 GL_RGB, GL_UNSIGNED_BYTE_3_3_2,
245 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING},
246 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
247 GL_ALPHA, GL_UNSIGNED_BYTE,
248 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING},
249 {WINED3DFMT_A8R3G3B2, 0, 0, 0,
252 {WINED3DFMT_X4R4G4B4, GL_RGB4, GL_RGB4, 0,
253 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
254 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
255 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
256 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV,
257 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
258 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
259 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
260 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
261 {WINED3DFMT_X8B8G8R8, GL_RGB8, GL_RGB8, 0,
262 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
263 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
264 {WINED3DFMT_R16G16_UNORM, GL_RGB16_EXT, GL_RGB16_EXT, 0,
265 GL_RGB, GL_UNSIGNED_SHORT,
266 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
267 {WINED3DFMT_A2R10G10B10, GL_RGB10_A2, GL_RGB10_A2, 0,
268 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV,
269 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
270 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16_EXT, GL_RGBA16_EXT, 0,
271 GL_RGBA, GL_UNSIGNED_SHORT,
272 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
274 {WINED3DFMT_L8, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
275 GL_LUMINANCE, GL_UNSIGNED_BYTE,
276 WINED3DFMT_FLAG_FILTERING},
277 {WINED3DFMT_A8L8, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
278 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
279 WINED3DFMT_FLAG_FILTERING},
280 {WINED3DFMT_A4L4, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
281 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
283 /* Bump mapping stuff */
284 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
286 WINED3DFMT_FLAG_FILTERING},
287 {WINED3DFMT_L6V5U5, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
288 GL_DSDT_MAG_NV, GL_BYTE,
289 WINED3DFMT_FLAG_FILTERING},
290 {WINED3DFMT_X8L8V8U8, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
291 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV,
292 WINED3DFMT_FLAG_FILTERING},
293 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
295 WINED3DFMT_FLAG_FILTERING},
296 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
297 GL_HILO_NV, GL_SHORT,
298 WINED3DFMT_FLAG_FILTERING},
299 {WINED3DFMT_W11V11U10, 0, 0, 0,
302 {WINED3DFMT_A2W10V10U10, 0, 0, 0,
305 /* Depth stencil formats */
306 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
307 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
308 WINED3DFMT_FLAG_DEPTH},
309 {WINED3DFMT_D32, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
310 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
311 WINED3DFMT_FLAG_DEPTH},
312 {WINED3DFMT_D15S1, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
313 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
314 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
315 {WINED3DFMT_D24S8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
316 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
317 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
318 {WINED3DFMT_D24X8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
319 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
320 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH},
321 {WINED3DFMT_D24X4S4, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
322 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
323 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
324 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
325 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
326 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH},
327 {WINED3DFMT_L16, GL_LUMINANCE16_EXT, GL_LUMINANCE16_EXT, 0,
328 GL_LUMINANCE, GL_UNSIGNED_SHORT,
329 WINED3DFMT_FLAG_FILTERING},
330 {WINED3DFMT_D32F_LOCKABLE, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
331 GL_DEPTH_COMPONENT, GL_FLOAT,
332 WINED3DFMT_FLAG_DEPTH},
333 {WINED3DFMT_D24FS8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
334 GL_DEPTH_COMPONENT, GL_FLOAT,
335 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
336 /* Is this a vertex buffer? */
337 {WINED3DFMT_VERTEXDATA, 0, 0, 0,
340 {WINED3DFMT_R16_UINT, 0, 0, 0,
343 {WINED3DFMT_R32_UINT, 0, 0, 0,
346 {WINED3DFMT_R16G16B16A16_SNORM, GL_COLOR_INDEX, GL_COLOR_INDEX, 0,
347 GL_COLOR_INDEX, GL_UNSIGNED_SHORT,
349 /* Vendor-specific formats */
350 {WINED3DFMT_ATI2N, 0, 0, 0,
351 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
353 {WINED3DFMT_NVHU, 0, 0, 0,
354 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
356 {WINED3DFMT_NVHS, 0, 0, 0,
357 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
361 static inline int getFmtIdx(WINED3DFORMAT fmt) {
362 /* First check if the format is at the position of its value.
363 * This will catch the argb formats before the loop is entered
365 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
369 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
370 if(formats[i].format == fmt) {
378 static BOOL init_format_base_info(WineD3D_GL_Info *gl_info)
380 UINT format_count = sizeof(formats) / sizeof(*formats);
383 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->gl_formats));
384 if (!gl_info->gl_formats)
386 ERR("Failed to allocate memory.\n");
390 for (i = 0; i < format_count; ++i)
392 struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
393 desc->format = formats[i].format;
394 desc->red_mask = formats[i].redMask;
395 desc->green_mask = formats[i].greenMask;
396 desc->blue_mask = formats[i].blueMask;
397 desc->alpha_mask = formats[i].alphaMask;
398 desc->byte_count = formats[i].bpp;
399 desc->depth_size = formats[i].depthSize;
400 desc->stencil_size = formats[i].stencilSize;
401 if (formats[i].isFourcc) desc->Flags |= WINED3DFMT_FLAG_FOURCC;
407 BOOL initPixelFormatsNoGL(WineD3D_GL_Info *gl_info)
409 return init_format_base_info(gl_info);
412 #define GLINFO_LOCATION (*gl_info)
413 BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
418 if (!init_format_base_info(gl_info)) return FALSE;
420 /* If a format depends on some extensions, remove them from the table above and initialize them
423 for(src = 0; src < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); src++) {
424 struct GlPixelFormatDesc *desc;
425 dst = getFmtIdx(gl_formats_template[src].fmt);
426 desc = &gl_info->gl_formats[dst];
428 desc->glInternal = gl_formats_template[src].glInternal;
429 desc->glGammaInternal = gl_formats_template[src].glGammaInternal;
430 desc->glFormat = gl_formats_template[src].glFormat;
431 desc->glType = gl_formats_template[src].glType;
432 desc->color_fixup = COLOR_FIXUP_IDENTITY;
433 desc->Flags |= gl_formats_template[src].Flags;
434 desc->heightscale = 1.0;
436 if(wined3d_settings.offscreen_rendering_mode == ORM_FBO &&
437 gl_formats_template[src].rtInternal != 0) {
441 /* Check if the default internal format is supported as a frame buffer target, otherwise
442 * fall back to the render target internal.
444 * Try to stick to the standard format if possible, this limits precision differences
447 glGenTextures(1, &tex);
448 glBindTexture(GL_TEXTURE_2D, tex);
449 glTexImage2D(GL_TEXTURE_2D, 0, gl_formats_template[src].glInternal, 16, 16, 0,
450 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
452 GL_EXTCALL(glGenFramebuffersEXT(1, &fb));
453 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb));
454 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
455 GL_TEXTURE_2D, tex, 0));
457 status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
458 GL_EXTCALL(glDeleteFramebuffersEXT(1, &fb));
459 glDeleteTextures(1, &tex);
461 checkGLcall("Framebuffer format check");
463 if(status != GL_FRAMEBUFFER_COMPLETE_EXT) {
464 TRACE("Internal format of %s not supported as frame buffer target, using render target internal instead\n",
465 debug_d3dformat(gl_formats_template[src].fmt));
466 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].rtInternal;
468 TRACE("Format %s is supported as fbo target\n", debug_d3dformat(gl_formats_template[src].fmt));
469 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].glInternal;
473 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].glInternal;
477 dst = getFmtIdx(WINED3DFMT_R16_FLOAT);
478 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
479 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
480 /* When ARB_texture_rg is supported we only require 16-bit for R16F instead of 64-bit RGBA16F */
481 if(GL_SUPPORT(ARB_TEXTURE_RG))
483 gl_info->gl_formats[dst].glInternal = GL_R16F;
484 gl_info->gl_formats[dst].glGammaInternal = GL_R16F;
487 dst = getFmtIdx(WINED3DFMT_R32_FLOAT);
488 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
489 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
490 /* When ARB_texture_rg is supported we only require 32-bit for R32F instead of 128-bit RGBA32F */
491 if(GL_SUPPORT(ARB_TEXTURE_RG))
493 gl_info->gl_formats[dst].glInternal = GL_R32F;
494 gl_info->gl_formats[dst].glGammaInternal = GL_R32F;
497 dst = getFmtIdx(WINED3DFMT_R16G16_UNORM);
498 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
499 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
501 dst = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
502 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
503 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
505 dst = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
506 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
507 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
509 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
510 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
511 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
512 * the only driver that implements it(fglrx) has a buggy implementation.
514 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
515 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
516 * conversion for this format.
518 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
520 dst = getFmtIdx(WINED3DFMT_R8G8_SNORM);
521 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
522 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
523 dst = getFmtIdx(WINED3DFMT_R16G16_SNORM);
524 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
525 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
529 dst = getFmtIdx(WINED3DFMT_R8G8_SNORM);
530 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
531 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
532 dst = getFmtIdx(WINED3DFMT_R16G16_SNORM);
533 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
534 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
537 if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
538 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
541 dst = getFmtIdx(WINED3DFMT_L6V5U5);
542 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
543 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
544 dst = getFmtIdx(WINED3DFMT_X8L8V8U8);
545 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
546 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
547 dst = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
548 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
549 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
551 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
552 * are converted at surface loading time, but they do not need any modification in
553 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
554 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
558 if(GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
559 dst = getFmtIdx(WINED3DFMT_ATI2N);
560 gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
561 gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
562 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
563 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
564 } else if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC)) {
565 dst = getFmtIdx(WINED3DFMT_ATI2N);
566 gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
567 gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
568 gl_info->gl_formats[dst].color_fixup= create_color_fixup_desc(
569 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
572 if(!GL_SUPPORT(APPLE_YCBCR_422)) {
573 dst = getFmtIdx(WINED3DFMT_YUY2);
574 gl_info->gl_formats[dst].glInternal = GL_LUMINANCE_ALPHA;
575 gl_info->gl_formats[dst].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
576 gl_info->gl_formats[dst].glFormat = GL_LUMINANCE_ALPHA;
577 gl_info->gl_formats[dst].glType = GL_UNSIGNED_BYTE;
578 gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
580 dst = getFmtIdx(WINED3DFMT_UYVY);
581 gl_info->gl_formats[dst].glInternal = GL_LUMINANCE_ALPHA;
582 gl_info->gl_formats[dst].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
583 gl_info->gl_formats[dst].glFormat = GL_LUMINANCE_ALPHA;
584 gl_info->gl_formats[dst].glType = GL_UNSIGNED_BYTE;
585 gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
588 dst = getFmtIdx(WINED3DFMT_YV12);
589 gl_info->gl_formats[dst].heightscale = 1.5;
590 gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
595 /* NOTE: Make sure these are in the correct numerical order. (see /include/wined3d_types.h) */
596 static WINED3DGLTYPE const glTypeLookupTemplate[WINED3DDECLTYPE_UNUSED] =
598 {WINED3DDECLTYPE_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
599 {WINED3DDECLTYPE_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
600 {WINED3DDECLTYPE_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
601 {WINED3DDECLTYPE_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
602 {WINED3DDECLTYPE_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
603 {WINED3DDECLTYPE_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
604 {WINED3DDECLTYPE_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
605 {WINED3DDECLTYPE_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
606 {WINED3DDECLTYPE_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
607 {WINED3DDECLTYPE_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
608 {WINED3DDECLTYPE_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
609 {WINED3DDECLTYPE_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
610 {WINED3DDECLTYPE_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
611 {WINED3DDECLTYPE_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
612 {WINED3DDECLTYPE_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
613 {WINED3DDECLTYPE_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
614 {WINED3DDECLTYPE_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
617 void init_type_lookup(WineD3D_GL_Info *gl_info) {
618 memcpy(gl_info->glTypeLookup, glTypeLookupTemplate, sizeof(glTypeLookupTemplate));
620 if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
622 gl_info->glTypeLookup[WINED3DDECLTYPE_D3DCOLOR].format = GL_BGRA;
625 if (GL_SUPPORT(NV_HALF_FLOAT))
627 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
628 * It is the job of the vertex buffer code to make sure that the vbos have the right format
630 gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_2].glType = GL_HALF_FLOAT_NV;
631 gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_4].glType = GL_HALF_FLOAT_NV;
635 #undef GLINFO_LOCATION
637 #define GLINFO_LOCATION This->adapter->gl_info
639 const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const WineD3D_GL_Info *gl_info)
641 int idx = getFmtIdx(fmt);
644 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
645 /* Get the caller a valid pointer */
646 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
649 return &gl_info->gl_formats[idx];
652 /*****************************************************************************
653 * Trace formatting of useful values
655 const char* debug_d3dformat(WINED3DFORMAT fmt) {
657 #define FMT_TO_STR(fmt) case fmt: return #fmt
658 FMT_TO_STR(WINED3DFMT_UNKNOWN);
659 FMT_TO_STR(WINED3DFMT_R8G8B8);
660 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
661 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
662 FMT_TO_STR(WINED3DFMT_R5G6B5);
663 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
664 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
665 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
666 FMT_TO_STR(WINED3DFMT_R3G3B2);
667 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
668 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
669 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
670 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
671 FMT_TO_STR(WINED3DFMT_A8P8);
672 FMT_TO_STR(WINED3DFMT_P8);
673 FMT_TO_STR(WINED3DFMT_L8);
674 FMT_TO_STR(WINED3DFMT_A8L8);
675 FMT_TO_STR(WINED3DFMT_A4L4);
676 FMT_TO_STR(WINED3DFMT_L6V5U5);
677 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
678 FMT_TO_STR(WINED3DFMT_W11V11U10);
679 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
680 FMT_TO_STR(WINED3DFMT_UYVY);
681 FMT_TO_STR(WINED3DFMT_YUY2);
682 FMT_TO_STR(WINED3DFMT_YV12);
683 FMT_TO_STR(WINED3DFMT_DXT1);
684 FMT_TO_STR(WINED3DFMT_DXT2);
685 FMT_TO_STR(WINED3DFMT_DXT3);
686 FMT_TO_STR(WINED3DFMT_DXT4);
687 FMT_TO_STR(WINED3DFMT_DXT5);
688 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
689 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
690 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
691 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
692 FMT_TO_STR(WINED3DFMT_D32);
693 FMT_TO_STR(WINED3DFMT_D15S1);
694 FMT_TO_STR(WINED3DFMT_D24S8);
695 FMT_TO_STR(WINED3DFMT_D24X8);
696 FMT_TO_STR(WINED3DFMT_D24X4S4);
697 FMT_TO_STR(WINED3DFMT_L16);
698 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
699 FMT_TO_STR(WINED3DFMT_D24FS8);
700 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
701 FMT_TO_STR(WINED3DFMT_CxV8U8);
702 FMT_TO_STR(WINED3DFMT_ATI2N);
703 FMT_TO_STR(WINED3DFMT_NVHU);
704 FMT_TO_STR(WINED3DFMT_NVHS);
705 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
706 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
707 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
708 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
709 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
710 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
711 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
712 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
713 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
714 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
715 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
716 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
717 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
718 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
719 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
720 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
721 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
722 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
723 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
724 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
725 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
726 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
727 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
728 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
729 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
730 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
731 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
732 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
733 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
734 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
735 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
736 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
737 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
738 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
739 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
740 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
741 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
742 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
743 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
744 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
745 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
746 FMT_TO_STR(WINED3DFMT_R32_UINT);
747 FMT_TO_STR(WINED3DFMT_R32_SINT);
748 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
749 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
750 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
751 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
752 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
753 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
754 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
755 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
756 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
757 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
758 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
759 FMT_TO_STR(WINED3DFMT_D16_UNORM);
760 FMT_TO_STR(WINED3DFMT_R16_UNORM);
761 FMT_TO_STR(WINED3DFMT_R16_UINT);
762 FMT_TO_STR(WINED3DFMT_R16_SNORM);
763 FMT_TO_STR(WINED3DFMT_R16_SINT);
764 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
765 FMT_TO_STR(WINED3DFMT_R8_UNORM);
766 FMT_TO_STR(WINED3DFMT_R8_UINT);
767 FMT_TO_STR(WINED3DFMT_R8_SNORM);
768 FMT_TO_STR(WINED3DFMT_R8_SINT);
769 FMT_TO_STR(WINED3DFMT_A8_UNORM);
770 FMT_TO_STR(WINED3DFMT_R1_UNORM);
771 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
772 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
773 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
774 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
775 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
776 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
777 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
778 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
779 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
780 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
781 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
782 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
783 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
784 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
785 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
786 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
787 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
788 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
789 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
790 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
791 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
792 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
797 fourcc[0] = (char)(fmt);
798 fourcc[1] = (char)(fmt >> 8);
799 fourcc[2] = (char)(fmt >> 16);
800 fourcc[3] = (char)(fmt >> 24);
802 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
803 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
805 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
807 return "unrecognized";
811 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
813 #define DEVTYPE_TO_STR(dev) case dev: return #dev
814 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
815 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
816 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
817 #undef DEVTYPE_TO_STR
819 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
820 return "unrecognized";
824 const char* debug_d3dusage(DWORD usage) {
825 switch (usage & WINED3DUSAGE_MASK) {
826 #define WINED3DUSAGE_TO_STR(u) case u: return #u
827 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
828 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
829 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
830 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
831 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
832 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
833 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
834 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
835 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
836 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
837 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
838 #undef WINED3DUSAGE_TO_STR
839 case 0: return "none";
841 FIXME("Unrecognized %u Usage!\n", usage);
842 return "unrecognized";
846 const char* debug_d3dusagequery(DWORD usagequery) {
847 switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
848 #define WINED3DUSAGEQUERY_TO_STR(u) case u: return #u
849 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
850 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
851 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
852 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
853 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
854 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
855 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
856 #undef WINED3DUSAGEQUERY_TO_STR
857 case 0: return "none";
859 FIXME("Unrecognized %u Usage Query!\n", usagequery);
860 return "unrecognized";
864 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
866 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
867 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
868 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
869 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
870 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
871 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
872 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
873 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
874 #undef WINED3DDECLMETHOD_TO_STR
876 FIXME("Unrecognized %u declaration method!\n", method);
877 return "unrecognized";
881 const char* debug_d3ddecltype(WINED3DDECLTYPE type) {
883 #define WINED3DDECLTYPE_TO_STR(u) case u: return #u
884 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT1);
885 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT2);
886 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT3);
887 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT4);
888 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_D3DCOLOR);
889 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4);
890 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2);
891 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4);
892 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4N);
893 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2N);
894 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4N);
895 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT2N);
896 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT4N);
897 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UDEC3);
898 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_DEC3N);
899 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_2);
900 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_4);
901 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UNUSED);
902 #undef WINED3DDECLTYPE_TO_STR
904 FIXME("Unrecognized %u declaration type!\n", type);
905 return "unrecognized";
909 const char* debug_d3ddeclusage(BYTE usage) {
911 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
912 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
913 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
914 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
915 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
916 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
917 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
918 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
919 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
920 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
921 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
922 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
923 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
924 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
925 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
926 #undef WINED3DDECLUSAGE_TO_STR
928 FIXME("Unrecognized %u declaration usage!\n", usage);
929 return "unrecognized";
933 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
935 #define RES_TO_STR(res) case res: return #res
936 RES_TO_STR(WINED3DRTYPE_SURFACE);
937 RES_TO_STR(WINED3DRTYPE_VOLUME);
938 RES_TO_STR(WINED3DRTYPE_TEXTURE);
939 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
940 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
941 RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER);
942 RES_TO_STR(WINED3DRTYPE_INDEXBUFFER);
943 RES_TO_STR(WINED3DRTYPE_BUFFER);
946 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
947 return "unrecognized";
951 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
952 switch (PrimitiveType) {
953 #define PRIM_TO_STR(prim) case prim: return #prim
954 PRIM_TO_STR(WINED3DPT_UNDEFINED);
955 PRIM_TO_STR(WINED3DPT_POINTLIST);
956 PRIM_TO_STR(WINED3DPT_LINELIST);
957 PRIM_TO_STR(WINED3DPT_LINESTRIP);
958 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
959 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
960 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
961 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
962 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
963 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
964 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
967 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
968 return "unrecognized";
972 const char* debug_d3drenderstate(DWORD state) {
974 #define D3DSTATE_TO_STR(u) case u: return #u
975 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
976 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
977 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
978 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
979 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
980 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
981 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
982 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
983 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
984 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
985 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
986 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
987 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
988 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
989 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
990 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
991 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
992 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
993 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
994 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
995 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
996 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
997 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
998 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
999 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1000 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1001 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1002 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1003 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1004 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1005 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1006 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1007 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1008 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1009 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1010 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1011 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1012 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1013 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1014 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1015 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1016 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
1017 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
1018 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
1019 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1020 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1021 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1022 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1023 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1024 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1025 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1026 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1027 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1028 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1029 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1030 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1031 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1032 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1033 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1034 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
1035 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
1036 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
1037 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
1038 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
1039 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
1040 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
1041 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
1042 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
1043 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
1044 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
1045 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
1046 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
1047 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
1048 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
1049 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
1050 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
1051 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
1052 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
1053 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
1054 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
1055 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
1056 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
1057 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
1058 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
1059 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
1060 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
1061 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
1062 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
1063 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
1064 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
1065 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
1066 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1067 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1068 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1069 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1070 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1071 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1072 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1073 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1074 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1075 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1076 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1077 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1078 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1079 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1080 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1081 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1082 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1083 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1084 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1085 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1086 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1087 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1088 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1089 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1090 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1091 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1092 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1093 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1094 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1095 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1096 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1097 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1098 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1099 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1100 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1101 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1102 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1103 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1104 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1105 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1106 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1107 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1108 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1109 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1110 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1111 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1112 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1113 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1114 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1115 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1116 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1117 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1118 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1119 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1120 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1121 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1122 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1123 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1124 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1125 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1126 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1127 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1128 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1129 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1130 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1131 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1132 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1133 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1134 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1135 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1136 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1137 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1138 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1139 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1140 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1141 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1142 #undef D3DSTATE_TO_STR
1144 FIXME("Unrecognized %u render state!\n", state);
1145 return "unrecognized";
1149 const char* debug_d3dsamplerstate(DWORD state) {
1151 #define D3DSTATE_TO_STR(u) case u: return #u
1152 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1153 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1154 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1155 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1156 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1157 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1158 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1159 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1160 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1161 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1162 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1163 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1164 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1165 #undef D3DSTATE_TO_STR
1167 FIXME("Unrecognized %u sampler state!\n", state);
1168 return "unrecognized";
1172 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1173 switch (filter_type) {
1174 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1175 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1176 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1177 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1178 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1179 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1180 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1181 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1182 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1183 #undef D3DTEXTUREFILTERTYPE_TO_STR
1185 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1186 return "unrecognized";
1190 const char* debug_d3dtexturestate(DWORD state) {
1192 #define D3DSTATE_TO_STR(u) case u: return #u
1193 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1194 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1195 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1196 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1197 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1198 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1199 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1200 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1201 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1202 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1203 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1204 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1205 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1206 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1207 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1208 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1209 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1210 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1211 #undef D3DSTATE_TO_STR
1213 FIXME("Unrecognized %u texture state!\n", state);
1214 return "unrecognized";
1218 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1220 #define D3DTOP_TO_STR(u) case u: return #u
1221 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1222 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1223 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1224 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1225 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1226 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1227 D3DTOP_TO_STR(WINED3DTOP_ADD);
1228 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1229 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1230 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1231 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1232 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1233 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1234 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1235 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1236 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1237 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1238 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1239 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1240 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1241 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1242 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1243 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1244 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1245 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1246 D3DTOP_TO_STR(WINED3DTOP_LERP);
1247 #undef D3DTOP_TO_STR
1249 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1250 return "unrecognized";
1254 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1256 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1257 TSTYPE_TO_STR(WINED3DTS_VIEW);
1258 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1259 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1260 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1261 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1262 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1263 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1264 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1265 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1266 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1267 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1268 #undef TSTYPE_TO_STR
1270 if (tstype > 256 && tstype < 512) {
1271 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1272 return ("WINED3DTS_WORLDMATRIX > 0");
1274 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1275 return "unrecognized";
1279 const char* debug_d3dpool(WINED3DPOOL Pool) {
1281 #define POOL_TO_STR(p) case p: return #p
1282 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1283 POOL_TO_STR(WINED3DPOOL_MANAGED);
1284 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1285 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1288 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1289 return "unrecognized";
1293 const char *debug_fbostatus(GLenum status) {
1295 #define FBOSTATUS_TO_STR(u) case u: return #u
1296 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1297 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1298 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1299 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1300 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1301 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1302 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1303 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
1304 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1305 #undef FBOSTATUS_TO_STR
1307 FIXME("Unrecognied FBO status 0x%08x\n", status);
1308 return "unrecognized";
1312 const char *debug_glerror(GLenum error) {
1314 #define GLERROR_TO_STR(u) case u: return #u
1315 GLERROR_TO_STR(GL_NO_ERROR);
1316 GLERROR_TO_STR(GL_INVALID_ENUM);
1317 GLERROR_TO_STR(GL_INVALID_VALUE);
1318 GLERROR_TO_STR(GL_INVALID_OPERATION);
1319 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1320 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1321 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1322 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1323 #undef GLERROR_TO_STR
1325 FIXME("Unrecognied GL error 0x%08x\n", error);
1326 return "unrecognized";
1330 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1332 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1333 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1334 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1335 default: return "unrecognized";
1339 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1341 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1342 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1343 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1344 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1345 default: return "unrecognized";
1349 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
1353 #define WINED3D_TO_STR(x) case x: return #x
1354 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1355 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1356 WINED3D_TO_STR(CHANNEL_SOURCE_X);
1357 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1358 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1359 WINED3D_TO_STR(CHANNEL_SOURCE_W);
1360 WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1361 WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1362 #undef WINED3D_TO_STR
1364 FIXME("Unrecognized fixup_channel_source %#x\n", source);
1365 return "unrecognized";
1369 static const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1373 #define WINED3D_TO_STR(x) case x: return #x
1374 WINED3D_TO_STR(YUV_FIXUP_YUY2);
1375 WINED3D_TO_STR(YUV_FIXUP_UYVY);
1376 WINED3D_TO_STR(YUV_FIXUP_YV12);
1377 #undef WINED3D_TO_STR
1379 FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1380 return "unrecognized";
1384 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1386 if (is_yuv_fixup(fixup))
1388 TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1392 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1393 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1394 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1395 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1398 const char *debug_surflocation(DWORD flag) {
1402 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
1403 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
1404 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
1405 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
1406 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
1409 /*****************************************************************************
1410 * Useful functions mapping GL <-> D3D values
1412 GLenum StencilOp(DWORD op) {
1414 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1415 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1416 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1417 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1418 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1419 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1420 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1421 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1423 FIXME("Unrecognized stencil op %d\n", op);
1428 GLenum CompareFunc(DWORD func) {
1429 switch ((WINED3DCMPFUNC)func) {
1430 case WINED3DCMP_NEVER : return GL_NEVER;
1431 case WINED3DCMP_LESS : return GL_LESS;
1432 case WINED3DCMP_EQUAL : return GL_EQUAL;
1433 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1434 case WINED3DCMP_GREATER : return GL_GREATER;
1435 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1436 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1437 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1439 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1444 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1445 if (op == WINED3DTOP_DISABLE) return FALSE;
1446 if (This->stateBlock->textures[stage]) return FALSE;
1448 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1449 && op != WINED3DTOP_SELECTARG2) return TRUE;
1450 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1451 && op != WINED3DTOP_SELECTARG1) return TRUE;
1452 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1453 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1458 /* Setup this textures matrix according to the texture flags*/
1459 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype,
1460 BOOL ffp_proj_control)
1464 glMatrixMode(GL_TEXTURE);
1465 checkGLcall("glMatrixMode(GL_TEXTURE)");
1467 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1469 checkGLcall("glLoadIdentity()");
1473 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1474 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1478 memcpy(mat, smat, 16 * sizeof(float));
1480 if (flags & WINED3DTTFF_PROJECTED) {
1481 if(!ffp_proj_control) {
1482 switch (flags & ~WINED3DTTFF_PROJECTED) {
1483 case WINED3DTTFF_COUNT2:
1484 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1485 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1487 case WINED3DTTFF_COUNT3:
1488 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1489 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1493 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1494 if(!calculatedCoords) {
1496 case WINED3DDECLTYPE_FLOAT1:
1497 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1498 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1499 * the input value to the transformation will be 0, so the matrix value is irrelevant
1506 case WINED3DDECLTYPE_FLOAT2:
1507 /* See above, just 3rd and 4th coord
1514 case WINED3DDECLTYPE_FLOAT3: /* Opengl defaults match dx defaults */
1515 case WINED3DDECLTYPE_FLOAT4: /* No defaults apply, all app defined */
1517 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1518 * into a bad place. The division elimination below will apply to make sure the
1519 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1521 case WINED3DDECLTYPE_UNUSED: /* No texture coords, 0/0/0/1 defaults are passed */
1524 FIXME("Unexpected fixed function texture coord input\n");
1527 if(!ffp_proj_control) {
1528 switch (flags & ~WINED3DTTFF_PROJECTED) {
1529 /* case WINED3DTTFF_COUNT1: Won't ever get here */
1530 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
1531 /* OpenGL divides the first 3 vertex coord by the 4th by default,
1532 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
1533 * the 4th coord evaluates to 1.0 to eliminate that.
1535 * If the fixed function pipeline is used, the 4th value remains unused,
1536 * so there is no danger in doing this. With vertex shaders we have a
1537 * problem. Should an app hit that problem, the code here would have to
1538 * check for pixel shaders, and the shader has to undo the default gl divide.
1540 * A more serious problem occurs if the app passes 4 coordinates in, and the
1541 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
1542 * or a replacement shader
1544 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
1550 checkGLcall("glLoadMatrixf(mat)");
1552 #undef GLINFO_LOCATION
1554 /* This small helper function is used to convert a bitmask into the number of masked bits */
1555 unsigned int count_bits(unsigned int mask)
1558 for (count = 0; mask; ++count)
1565 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
1566 * The later function requires individual color components. */
1567 BOOL getColorBits(const struct GlPixelFormatDesc *format_desc,
1568 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
1570 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
1571 switch(format_desc->format)
1573 case WINED3DFMT_X8R8G8B8:
1574 case WINED3DFMT_R8G8B8:
1575 case WINED3DFMT_A8R8G8B8:
1576 case WINED3DFMT_R8G8B8A8_UNORM:
1577 case WINED3DFMT_A2R10G10B10:
1578 case WINED3DFMT_X1R5G5B5:
1579 case WINED3DFMT_A1R5G5B5:
1580 case WINED3DFMT_R5G6B5:
1581 case WINED3DFMT_X4R4G4B4:
1582 case WINED3DFMT_A4R4G4B4:
1583 case WINED3DFMT_R3G3B2:
1584 case WINED3DFMT_A8P8:
1588 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
1592 *redSize = count_bits(format_desc->red_mask);
1593 *greenSize = count_bits(format_desc->green_mask);
1594 *blueSize = count_bits(format_desc->blue_mask);
1595 *alphaSize = count_bits(format_desc->alpha_mask);
1596 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
1598 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
1599 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
1603 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
1604 BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize)
1606 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
1607 switch(format_desc->format)
1609 case WINED3DFMT_D16_LOCKABLE:
1610 case WINED3DFMT_D16_UNORM:
1611 case WINED3DFMT_D15S1:
1612 case WINED3DFMT_D24X8:
1613 case WINED3DFMT_D24X4S4:
1614 case WINED3DFMT_D24S8:
1615 case WINED3DFMT_D24FS8:
1616 case WINED3DFMT_D32:
1617 case WINED3DFMT_D32F_LOCKABLE:
1620 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
1624 *depthSize = format_desc->depth_size;
1625 *stencilSize = format_desc->stencil_size;
1627 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
1628 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
1632 /* DirectDraw stuff */
1633 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
1635 case 8: return WINED3DFMT_P8;
1636 case 15: return WINED3DFMT_X1R5G5B5;
1637 case 16: return WINED3DFMT_R5G6B5;
1638 case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
1639 case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
1640 default: return WINED3DFMT_UNKNOWN;
1644 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
1647 /* Now do the multiplication 'by hand'.
1648 I know that all this could be optimised, but this will be done later :-) */
1649 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);
1650 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);
1651 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);
1652 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);
1654 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);
1655 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);
1656 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);
1657 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);
1659 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);
1660 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);
1661 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);
1662 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);
1664 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);
1665 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);
1666 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);
1667 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);
1669 /* And copy the new matrix in the good storage.. */
1670 memcpy(dest, &temp, 16 * sizeof(float));
1673 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
1676 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
1678 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
1679 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
1680 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
1681 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
1682 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
1683 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
1684 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
1685 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
1686 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
1687 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
1688 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
1689 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
1690 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
1691 default: ERR("Unexpected position mask\n");
1693 for (i = 0; i < numTextures; i++) {
1694 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
1700 /***********************************************************************
1703 * Calculates the dimensions of the opengl texture used for blits.
1704 * Handled oversized opengl textures and updates the source rectangle
1708 * This: Surface to operate on
1709 * Rect: Requested rectangle
1712 * TRUE if the texture part can be loaded,
1715 *********************************************************************/
1716 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
1718 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
1719 int x1 = Rect->left, x2 = Rect->right;
1720 int y1 = Rect->top, y2 = Rect->bottom;
1721 GLint maxSize = GL_LIMITS(texture_size);
1723 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
1724 Rect->left, Rect->top, Rect->right, Rect->bottom);
1726 /* The sizes might be reversed */
1727 if(Rect->left > Rect->right) {
1731 if(Rect->top > Rect->bottom) {
1736 /* No oversized texture? This is easy */
1737 if(!(This->Flags & SFLAG_OVERSIZE)) {
1738 /* Which rect from the texture do I need? */
1739 if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
1740 glTexCoord[0] = (float) Rect->left;
1741 glTexCoord[2] = (float) Rect->top;
1742 glTexCoord[1] = (float) Rect->right;
1743 glTexCoord[3] = (float) Rect->bottom;
1745 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
1746 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
1747 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
1748 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
1753 /* Check if we can succeed at all */
1754 if( (x2 - x1) > maxSize ||
1755 (y2 - y1) > maxSize ) {
1756 TRACE("Requested rectangle is too large for gl\n");
1760 /* A part of the texture has to be picked. First, check if
1761 * some texture part is loaded already, if yes try to re-use it.
1762 * If the texture is dirty, or the part can't be used,
1763 * re-position the part to load
1765 if(This->Flags & SFLAG_INTEXTURE) {
1766 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
1767 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
1768 /* Ok, the rectangle is ok, re-use it */
1769 TRACE("Using existing gl Texture\n");
1771 /* Rectangle is not ok, dirtify the texture to reload it */
1772 TRACE("Dirtifying texture to force reload\n");
1773 This->Flags &= ~SFLAG_INTEXTURE;
1777 /* Now if we are dirty(no else if!) */
1778 if(!(This->Flags & SFLAG_INTEXTURE)) {
1779 /* Set the new rectangle. Use the following strategy:
1780 * 1) Use as big textures as possible.
1781 * 2) Place the texture part in the way that the requested
1782 * part is in the middle of the texture(well, almost)
1783 * 3) If the texture is moved over the edges of the
1784 * surface, replace it nicely
1785 * 4) If the coord is not limiting the texture size,
1786 * use the whole size
1788 if((This->pow2Width) > maxSize) {
1789 This->glRect.left = x1 - maxSize / 2;
1790 if(This->glRect.left < 0) {
1791 This->glRect.left = 0;
1793 This->glRect.right = This->glRect.left + maxSize;
1794 if(This->glRect.right > This->currentDesc.Width) {
1795 This->glRect.right = This->currentDesc.Width;
1796 This->glRect.left = This->glRect.right - maxSize;
1799 This->glRect.left = 0;
1800 This->glRect.right = This->pow2Width;
1803 if(This->pow2Height > maxSize) {
1804 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
1805 if(This->glRect.top < 0) This->glRect.top = 0;
1806 This->glRect.bottom = This->glRect.left + maxSize;
1807 if(This->glRect.bottom > This->currentDesc.Height) {
1808 This->glRect.bottom = This->currentDesc.Height;
1809 This->glRect.top = This->glRect.bottom - maxSize;
1812 This->glRect.top = 0;
1813 This->glRect.bottom = This->pow2Height;
1815 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
1816 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
1819 /* Re-calculate the rect to draw */
1820 Rect->left -= This->glRect.left;
1821 Rect->right -= This->glRect.left;
1822 Rect->top -= This->glRect.top;
1823 Rect->bottom -= This->glRect.top;
1825 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
1826 * or the pow2Width / pow2Height of the surface.
1828 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
1829 * as regular GL_TEXTURE_2D.
1831 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
1832 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
1833 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
1834 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
1838 #undef GLINFO_LOCATION
1840 /* Hash table functions */
1842 struct hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
1844 struct hash_table_t *table;
1845 unsigned int initial_size = 8;
1847 table = HeapAlloc(GetProcessHeap(), 0, sizeof(struct hash_table_t) + (initial_size * sizeof(struct list)));
1850 ERR("Failed to allocate table, returning NULL.\n");
1854 table->hash_function = hash_function;
1855 table->compare_function = compare_function;
1857 table->grow_size = initial_size - (initial_size >> 2);
1858 table->shrink_size = 0;
1860 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
1861 if (!table->buckets)
1863 ERR("Failed to allocate table buckets, returning NULL.\n");
1864 HeapFree(GetProcessHeap(), 0, table);
1867 table->bucket_count = initial_size;
1869 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(struct hash_table_entry_t));
1870 if (!table->entries)
1872 ERR("Failed to allocate table entries, returning NULL.\n");
1873 HeapFree(GetProcessHeap(), 0, table->buckets);
1874 HeapFree(GetProcessHeap(), 0, table);
1877 table->entry_count = 0;
1879 list_init(&table->free_entries);
1885 void hash_table_destroy(struct hash_table_t *table, void (*free_value)(void *value, void *cb), void *cb)
1889 for (i = 0; i < table->entry_count; ++i)
1892 free_value(table->entries[i].value, cb);
1894 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
1897 HeapFree(GetProcessHeap(), 0, table->entries);
1898 HeapFree(GetProcessHeap(), 0, table->buckets);
1899 HeapFree(GetProcessHeap(), 0, table);
1902 void hash_table_for_each_entry(struct hash_table_t *table, void (*callback)(void *value, void *context), void *context)
1906 for (i = 0; i < table->entry_count; ++i)
1908 callback(table->entries[i].value, context);
1912 static inline struct hash_table_entry_t *hash_table_get_by_idx(const struct hash_table_t *table, const void *key,
1915 struct hash_table_entry_t *entry;
1917 if (table->buckets[idx].next)
1918 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), struct hash_table_entry_t, entry)
1919 if (table->compare_function(entry->key, key)) return entry;
1924 static BOOL hash_table_resize(struct hash_table_t *table, unsigned int new_bucket_count)
1926 unsigned int new_entry_count = 0;
1927 struct hash_table_entry_t *new_entries;
1928 struct list *new_buckets;
1929 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
1932 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
1935 ERR("Failed to allocate new buckets, returning FALSE.\n");
1939 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(struct hash_table_entry_t));
1942 ERR("Failed to allocate new entries, returning FALSE.\n");
1943 HeapFree(GetProcessHeap(), 0, new_buckets);
1947 for (i = 0; i < table->bucket_count; ++i)
1949 if (table->buckets[i].next)
1951 struct hash_table_entry_t *entry, *entry2;
1953 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], struct hash_table_entry_t, entry)
1956 struct hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
1957 *new_entry = *entry;
1959 j = new_entry->hash & (new_bucket_count - 1);
1961 if (!new_buckets[j].next) list_init(&new_buckets[j]);
1962 list_add_head(&new_buckets[j], &new_entry->entry);
1967 HeapFree(GetProcessHeap(), 0, table->buckets);
1968 table->buckets = new_buckets;
1970 HeapFree(GetProcessHeap(), 0, table->entries);
1971 table->entries = new_entries;
1973 table->entry_count = new_entry_count;
1974 list_init(&table->free_entries);
1976 table->bucket_count = new_bucket_count;
1977 table->grow_size = grow_size;
1978 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
1983 void hash_table_put(struct hash_table_t *table, void *key, void *value)
1987 struct hash_table_entry_t *entry;
1989 hash = table->hash_function(key);
1990 idx = hash & (table->bucket_count - 1);
1991 entry = hash_table_get_by_idx(table, key, idx);
1995 HeapFree(GetProcessHeap(), 0, key);
1996 entry->value = value;
2000 HeapFree(GetProcessHeap(), 0, entry->key);
2003 /* Remove the entry */
2004 list_remove(&entry->entry);
2005 list_add_head(&table->free_entries, &entry->entry);
2009 /* Shrink if necessary */
2010 if (table->count < table->shrink_size) {
2011 if (!hash_table_resize(table, table->bucket_count >> 1))
2013 ERR("Failed to shrink the table...\n");
2023 /* Grow if necessary */
2024 if (table->count >= table->grow_size)
2026 if (!hash_table_resize(table, table->bucket_count << 1))
2028 ERR("Failed to grow the table, returning.\n");
2032 idx = hash & (table->bucket_count - 1);
2035 /* Find an entry to insert */
2036 if (!list_empty(&table->free_entries))
2038 struct list *elem = list_head(&table->free_entries);
2041 entry = LIST_ENTRY(elem, struct hash_table_entry_t, entry);
2043 entry = table->entries + (table->entry_count++);
2046 /* Insert the entry */
2048 entry->value = value;
2050 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
2051 list_add_head(&table->buckets[idx], &entry->entry);
2056 void hash_table_remove(struct hash_table_t *table, void *key)
2058 hash_table_put(table, key, NULL);
2061 void *hash_table_get(const struct hash_table_t *table, const void *key)
2064 struct hash_table_entry_t *entry;
2066 idx = table->hash_function(key) & (table->bucket_count - 1);
2067 entry = hash_table_get_by_idx(table, key, idx);
2069 return entry ? entry->value : NULL;
2072 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2073 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2077 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2079 /* D3DTOP_DISABLE */ 0,
2080 /* D3DTOP_SELECTARG1 */ ARG1,
2081 /* D3DTOP_SELECTARG2 */ ARG2,
2082 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2083 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2084 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2085 /* D3DTOP_ADD */ ARG1 | ARG2,
2086 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2087 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2088 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2089 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2090 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2091 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2092 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2093 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2094 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2095 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2096 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2097 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2098 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2099 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2100 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2101 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2102 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2103 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2104 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2108 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2110 for(i = 0; i < GL_LIMITS(texture_stages); i++) {
2111 IWineD3DBaseTextureImpl *texture;
2112 settings->op[i].padding = 0;
2113 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2114 settings->op[i].cop = WINED3DTOP_DISABLE;
2115 settings->op[i].aop = WINED3DTOP_DISABLE;
2116 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2117 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2118 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2119 settings->op[i].dst = resultreg;
2120 settings->op[i].tex_type = tex_1d;
2121 settings->op[i].projected = proj_none;
2126 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2128 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2129 if(ignore_textype) {
2130 settings->op[i].tex_type = tex_1d;
2132 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2134 settings->op[i].tex_type = tex_1d;
2137 settings->op[i].tex_type = tex_2d;
2140 settings->op[i].tex_type = tex_3d;
2142 case GL_TEXTURE_CUBE_MAP_ARB:
2143 settings->op[i].tex_type = tex_cube;
2145 case GL_TEXTURE_RECTANGLE_ARB:
2146 settings->op[i].tex_type = tex_rect;
2151 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2152 settings->op[i].tex_type = tex_1d;
2155 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2156 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2158 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2159 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2160 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2162 if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
2163 carg1, carg2, carg0)) {
2166 carg1 = WINED3DTA_CURRENT;
2167 cop = WINED3DTOP_SELECTARG1;
2170 if(cop == WINED3DTOP_DOTPRODUCT3) {
2171 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2172 * the color result to the alpha component of the destination
2179 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2180 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2181 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2184 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2186 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2188 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2190 IWineD3DSurfaceImpl *surf;
2191 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2193 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2195 if (aop == WINED3DTOP_DISABLE)
2197 aarg1 = WINED3DTA_TEXTURE;
2198 aop = WINED3DTOP_SELECTARG1;
2200 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2202 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2204 aarg2 = WINED3DTA_TEXTURE;
2205 aop = WINED3DTOP_MODULATE;
2207 else aarg1 = WINED3DTA_TEXTURE;
2209 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2211 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2213 aarg1 = WINED3DTA_TEXTURE;
2214 aop = WINED3DTOP_MODULATE;
2216 else aarg2 = WINED3DTA_TEXTURE;
2222 if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
2223 aarg1, aarg2, aarg0)) {
2226 aarg1 = WINED3DTA_CURRENT;
2227 aop = WINED3DTOP_SELECTARG1;
2230 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2231 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2232 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2233 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2234 settings->op[i].projected = proj_count3;
2235 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2236 settings->op[i].projected = proj_count4;
2238 settings->op[i].projected = proj_none;
2241 settings->op[i].projected = proj_none;
2244 settings->op[i].cop = cop;
2245 settings->op[i].aop = aop;
2246 settings->op[i].carg0 = carg0;
2247 settings->op[i].carg1 = carg1;
2248 settings->op[i].carg2 = carg2;
2249 settings->op[i].aarg0 = aarg0;
2250 settings->op[i].aarg1 = aarg1;
2251 settings->op[i].aarg2 = aarg2;
2253 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2254 settings->op[i].dst = tempreg;
2256 settings->op[i].dst = resultreg;
2260 /* Clear unsupported stages */
2261 for(; i < MAX_TEXTURES; i++) {
2262 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2265 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2266 settings->fog = FOG_OFF;
2267 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2268 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2269 settings->fog = FOG_LINEAR;
2271 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2272 case WINED3DFOG_NONE:
2273 case WINED3DFOG_LINEAR:
2274 settings->fog = FOG_LINEAR;
2276 case WINED3DFOG_EXP:
2277 settings->fog = FOG_EXP;
2279 case WINED3DFOG_EXP2:
2280 settings->fog = FOG_EXP2;
2285 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2286 case WINED3DFOG_LINEAR:
2287 settings->fog = FOG_LINEAR;
2289 case WINED3DFOG_EXP:
2290 settings->fog = FOG_EXP;
2292 case WINED3DFOG_EXP2:
2293 settings->fog = FOG_EXP2;
2297 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2298 settings->sRGB_write = 1;
2300 settings->sRGB_write = 0;
2303 #undef GLINFO_LOCATION
2305 const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
2306 const struct ffp_frag_settings *settings)
2308 return hash_table_get(fragment_shaders, settings);
2311 void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *desc) {
2312 struct ffp_frag_settings *key = HeapAlloc(GetProcessHeap(), 0, sizeof(*key));
2313 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2314 * whereas desc points to an extended structure with implementation specific parts.
2315 * Make a copy of the key because hash_table_put takes ownership of it
2317 *key = desc->settings;
2318 hash_table_put(shaders, key, desc);
2321 /* Activates the texture dimension according to the bound D3D texture.
2322 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2323 * Requires the caller to activate the correct unit before
2325 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2326 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2327 if(stateblock->textures[stage]) {
2328 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2330 glDisable(GL_TEXTURE_3D);
2331 checkGLcall("glDisable(GL_TEXTURE_3D)");
2332 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2333 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2334 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2336 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2337 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2338 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2340 glEnable(GL_TEXTURE_2D);
2341 checkGLcall("glEnable(GL_TEXTURE_2D)");
2343 case GL_TEXTURE_RECTANGLE_ARB:
2344 glDisable(GL_TEXTURE_2D);
2345 checkGLcall("glDisable(GL_TEXTURE_2D)");
2346 glDisable(GL_TEXTURE_3D);
2347 checkGLcall("glDisable(GL_TEXTURE_3D)");
2348 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2349 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2350 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2352 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2353 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2356 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2357 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2358 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2360 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2361 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2362 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2364 glDisable(GL_TEXTURE_2D);
2365 checkGLcall("glDisable(GL_TEXTURE_2D)");
2366 glEnable(GL_TEXTURE_3D);
2367 checkGLcall("glEnable(GL_TEXTURE_3D)");
2369 case GL_TEXTURE_CUBE_MAP_ARB:
2370 glDisable(GL_TEXTURE_2D);
2371 checkGLcall("glDisable(GL_TEXTURE_2D)");
2372 glDisable(GL_TEXTURE_3D);
2373 checkGLcall("glDisable(GL_TEXTURE_3D)");
2374 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2375 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2376 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2378 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2379 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2383 glEnable(GL_TEXTURE_2D);
2384 checkGLcall("glEnable(GL_TEXTURE_2D)");
2385 glDisable(GL_TEXTURE_3D);
2386 checkGLcall("glDisable(GL_TEXTURE_3D)");
2387 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2388 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2389 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2391 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2392 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2393 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2395 /* Binding textures is done by samplers. A dummy texture will be bound */
2399 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2400 DWORD sampler = state - STATE_SAMPLER(0);
2401 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2403 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2404 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2405 * will take care of this business
2407 if(mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= GL_LIMITS(textures)) return;
2408 if(sampler >= stateblock->lowest_disabled_stage) return;
2409 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2411 texture_activate_dimensions(sampler, stateblock, context);
2413 #undef GLINFO_LOCATION
2415 unsigned int ffp_frag_program_key_hash(const void *key)
2417 const struct ffp_frag_settings *k = key;
2418 unsigned int hash = 0, i;
2421 /* This takes the texture op settings of stage 0 and 1 into account.
2422 * how exactly depends on the memory laybout of the compiler, but it
2423 * should not matter too much. Stages > 1 are used rarely, so there's
2424 * no need to process them. Even if they're used it is likely that
2425 * the ffp setup has distinct stage 0 and 1 settings.
2427 for(i = 0; i < 2; i++) {
2428 blob = (const DWORD *)&k->op[i];
2429 hash ^= blob[0] ^ blob[1];
2432 hash += ~(hash << 15);
2433 hash ^= (hash >> 10);
2434 hash += (hash << 3);
2435 hash ^= (hash >> 6);
2436 hash += ~(hash << 11);
2437 hash ^= (hash >> 16);
2442 BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb)
2444 const struct ffp_frag_settings *ka = keya;
2445 const struct ffp_frag_settings *kb = keyb;
2447 return memcmp(ka, kb, sizeof(*ka)) == 0;
2450 UINT wined3d_log2i(UINT32 x)
2452 static const BYTE l[] =
2454 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2455 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2456 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2457 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2458 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2459 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2460 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2461 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2462 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2463 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2464 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2465 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2466 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2467 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2468 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2469 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2473 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];