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 /*****************************************************************************
34 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
35 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
36 * high masks do not fit into the 32 bit values needed for ddraw. It is only
37 * used for ddraw mostly, and to figure out if the format has alpha at all, so
38 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
39 * formats are not usable in 2D rendering because ddraw doesn't support them.
41 static const StaticPixelFormatDesc formats[] = {
42 /* WINED3DFORMAT alphamask redmask greenmask bluemask bpp depth stencil isFourcc */
43 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
44 /* FourCC formats, kept here to have WINED3DFMT_R8G8B8(=20) at position 20 */
45 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
46 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
47 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
48 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
49 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
50 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
51 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
52 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
53 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
54 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
55 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
57 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
58 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
59 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0, FALSE},
61 {WINED3DFMT_CxV8U8, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
63 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
64 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
65 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
66 /* Palettized formats */
67 {WINED3DFMT_A8P8, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
68 {WINED3DFMT_P8, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
69 /* Standard ARGB formats. Keep WINED3DFMT_R8G8B8(=20) at position 20 */
70 {WINED3DFMT_R8G8B8, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0, FALSE},
71 {WINED3DFMT_A8R8G8B8, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0, FALSE},
72 {WINED3DFMT_X8R8G8B8, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0, FALSE},
73 {WINED3DFMT_R5G6B5, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0, FALSE},
74 {WINED3DFMT_X1R5G5B5, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0, FALSE},
75 {WINED3DFMT_A1R5G5B5, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0, FALSE},
76 {WINED3DFMT_A4R4G4B4, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0, FALSE},
77 {WINED3DFMT_R3G3B2, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0, FALSE},
78 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
79 {WINED3DFMT_A8R3G3B2, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0, FALSE},
80 {WINED3DFMT_X4R4G4B4, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0, FALSE},
81 {WINED3DFMT_R10G10B10A2_UNORM, 0xb0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
82 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
83 {WINED3DFMT_X8B8G8R8, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
84 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0, FALSE},
85 {WINED3DFMT_A2R10G10B10, 0xb0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0, FALSE},
86 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0, FALSE},
88 {WINED3DFMT_L8, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
89 {WINED3DFMT_A8L8, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
90 {WINED3DFMT_A4L4, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
91 /* Bump mapping stuff */
92 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
93 {WINED3DFMT_L6V5U5, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
94 {WINED3DFMT_X8L8V8U8, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
95 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
96 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
97 {WINED3DFMT_W11V11U10, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
98 {WINED3DFMT_A2W10V10U10, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
99 /* Depth stencil formats */
100 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
101 {WINED3DFMT_D32, 0x0, 0x0, 0x0, 0x0, 4, 32, 0, FALSE},
102 {WINED3DFMT_D15S1, 0x0, 0x0, 0x0, 0x0, 2, 15, 1, FALSE},
103 {WINED3DFMT_D24S8, 0x0, 0x0, 0x0, 0x0, 4, 24, 8, FALSE},
104 {WINED3DFMT_D24X8, 0x0, 0x0, 0x0, 0x0, 4, 24, 0, FALSE},
105 {WINED3DFMT_D24X4S4, 0x0, 0x0, 0x0, 0x0, 4, 24, 4, FALSE},
106 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
107 {WINED3DFMT_L16, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
108 {WINED3DFMT_D32F_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 4, 32, 0, FALSE},
109 {WINED3DFMT_D24FS8, 0x0, 0x0, 0x0, 0x0, 4, 24, 8, FALSE},
110 /* Is this a vertex buffer? */
111 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, FALSE},
112 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
113 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
114 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
115 /* Vendor-specific formats */
116 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
117 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
118 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
123 GLint glInternal, glGammaInternal, rtInternal, glFormat, glType;
125 } GlPixelFormatDescTemplate;
127 /*****************************************************************************
128 * OpenGL format template. Contains unexciting formats which do not need
129 * extension checks. The order in this table is independent of the order in
130 * the table StaticPixelFormatDesc above. Not all formats have to be in this
133 static const GlPixelFormatDescTemplate gl_formats_template[] = {
134 /* WINED3DFORMAT internal srgbInternal rtInternal
137 {WINED3DFMT_UNKNOWN, 0, 0, 0,
141 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
142 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
143 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
144 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
147 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
148 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE,
149 WINED3DFMT_FLAG_FILTERING},
150 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
151 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE,
152 WINED3DFMT_FLAG_FILTERING},
153 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
154 GL_ALPHA, GL_UNSIGNED_BYTE,
155 WINED3DFMT_FLAG_FILTERING},
156 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
157 GL_RGBA, GL_UNSIGNED_BYTE,
158 WINED3DFMT_FLAG_FILTERING},
159 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
160 GL_RGBA, GL_UNSIGNED_BYTE,
161 WINED3DFMT_FLAG_FILTERING},
162 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
163 GL_RGBA, GL_UNSIGNED_BYTE,
164 WINED3DFMT_FLAG_FILTERING},
165 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
166 GL_RGBA, GL_UNSIGNED_BYTE,
167 WINED3DFMT_FLAG_FILTERING},
168 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
169 GL_RGBA, GL_UNSIGNED_BYTE,
170 WINED3DFMT_FLAG_FILTERING},
171 {WINED3DFMT_MULTI2_ARGB8, 0, 0, 0,
174 {WINED3DFMT_G8R8_G8B8, 0, 0, 0,
177 {WINED3DFMT_R8G8_B8G8, 0, 0, 0,
181 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
183 WINED3DFMT_FLAG_RENDERTARGET},
184 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
186 WINED3DFMT_FLAG_RENDERTARGET},
187 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
189 WINED3DFMT_FLAG_RENDERTARGET},
191 {WINED3DFMT_CxV8U8, 0, 0, 0,
195 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
196 GL_RED, GL_HALF_FLOAT_ARB,
197 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
198 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
199 GL_RG, GL_HALF_FLOAT_ARB,
200 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
201 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
202 GL_RGBA, GL_HALF_FLOAT_ARB,
203 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
204 /* Palettized formats */
205 {WINED3DFMT_A8P8, 0, 0, 0,
208 {WINED3DFMT_P8, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
209 GL_COLOR_INDEX, GL_UNSIGNED_BYTE,
211 /* Standard ARGB formats */
212 {WINED3DFMT_R8G8B8, GL_RGB8, GL_RGB8, 0,
213 GL_BGR, GL_UNSIGNED_BYTE,
214 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
215 {WINED3DFMT_A8R8G8B8, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
216 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
217 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
218 {WINED3DFMT_X8R8G8B8, GL_RGB8, GL_SRGB8_EXT, 0,
219 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
220 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
221 {WINED3DFMT_R5G6B5, GL_RGB5, GL_RGB5, GL_RGB8,
222 GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
223 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
224 {WINED3DFMT_X1R5G5B5, GL_RGB5, GL_RGB5_A1, 0,
225 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
226 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
227 {WINED3DFMT_A1R5G5B5, GL_RGB5_A1, GL_RGB5_A1, 0,
228 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
229 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
230 {WINED3DFMT_A4R4G4B4, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
231 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
232 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
233 {WINED3DFMT_R3G3B2, GL_R3_G3_B2, GL_R3_G3_B2, 0,
234 GL_RGB, GL_UNSIGNED_BYTE_3_3_2,
235 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING},
236 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
237 GL_ALPHA, GL_UNSIGNED_BYTE,
238 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING},
239 {WINED3DFMT_A8R3G3B2, 0, 0, 0,
242 {WINED3DFMT_X4R4G4B4, GL_RGB4, GL_RGB4, 0,
243 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
244 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
245 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
246 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV,
247 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
248 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
249 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
250 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
251 {WINED3DFMT_X8B8G8R8, GL_RGB8, GL_RGB8, 0,
252 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
253 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
254 {WINED3DFMT_R16G16_UNORM, GL_RGB16_EXT, GL_RGB16_EXT, 0,
255 GL_RGB, GL_UNSIGNED_SHORT,
256 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
257 {WINED3DFMT_A2R10G10B10, GL_RGB10_A2, GL_RGB10_A2, 0,
258 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV,
259 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
260 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16_EXT, GL_RGBA16_EXT, 0,
261 GL_RGBA, GL_UNSIGNED_SHORT,
262 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
264 {WINED3DFMT_L8, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
265 GL_LUMINANCE, GL_UNSIGNED_BYTE,
266 WINED3DFMT_FLAG_FILTERING},
267 {WINED3DFMT_A8L8, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
268 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
269 WINED3DFMT_FLAG_FILTERING},
270 {WINED3DFMT_A4L4, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
271 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
273 /* Bump mapping stuff */
274 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
276 WINED3DFMT_FLAG_FILTERING},
277 {WINED3DFMT_L6V5U5, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
278 GL_DSDT_MAG_NV, GL_BYTE,
279 WINED3DFMT_FLAG_FILTERING},
280 {WINED3DFMT_X8L8V8U8, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
281 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV,
282 WINED3DFMT_FLAG_FILTERING},
283 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
285 WINED3DFMT_FLAG_FILTERING},
286 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
287 GL_HILO_NV, GL_SHORT,
288 WINED3DFMT_FLAG_FILTERING},
289 {WINED3DFMT_W11V11U10, 0, 0, 0,
292 {WINED3DFMT_A2W10V10U10, 0, 0, 0,
295 /* Depth stencil formats */
296 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
297 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
298 WINED3DFMT_FLAG_DEPTH},
299 {WINED3DFMT_D32, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
300 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
301 WINED3DFMT_FLAG_DEPTH},
302 {WINED3DFMT_D15S1, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
303 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
304 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
305 {WINED3DFMT_D24S8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
306 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
307 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
308 {WINED3DFMT_D24X8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
309 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
310 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH},
311 {WINED3DFMT_D24X4S4, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
312 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
313 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
314 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
315 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
316 WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH},
317 {WINED3DFMT_L16, GL_LUMINANCE16_EXT, GL_LUMINANCE16_EXT, 0,
318 GL_LUMINANCE, GL_UNSIGNED_SHORT,
319 WINED3DFMT_FLAG_FILTERING},
320 {WINED3DFMT_D32F_LOCKABLE, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
321 GL_DEPTH_COMPONENT, GL_FLOAT,
322 WINED3DFMT_FLAG_DEPTH},
323 {WINED3DFMT_D24FS8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
324 GL_DEPTH_COMPONENT, GL_FLOAT,
325 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
326 /* Is this a vertex buffer? */
327 {WINED3DFMT_VERTEXDATA, 0, 0, 0,
330 {WINED3DFMT_R16_UINT, 0, 0, 0,
333 {WINED3DFMT_R32_UINT, 0, 0, 0,
336 {WINED3DFMT_R16G16B16A16_SNORM, GL_COLOR_INDEX, GL_COLOR_INDEX, 0,
337 GL_COLOR_INDEX, GL_UNSIGNED_SHORT,
339 /* Vendor-specific formats */
340 {WINED3DFMT_ATI2N, 0, 0, 0,
341 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
343 {WINED3DFMT_NVHU, 0, 0, 0,
344 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
346 {WINED3DFMT_NVHS, 0, 0, 0,
347 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
351 static inline int getFmtIdx(WINED3DFORMAT fmt) {
352 /* First check if the format is at the position of its value.
353 * This will catch the argb formats before the loop is entered
355 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
359 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
360 if(formats[i].format == fmt) {
368 #define GLINFO_LOCATION (*gl_info)
369 BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
374 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
375 sizeof(formats) / sizeof(formats[0]) * sizeof(gl_info->gl_formats[0]));
376 if(!gl_info->gl_formats) return FALSE;
378 /* If a format depends on some extensions, remove them from the table above and initialize them
381 for(src = 0; src < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); src++) {
382 dst = getFmtIdx(gl_formats_template[src].fmt);
383 gl_info->gl_formats[dst].glInternal = gl_formats_template[src].glInternal;
384 gl_info->gl_formats[dst].glGammaInternal = gl_formats_template[src].glGammaInternal;
385 gl_info->gl_formats[dst].glFormat = gl_formats_template[src].glFormat;
386 gl_info->gl_formats[dst].glType = gl_formats_template[src].glType;
387 gl_info->gl_formats[dst].color_fixup = COLOR_FIXUP_IDENTITY;
388 gl_info->gl_formats[dst].Flags = gl_formats_template[src].Flags;
389 gl_info->gl_formats[dst].heightscale = 1.0;
391 if(wined3d_settings.offscreen_rendering_mode == ORM_FBO &&
392 gl_formats_template[src].rtInternal != 0) {
396 /* Check if the default internal format is supported as a frame buffer target, otherwise
397 * fall back to the render target internal.
399 * Try to stick to the standard format if possible, this limits precision differences
402 glGenTextures(1, &tex);
403 glBindTexture(GL_TEXTURE_2D, tex);
404 glTexImage2D(GL_TEXTURE_2D, 0, gl_formats_template[src].glInternal, 16, 16, 0,
405 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
407 GL_EXTCALL(glGenFramebuffersEXT(1, &fb));
408 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb));
409 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
410 GL_TEXTURE_2D, tex, 0));
412 status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
413 GL_EXTCALL(glDeleteFramebuffersEXT(1, &fb));
414 glDeleteTextures(1, &tex);
416 checkGLcall("Framebuffer format check");
418 if(status != GL_FRAMEBUFFER_COMPLETE_EXT) {
419 TRACE("Internal format of %s not supported as frame buffer target, using render target internal instead\n",
420 debug_d3dformat(gl_formats_template[src].fmt));
421 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].rtInternal;
423 TRACE("Format %s is supported as fbo target\n", debug_d3dformat(gl_formats_template[src].fmt));
424 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].glInternal;
428 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].glInternal;
432 dst = getFmtIdx(WINED3DFMT_R16_FLOAT);
433 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
434 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
435 /* When ARB_texture_rg is supported we only require 16-bit for R16F instead of 64-bit RGBA16F */
436 if(GL_SUPPORT(ARB_TEXTURE_RG))
438 gl_info->gl_formats[dst].glInternal = GL_R16F;
439 gl_info->gl_formats[dst].glGammaInternal = GL_R16F;
442 dst = getFmtIdx(WINED3DFMT_R32_FLOAT);
443 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
444 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
445 /* When ARB_texture_rg is supported we only require 32-bit for R32F instead of 128-bit RGBA32F */
446 if(GL_SUPPORT(ARB_TEXTURE_RG))
448 gl_info->gl_formats[dst].glInternal = GL_R32F;
449 gl_info->gl_formats[dst].glGammaInternal = GL_R32F;
452 dst = getFmtIdx(WINED3DFMT_R16G16_UNORM);
453 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
454 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
456 dst = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
457 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
458 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
460 dst = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
461 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
462 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
464 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
465 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
466 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
467 * the only driver that implements it(fglrx) has a buggy implementation.
469 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
470 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
471 * conversion for this format.
473 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
475 dst = getFmtIdx(WINED3DFMT_R8G8_SNORM);
476 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
477 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
478 dst = getFmtIdx(WINED3DFMT_R16G16_SNORM);
479 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
480 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
484 dst = getFmtIdx(WINED3DFMT_R8G8_SNORM);
485 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
486 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
487 dst = getFmtIdx(WINED3DFMT_R16G16_SNORM);
488 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
489 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
492 if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
493 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
496 dst = getFmtIdx(WINED3DFMT_L6V5U5);
497 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
498 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
499 dst = getFmtIdx(WINED3DFMT_X8L8V8U8);
500 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
501 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
502 dst = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
503 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
504 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
506 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
507 * are converted at surface loading time, but they do not need any modification in
508 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
509 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
513 if(GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
514 dst = getFmtIdx(WINED3DFMT_ATI2N);
515 gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
516 gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
517 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
518 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
519 } else if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC)) {
520 dst = getFmtIdx(WINED3DFMT_ATI2N);
521 gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
522 gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
523 gl_info->gl_formats[dst].color_fixup= create_color_fixup_desc(
524 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
527 if(!GL_SUPPORT(APPLE_YCBCR_422)) {
528 dst = getFmtIdx(WINED3DFMT_YUY2);
529 gl_info->gl_formats[dst].glInternal = GL_LUMINANCE_ALPHA;
530 gl_info->gl_formats[dst].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
531 gl_info->gl_formats[dst].glFormat = GL_LUMINANCE_ALPHA;
532 gl_info->gl_formats[dst].glType = GL_UNSIGNED_BYTE;
533 gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
535 dst = getFmtIdx(WINED3DFMT_UYVY);
536 gl_info->gl_formats[dst].glInternal = GL_LUMINANCE_ALPHA;
537 gl_info->gl_formats[dst].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
538 gl_info->gl_formats[dst].glFormat = GL_LUMINANCE_ALPHA;
539 gl_info->gl_formats[dst].glType = GL_UNSIGNED_BYTE;
540 gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
543 dst = getFmtIdx(WINED3DFMT_YV12);
544 gl_info->gl_formats[dst].heightscale = 1.5;
545 gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
550 /* NOTE: Make sure these are in the correct numerical order. (see /include/wined3d_types.h) */
551 static WINED3DGLTYPE const glTypeLookupTemplate[WINED3DDECLTYPE_UNUSED] =
553 {WINED3DDECLTYPE_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
554 {WINED3DDECLTYPE_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
555 {WINED3DDECLTYPE_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
556 {WINED3DDECLTYPE_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
557 {WINED3DDECLTYPE_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
558 {WINED3DDECLTYPE_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
559 {WINED3DDECLTYPE_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
560 {WINED3DDECLTYPE_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
561 {WINED3DDECLTYPE_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
562 {WINED3DDECLTYPE_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
563 {WINED3DDECLTYPE_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
564 {WINED3DDECLTYPE_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
565 {WINED3DDECLTYPE_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
566 {WINED3DDECLTYPE_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
567 {WINED3DDECLTYPE_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
568 {WINED3DDECLTYPE_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
569 {WINED3DDECLTYPE_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
572 void init_type_lookup(WineD3D_GL_Info *gl_info) {
573 memcpy(gl_info->glTypeLookup, glTypeLookupTemplate, sizeof(glTypeLookupTemplate));
575 if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
577 gl_info->glTypeLookup[WINED3DDECLTYPE_D3DCOLOR].format = GL_BGRA;
580 if (GL_SUPPORT(NV_HALF_FLOAT))
582 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
583 * It is the job of the vertex buffer code to make sure that the vbos have the right format
585 gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_2].glType = GL_HALF_FLOAT_NV;
586 gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_4].glType = GL_HALF_FLOAT_NV;
590 #undef GLINFO_LOCATION
592 #define GLINFO_LOCATION This->adapter->gl_info
594 const StaticPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const WineD3D_GL_Info *gl_info,
595 const struct GlPixelFormatDesc **glDesc)
597 int idx = getFmtIdx(fmt);
600 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
601 /* Get the caller a valid pointer */
602 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
605 if(!gl_info->gl_formats) {
606 /* If we do not have gl format information, provide a dummy NULL format. This is an easy way to make
607 * all gl caps check return "unsupported" than catching the lack of gl all over the code. ANSI C requires
608 * static variables to be initialized to 0.
610 static const struct GlPixelFormatDesc dummyFmt;
613 *glDesc = &gl_info->gl_formats[idx];
616 return &formats[idx];
619 /*****************************************************************************
620 * Trace formatting of useful values
622 const char* debug_d3dformat(WINED3DFORMAT fmt) {
624 #define FMT_TO_STR(fmt) case fmt: return #fmt
625 FMT_TO_STR(WINED3DFMT_UNKNOWN);
626 FMT_TO_STR(WINED3DFMT_R8G8B8);
627 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
628 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
629 FMT_TO_STR(WINED3DFMT_R5G6B5);
630 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
631 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
632 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
633 FMT_TO_STR(WINED3DFMT_R3G3B2);
634 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
635 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
636 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
637 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
638 FMT_TO_STR(WINED3DFMT_A8P8);
639 FMT_TO_STR(WINED3DFMT_P8);
640 FMT_TO_STR(WINED3DFMT_L8);
641 FMT_TO_STR(WINED3DFMT_A8L8);
642 FMT_TO_STR(WINED3DFMT_A4L4);
643 FMT_TO_STR(WINED3DFMT_L6V5U5);
644 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
645 FMT_TO_STR(WINED3DFMT_W11V11U10);
646 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
647 FMT_TO_STR(WINED3DFMT_UYVY);
648 FMT_TO_STR(WINED3DFMT_YUY2);
649 FMT_TO_STR(WINED3DFMT_YV12);
650 FMT_TO_STR(WINED3DFMT_DXT1);
651 FMT_TO_STR(WINED3DFMT_DXT2);
652 FMT_TO_STR(WINED3DFMT_DXT3);
653 FMT_TO_STR(WINED3DFMT_DXT4);
654 FMT_TO_STR(WINED3DFMT_DXT5);
655 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
656 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
657 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
658 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
659 FMT_TO_STR(WINED3DFMT_D32);
660 FMT_TO_STR(WINED3DFMT_D15S1);
661 FMT_TO_STR(WINED3DFMT_D24S8);
662 FMT_TO_STR(WINED3DFMT_D24X8);
663 FMT_TO_STR(WINED3DFMT_D24X4S4);
664 FMT_TO_STR(WINED3DFMT_L16);
665 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
666 FMT_TO_STR(WINED3DFMT_D24FS8);
667 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
668 FMT_TO_STR(WINED3DFMT_CxV8U8);
669 FMT_TO_STR(WINED3DFMT_ATI2N);
670 FMT_TO_STR(WINED3DFMT_NVHU);
671 FMT_TO_STR(WINED3DFMT_NVHS);
672 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
673 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
674 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
675 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
676 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
677 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
678 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
679 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
680 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
681 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
682 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
683 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
684 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
685 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
686 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
687 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
688 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
689 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
690 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
691 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
692 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
693 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
694 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
695 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
696 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
697 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
698 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
699 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
700 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
701 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
702 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
703 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
704 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
705 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
706 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
707 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
708 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
709 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
710 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
711 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
712 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
713 FMT_TO_STR(WINED3DFMT_R32_UINT);
714 FMT_TO_STR(WINED3DFMT_R32_SINT);
715 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
716 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
717 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
718 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
719 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
720 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
721 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
722 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
723 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
724 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
725 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
726 FMT_TO_STR(WINED3DFMT_D16_UNORM);
727 FMT_TO_STR(WINED3DFMT_R16_UNORM);
728 FMT_TO_STR(WINED3DFMT_R16_UINT);
729 FMT_TO_STR(WINED3DFMT_R16_SNORM);
730 FMT_TO_STR(WINED3DFMT_R16_SINT);
731 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
732 FMT_TO_STR(WINED3DFMT_R8_UNORM);
733 FMT_TO_STR(WINED3DFMT_R8_UINT);
734 FMT_TO_STR(WINED3DFMT_R8_SNORM);
735 FMT_TO_STR(WINED3DFMT_R8_SINT);
736 FMT_TO_STR(WINED3DFMT_A8_UNORM);
737 FMT_TO_STR(WINED3DFMT_R1_UNORM);
738 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
739 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
740 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
741 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
742 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
743 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
744 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
745 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
746 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
747 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
748 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
749 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
750 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
751 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
752 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
753 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
754 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
755 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
756 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
757 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
758 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
759 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
764 fourcc[0] = (char)(fmt);
765 fourcc[1] = (char)(fmt >> 8);
766 fourcc[2] = (char)(fmt >> 16);
767 fourcc[3] = (char)(fmt >> 24);
769 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
770 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
772 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
774 return "unrecognized";
778 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
780 #define DEVTYPE_TO_STR(dev) case dev: return #dev
781 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
782 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
783 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
784 #undef DEVTYPE_TO_STR
786 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
787 return "unrecognized";
791 const char* debug_d3dusage(DWORD usage) {
792 switch (usage & WINED3DUSAGE_MASK) {
793 #define WINED3DUSAGE_TO_STR(u) case u: return #u
794 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
795 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
796 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
797 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
798 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
799 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
800 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
801 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
802 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
803 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
804 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
805 #undef WINED3DUSAGE_TO_STR
806 case 0: return "none";
808 FIXME("Unrecognized %u Usage!\n", usage);
809 return "unrecognized";
813 const char* debug_d3dusagequery(DWORD usagequery) {
814 switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
815 #define WINED3DUSAGEQUERY_TO_STR(u) case u: return #u
816 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
817 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
818 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
819 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
820 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
821 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
822 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
823 #undef WINED3DUSAGEQUERY_TO_STR
824 case 0: return "none";
826 FIXME("Unrecognized %u Usage Query!\n", usagequery);
827 return "unrecognized";
831 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
833 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
834 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
835 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
836 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
837 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
838 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
839 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
840 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
841 #undef WINED3DDECLMETHOD_TO_STR
843 FIXME("Unrecognized %u declaration method!\n", method);
844 return "unrecognized";
848 const char* debug_d3ddecltype(WINED3DDECLTYPE type) {
850 #define WINED3DDECLTYPE_TO_STR(u) case u: return #u
851 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT1);
852 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT2);
853 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT3);
854 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT4);
855 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_D3DCOLOR);
856 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4);
857 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2);
858 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4);
859 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4N);
860 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2N);
861 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4N);
862 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT2N);
863 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT4N);
864 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UDEC3);
865 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_DEC3N);
866 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_2);
867 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_4);
868 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UNUSED);
869 #undef WINED3DDECLTYPE_TO_STR
871 FIXME("Unrecognized %u declaration type!\n", type);
872 return "unrecognized";
876 const char* debug_d3ddeclusage(BYTE usage) {
878 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
879 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
880 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
881 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
882 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
883 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
884 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
885 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
886 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
887 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
888 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
889 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
890 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
891 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
892 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
893 #undef WINED3DDECLUSAGE_TO_STR
895 FIXME("Unrecognized %u declaration usage!\n", usage);
896 return "unrecognized";
900 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
902 #define RES_TO_STR(res) case res: return #res
903 RES_TO_STR(WINED3DRTYPE_SURFACE);
904 RES_TO_STR(WINED3DRTYPE_VOLUME);
905 RES_TO_STR(WINED3DRTYPE_TEXTURE);
906 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
907 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
908 RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER);
909 RES_TO_STR(WINED3DRTYPE_INDEXBUFFER);
910 RES_TO_STR(WINED3DRTYPE_BUFFER);
913 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
914 return "unrecognized";
918 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
919 switch (PrimitiveType) {
920 #define PRIM_TO_STR(prim) case prim: return #prim
921 PRIM_TO_STR(WINED3DPT_POINTLIST);
922 PRIM_TO_STR(WINED3DPT_LINELIST);
923 PRIM_TO_STR(WINED3DPT_LINESTRIP);
924 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
925 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
926 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
929 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
930 return "unrecognized";
934 const char* debug_d3drenderstate(DWORD state) {
936 #define D3DSTATE_TO_STR(u) case u: return #u
937 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
938 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
939 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
940 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
941 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
942 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
943 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
944 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
945 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
946 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
947 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
948 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
949 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
950 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
951 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
952 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
953 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
954 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
955 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
956 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
957 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
958 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
959 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
960 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
961 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
962 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
963 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
964 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
965 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
966 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
967 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
968 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
969 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
970 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
971 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
972 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
973 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
974 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
975 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
976 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
977 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
978 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
979 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
980 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
981 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
982 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
983 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
984 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
985 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
986 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
987 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
988 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
989 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
990 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
991 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
992 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
993 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
994 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
995 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
996 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
997 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
998 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
999 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
1000 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
1001 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
1002 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
1003 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
1004 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
1005 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
1006 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
1007 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
1008 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
1009 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
1010 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
1011 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
1012 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
1013 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
1014 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
1015 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
1016 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
1017 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
1018 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
1019 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
1020 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
1021 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
1022 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
1023 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
1024 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
1025 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
1026 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
1027 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
1028 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1029 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1030 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1031 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1032 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1033 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1034 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1035 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1036 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1037 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1038 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1039 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1040 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1041 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1042 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1043 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1044 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1045 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1046 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1047 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1048 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1049 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1050 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1051 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1052 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1053 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1054 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1055 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1056 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1057 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1058 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1059 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1060 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1061 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1062 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1063 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1064 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1065 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1066 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1067 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1068 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1069 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1070 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1071 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1072 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1073 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1074 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1075 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1076 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1077 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1078 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1079 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1080 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1081 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1082 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1083 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1084 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1085 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1086 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1087 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1088 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1089 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1090 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1091 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1092 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1093 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1094 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1095 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1096 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1097 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1098 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1099 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1100 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1101 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1102 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1103 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1104 #undef D3DSTATE_TO_STR
1106 FIXME("Unrecognized %u render state!\n", state);
1107 return "unrecognized";
1111 const char* debug_d3dsamplerstate(DWORD state) {
1113 #define D3DSTATE_TO_STR(u) case u: return #u
1114 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1115 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1116 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1117 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1118 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1119 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1120 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1121 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1122 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1123 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1124 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1125 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1126 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1127 #undef D3DSTATE_TO_STR
1129 FIXME("Unrecognized %u sampler state!\n", state);
1130 return "unrecognized";
1134 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1135 switch (filter_type) {
1136 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1137 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1138 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1139 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1140 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1141 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1142 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1143 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1144 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1145 #undef D3DTEXTUREFILTERTYPE_TO_STR
1147 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1148 return "unrecognized";
1152 const char* debug_d3dtexturestate(DWORD state) {
1154 #define D3DSTATE_TO_STR(u) case u: return #u
1155 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1156 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1157 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1158 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1159 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1160 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1161 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1162 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1163 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1164 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1165 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1166 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1167 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1168 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1169 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1170 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1171 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1172 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1173 #undef D3DSTATE_TO_STR
1175 FIXME("Unrecognized %u texture state!\n", state);
1176 return "unrecognized";
1180 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1182 #define D3DTOP_TO_STR(u) case u: return #u
1183 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1184 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1185 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1186 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1187 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1188 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1189 D3DTOP_TO_STR(WINED3DTOP_ADD);
1190 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1191 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1192 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1193 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1194 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1195 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1196 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1197 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1198 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1199 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1200 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1201 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1202 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1203 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1204 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1205 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1206 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1207 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1208 D3DTOP_TO_STR(WINED3DTOP_LERP);
1209 #undef D3DTOP_TO_STR
1211 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1212 return "unrecognized";
1216 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1218 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1219 TSTYPE_TO_STR(WINED3DTS_VIEW);
1220 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1221 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1222 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1223 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1224 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1225 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1226 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1227 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1228 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1229 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1230 #undef TSTYPE_TO_STR
1232 if (tstype > 256 && tstype < 512) {
1233 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1234 return ("WINED3DTS_WORLDMATRIX > 0");
1236 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1237 return "unrecognized";
1241 const char* debug_d3dpool(WINED3DPOOL Pool) {
1243 #define POOL_TO_STR(p) case p: return #p
1244 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1245 POOL_TO_STR(WINED3DPOOL_MANAGED);
1246 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1247 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1250 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1251 return "unrecognized";
1255 const char *debug_fbostatus(GLenum status) {
1257 #define FBOSTATUS_TO_STR(u) case u: return #u
1258 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1259 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1260 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1261 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1262 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1263 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1264 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1265 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
1266 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1267 #undef FBOSTATUS_TO_STR
1269 FIXME("Unrecognied FBO status 0x%08x\n", status);
1270 return "unrecognized";
1274 const char *debug_glerror(GLenum error) {
1276 #define GLERROR_TO_STR(u) case u: return #u
1277 GLERROR_TO_STR(GL_NO_ERROR);
1278 GLERROR_TO_STR(GL_INVALID_ENUM);
1279 GLERROR_TO_STR(GL_INVALID_VALUE);
1280 GLERROR_TO_STR(GL_INVALID_OPERATION);
1281 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1282 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1283 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1284 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1285 #undef GLERROR_TO_STR
1287 FIXME("Unrecognied GL error 0x%08x\n", error);
1288 return "unrecognized";
1292 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1294 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1295 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1296 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1297 default: return "unrecognized";
1301 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1303 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1304 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1305 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1306 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1307 default: return "unrecognized";
1311 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
1315 #define WINED3D_TO_STR(x) case x: return #x
1316 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1317 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1318 WINED3D_TO_STR(CHANNEL_SOURCE_X);
1319 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1320 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1321 WINED3D_TO_STR(CHANNEL_SOURCE_W);
1322 WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1323 WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1324 #undef WINED3D_TO_STR
1326 FIXME("Unrecognized fixup_channel_source %#x\n", source);
1327 return "unrecognized";
1331 static const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1335 #define WINED3D_TO_STR(x) case x: return #x
1336 WINED3D_TO_STR(YUV_FIXUP_YUY2);
1337 WINED3D_TO_STR(YUV_FIXUP_UYVY);
1338 WINED3D_TO_STR(YUV_FIXUP_YV12);
1339 #undef WINED3D_TO_STR
1341 FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1342 return "unrecognized";
1346 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1348 if (is_yuv_fixup(fixup))
1350 TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1354 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1355 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1356 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1357 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1360 const char *debug_surflocation(DWORD flag) {
1364 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
1365 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
1366 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
1367 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
1368 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
1371 /*****************************************************************************
1372 * Useful functions mapping GL <-> D3D values
1374 GLenum StencilOp(DWORD op) {
1376 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1377 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1378 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1379 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1380 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1381 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1382 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1383 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1385 FIXME("Unrecognized stencil op %d\n", op);
1390 GLenum CompareFunc(DWORD func) {
1391 switch ((WINED3DCMPFUNC)func) {
1392 case WINED3DCMP_NEVER : return GL_NEVER;
1393 case WINED3DCMP_LESS : return GL_LESS;
1394 case WINED3DCMP_EQUAL : return GL_EQUAL;
1395 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1396 case WINED3DCMP_GREATER : return GL_GREATER;
1397 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1398 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1399 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1401 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1406 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1407 if (op == WINED3DTOP_DISABLE) return FALSE;
1408 if (This->stateBlock->textures[stage]) return FALSE;
1410 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1411 && op != WINED3DTOP_SELECTARG2) return TRUE;
1412 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1413 && op != WINED3DTOP_SELECTARG1) return TRUE;
1414 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1415 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1420 /* Setup this textures matrix according to the texture flags*/
1421 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype,
1422 BOOL ffp_proj_control)
1426 glMatrixMode(GL_TEXTURE);
1427 checkGLcall("glMatrixMode(GL_TEXTURE)");
1429 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1431 checkGLcall("glLoadIdentity()");
1435 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1436 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1440 memcpy(mat, smat, 16 * sizeof(float));
1442 if (flags & WINED3DTTFF_PROJECTED) {
1443 if(!ffp_proj_control) {
1444 switch (flags & ~WINED3DTTFF_PROJECTED) {
1445 case WINED3DTTFF_COUNT2:
1446 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1447 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1449 case WINED3DTTFF_COUNT3:
1450 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1451 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1455 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1456 if(!calculatedCoords) {
1458 case WINED3DDECLTYPE_FLOAT1:
1459 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1460 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1461 * the input value to the transformation will be 0, so the matrix value is irrelevant
1468 case WINED3DDECLTYPE_FLOAT2:
1469 /* See above, just 3rd and 4th coord
1476 case WINED3DDECLTYPE_FLOAT3: /* Opengl defaults match dx defaults */
1477 case WINED3DDECLTYPE_FLOAT4: /* No defaults apply, all app defined */
1479 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1480 * into a bad place. The division elimination below will apply to make sure the
1481 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1483 case WINED3DDECLTYPE_UNUSED: /* No texture coords, 0/0/0/1 defaults are passed */
1486 FIXME("Unexpected fixed function texture coord input\n");
1489 if(!ffp_proj_control) {
1490 switch (flags & ~WINED3DTTFF_PROJECTED) {
1491 /* case WINED3DTTFF_COUNT1: Won't ever get here */
1492 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
1493 /* OpenGL divides the first 3 vertex coord by the 4th by default,
1494 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
1495 * the 4th coord evaluates to 1.0 to eliminate that.
1497 * If the fixed function pipeline is used, the 4th value remains unused,
1498 * so there is no danger in doing this. With vertex shaders we have a
1499 * problem. Should an app hit that problem, the code here would have to
1500 * check for pixel shaders, and the shader has to undo the default gl divide.
1502 * A more serious problem occurs if the app passes 4 coordinates in, and the
1503 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
1504 * or a replacement shader
1506 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
1512 checkGLcall("glLoadMatrixf(mat)");
1514 #undef GLINFO_LOCATION
1516 /* This small helper function is used to convert a bitmask into the number of masked bits */
1517 unsigned int count_bits(unsigned int mask)
1520 for (count = 0; mask; ++count)
1527 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
1528 * The later function requires individual color components. */
1529 BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
1531 const StaticPixelFormatDesc *desc;
1533 TRACE("fmt: %s\n", debug_d3dformat(fmt));
1536 case WINED3DFMT_X8R8G8B8:
1537 case WINED3DFMT_R8G8B8:
1538 case WINED3DFMT_A8R8G8B8:
1539 case WINED3DFMT_A2R10G10B10:
1540 case WINED3DFMT_X1R5G5B5:
1541 case WINED3DFMT_A1R5G5B5:
1542 case WINED3DFMT_R5G6B5:
1543 case WINED3DFMT_X4R4G4B4:
1544 case WINED3DFMT_A4R4G4B4:
1545 case WINED3DFMT_R3G3B2:
1546 case WINED3DFMT_A8P8:
1550 ERR("Unsupported format: %s\n", debug_d3dformat(fmt));
1554 desc = getFormatDescEntry(fmt, NULL, NULL);
1557 ERR("Unable to look up format: 0x%x\n", fmt);
1560 *redSize = count_bits(desc->redMask);
1561 *greenSize = count_bits(desc->greenMask);
1562 *blueSize = count_bits(desc->blueMask);
1563 *alphaSize = count_bits(desc->alphaMask);
1564 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
1566 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n", *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(fmt));
1570 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
1571 BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize)
1573 const StaticPixelFormatDesc *desc;
1575 TRACE("fmt: %s\n", debug_d3dformat(fmt));
1578 case WINED3DFMT_D16_LOCKABLE:
1579 case WINED3DFMT_D16_UNORM:
1580 case WINED3DFMT_D15S1:
1581 case WINED3DFMT_D24X8:
1582 case WINED3DFMT_D24X4S4:
1583 case WINED3DFMT_D24S8:
1584 case WINED3DFMT_D24FS8:
1585 case WINED3DFMT_D32:
1586 case WINED3DFMT_D32F_LOCKABLE:
1589 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(fmt));
1593 desc = getFormatDescEntry(fmt, NULL, NULL);
1596 ERR("Unable to look up format: 0x%x\n", fmt);
1599 *depthSize = desc->depthSize;
1600 *stencilSize = desc->stencilSize;
1602 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n", *depthSize, *stencilSize, debug_d3dformat(fmt));
1606 /* DirectDraw stuff */
1607 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
1609 case 8: return WINED3DFMT_P8;
1610 case 15: return WINED3DFMT_X1R5G5B5;
1611 case 16: return WINED3DFMT_R5G6B5;
1612 case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
1613 case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
1614 default: return WINED3DFMT_UNKNOWN;
1618 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
1621 /* Now do the multiplication 'by hand'.
1622 I know that all this could be optimised, but this will be done later :-) */
1623 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);
1624 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);
1625 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);
1626 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);
1628 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);
1629 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);
1630 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);
1631 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);
1633 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);
1634 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);
1635 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);
1636 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);
1638 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);
1639 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);
1640 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);
1641 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);
1643 /* And copy the new matrix in the good storage.. */
1644 memcpy(dest, &temp, 16 * sizeof(float));
1647 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
1650 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
1652 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
1653 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
1654 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
1655 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
1656 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
1657 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
1658 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
1659 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
1660 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
1661 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
1662 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
1663 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
1664 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
1665 default: ERR("Unexpected position mask\n");
1667 for (i = 0; i < numTextures; i++) {
1668 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
1674 /***********************************************************************
1677 * Calculates the dimensions of the opengl texture used for blits.
1678 * Handled oversized opengl textures and updates the source rectangle
1682 * This: Surface to operate on
1683 * Rect: Requested rectangle
1686 * TRUE if the texture part can be loaded,
1689 *********************************************************************/
1690 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
1692 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
1693 int x1 = Rect->left, x2 = Rect->right;
1694 int y1 = Rect->top, y2 = Rect->bottom;
1695 GLint maxSize = GL_LIMITS(texture_size);
1697 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
1698 Rect->left, Rect->top, Rect->right, Rect->bottom);
1700 /* The sizes might be reversed */
1701 if(Rect->left > Rect->right) {
1705 if(Rect->top > Rect->bottom) {
1710 /* No oversized texture? This is easy */
1711 if(!(This->Flags & SFLAG_OVERSIZE)) {
1712 /* Which rect from the texture do I need? */
1713 if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
1714 glTexCoord[0] = (float) Rect->left;
1715 glTexCoord[2] = (float) Rect->top;
1716 glTexCoord[1] = (float) Rect->right;
1717 glTexCoord[3] = (float) Rect->bottom;
1719 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
1720 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
1721 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
1722 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
1727 /* Check if we can succeed at all */
1728 if( (x2 - x1) > maxSize ||
1729 (y2 - y1) > maxSize ) {
1730 TRACE("Requested rectangle is too large for gl\n");
1734 /* A part of the texture has to be picked. First, check if
1735 * some texture part is loaded already, if yes try to re-use it.
1736 * If the texture is dirty, or the part can't be used,
1737 * re-position the part to load
1739 if(This->Flags & SFLAG_INTEXTURE) {
1740 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
1741 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
1742 /* Ok, the rectangle is ok, re-use it */
1743 TRACE("Using existing gl Texture\n");
1745 /* Rectangle is not ok, dirtify the texture to reload it */
1746 TRACE("Dirtifying texture to force reload\n");
1747 This->Flags &= ~SFLAG_INTEXTURE;
1751 /* Now if we are dirty(no else if!) */
1752 if(!(This->Flags & SFLAG_INTEXTURE)) {
1753 /* Set the new rectangle. Use the following strategy:
1754 * 1) Use as big textures as possible.
1755 * 2) Place the texture part in the way that the requested
1756 * part is in the middle of the texture(well, almost)
1757 * 3) If the texture is moved over the edges of the
1758 * surface, replace it nicely
1759 * 4) If the coord is not limiting the texture size,
1760 * use the whole size
1762 if((This->pow2Width) > maxSize) {
1763 This->glRect.left = x1 - maxSize / 2;
1764 if(This->glRect.left < 0) {
1765 This->glRect.left = 0;
1767 This->glRect.right = This->glRect.left + maxSize;
1768 if(This->glRect.right > This->currentDesc.Width) {
1769 This->glRect.right = This->currentDesc.Width;
1770 This->glRect.left = This->glRect.right - maxSize;
1773 This->glRect.left = 0;
1774 This->glRect.right = This->pow2Width;
1777 if(This->pow2Height > maxSize) {
1778 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
1779 if(This->glRect.top < 0) This->glRect.top = 0;
1780 This->glRect.bottom = This->glRect.left + maxSize;
1781 if(This->glRect.bottom > This->currentDesc.Height) {
1782 This->glRect.bottom = This->currentDesc.Height;
1783 This->glRect.top = This->glRect.bottom - maxSize;
1786 This->glRect.top = 0;
1787 This->glRect.bottom = This->pow2Height;
1789 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
1790 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
1793 /* Re-calculate the rect to draw */
1794 Rect->left -= This->glRect.left;
1795 Rect->right -= This->glRect.left;
1796 Rect->top -= This->glRect.top;
1797 Rect->bottom -= This->glRect.top;
1799 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
1800 * or the pow2Width / pow2Height of the surface.
1802 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
1803 * as regular GL_TEXTURE_2D.
1805 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
1806 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
1807 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
1808 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
1812 #undef GLINFO_LOCATION
1814 /* Hash table functions */
1816 struct hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
1818 struct hash_table_t *table;
1819 unsigned int initial_size = 8;
1821 table = HeapAlloc(GetProcessHeap(), 0, sizeof(struct hash_table_t) + (initial_size * sizeof(struct list)));
1824 ERR("Failed to allocate table, returning NULL.\n");
1828 table->hash_function = hash_function;
1829 table->compare_function = compare_function;
1831 table->grow_size = initial_size - (initial_size >> 2);
1832 table->shrink_size = 0;
1834 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
1835 if (!table->buckets)
1837 ERR("Failed to allocate table buckets, returning NULL.\n");
1838 HeapFree(GetProcessHeap(), 0, table);
1841 table->bucket_count = initial_size;
1843 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(struct hash_table_entry_t));
1844 if (!table->entries)
1846 ERR("Failed to allocate table entries, returning NULL.\n");
1847 HeapFree(GetProcessHeap(), 0, table->buckets);
1848 HeapFree(GetProcessHeap(), 0, table);
1851 table->entry_count = 0;
1853 list_init(&table->free_entries);
1859 void hash_table_destroy(struct hash_table_t *table, void (*free_value)(void *value, void *cb), void *cb)
1863 for (i = 0; i < table->entry_count; ++i)
1866 free_value(table->entries[i].value, cb);
1868 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
1871 HeapFree(GetProcessHeap(), 0, table->entries);
1872 HeapFree(GetProcessHeap(), 0, table->buckets);
1873 HeapFree(GetProcessHeap(), 0, table);
1876 void hash_table_for_each_entry(struct hash_table_t *table, void (*callback)(void *value, void *context), void *context)
1880 for (i = 0; i < table->entry_count; ++i)
1882 callback(table->entries[i].value, context);
1886 static inline struct hash_table_entry_t *hash_table_get_by_idx(const struct hash_table_t *table, const void *key,
1889 struct hash_table_entry_t *entry;
1891 if (table->buckets[idx].next)
1892 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), struct hash_table_entry_t, entry)
1893 if (table->compare_function(entry->key, key)) return entry;
1898 static BOOL hash_table_resize(struct hash_table_t *table, unsigned int new_bucket_count)
1900 unsigned int new_entry_count = 0;
1901 struct hash_table_entry_t *new_entries;
1902 struct list *new_buckets;
1903 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
1906 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
1909 ERR("Failed to allocate new buckets, returning FALSE.\n");
1913 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(struct hash_table_entry_t));
1916 ERR("Failed to allocate new entries, returning FALSE.\n");
1917 HeapFree(GetProcessHeap(), 0, new_buckets);
1921 for (i = 0; i < table->bucket_count; ++i)
1923 if (table->buckets[i].next)
1925 struct hash_table_entry_t *entry, *entry2;
1927 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], struct hash_table_entry_t, entry)
1930 struct hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
1931 *new_entry = *entry;
1933 j = new_entry->hash & (new_bucket_count - 1);
1935 if (!new_buckets[j].next) list_init(&new_buckets[j]);
1936 list_add_head(&new_buckets[j], &new_entry->entry);
1941 HeapFree(GetProcessHeap(), 0, table->buckets);
1942 table->buckets = new_buckets;
1944 HeapFree(GetProcessHeap(), 0, table->entries);
1945 table->entries = new_entries;
1947 table->entry_count = new_entry_count;
1948 list_init(&table->free_entries);
1950 table->bucket_count = new_bucket_count;
1951 table->grow_size = grow_size;
1952 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
1957 void hash_table_put(struct hash_table_t *table, void *key, void *value)
1961 struct hash_table_entry_t *entry;
1963 hash = table->hash_function(key);
1964 idx = hash & (table->bucket_count - 1);
1965 entry = hash_table_get_by_idx(table, key, idx);
1969 HeapFree(GetProcessHeap(), 0, key);
1970 entry->value = value;
1974 HeapFree(GetProcessHeap(), 0, entry->key);
1977 /* Remove the entry */
1978 list_remove(&entry->entry);
1979 list_add_head(&table->free_entries, &entry->entry);
1983 /* Shrink if necessary */
1984 if (table->count < table->shrink_size) {
1985 if (!hash_table_resize(table, table->bucket_count >> 1))
1987 ERR("Failed to shrink the table...\n");
1997 /* Grow if necessary */
1998 if (table->count >= table->grow_size)
2000 if (!hash_table_resize(table, table->bucket_count << 1))
2002 ERR("Failed to grow the table, returning.\n");
2006 idx = hash & (table->bucket_count - 1);
2009 /* Find an entry to insert */
2010 if (!list_empty(&table->free_entries))
2012 struct list *elem = list_head(&table->free_entries);
2015 entry = LIST_ENTRY(elem, struct hash_table_entry_t, entry);
2017 entry = table->entries + (table->entry_count++);
2020 /* Insert the entry */
2022 entry->value = value;
2024 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
2025 list_add_head(&table->buckets[idx], &entry->entry);
2030 void hash_table_remove(struct hash_table_t *table, void *key)
2032 hash_table_put(table, key, NULL);
2035 void *hash_table_get(const struct hash_table_t *table, const void *key)
2038 struct hash_table_entry_t *entry;
2040 idx = table->hash_function(key) & (table->bucket_count - 1);
2041 entry = hash_table_get_by_idx(table, key, idx);
2043 return entry ? entry->value : NULL;
2046 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2047 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2051 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2053 /* D3DTOP_DISABLE */ 0,
2054 /* D3DTOP_SELECTARG1 */ ARG1,
2055 /* D3DTOP_SELECTARG2 */ ARG2,
2056 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2057 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2058 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2059 /* D3DTOP_ADD */ ARG1 | ARG2,
2060 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2061 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2062 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2063 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2064 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2065 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2066 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2067 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2068 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2069 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2070 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2071 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2072 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2073 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2074 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2075 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2076 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2077 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2078 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2082 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2084 for(i = 0; i < GL_LIMITS(texture_stages); i++) {
2085 IWineD3DBaseTextureImpl *texture;
2086 settings->op[i].padding = 0;
2087 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2088 settings->op[i].cop = WINED3DTOP_DISABLE;
2089 settings->op[i].aop = WINED3DTOP_DISABLE;
2090 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2091 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2092 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2093 settings->op[i].dst = resultreg;
2094 settings->op[i].tex_type = tex_1d;
2095 settings->op[i].projected = proj_none;
2100 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2102 settings->op[i].color_fixup = texture->baseTexture.shader_color_fixup;
2103 if(ignore_textype) {
2104 settings->op[i].tex_type = tex_1d;
2106 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2108 settings->op[i].tex_type = tex_1d;
2111 settings->op[i].tex_type = tex_2d;
2114 settings->op[i].tex_type = tex_3d;
2116 case GL_TEXTURE_CUBE_MAP_ARB:
2117 settings->op[i].tex_type = tex_cube;
2119 case GL_TEXTURE_RECTANGLE_ARB:
2120 settings->op[i].tex_type = tex_rect;
2125 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2126 settings->op[i].tex_type = tex_1d;
2129 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2130 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2132 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2133 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2134 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2136 if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
2137 carg1, carg2, carg0)) {
2140 carg1 = WINED3DTA_CURRENT;
2141 cop = WINED3DTOP_SELECTARG1;
2144 if(cop == WINED3DTOP_DOTPRODUCT3) {
2145 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2146 * the color result to the alpha component of the destination
2153 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2154 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2155 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2158 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2160 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2162 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2164 IWineD3DSurfaceImpl *surf;
2165 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2167 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT
2168 && getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000)
2170 if (aop == WINED3DTOP_DISABLE)
2172 aarg1 = WINED3DTA_TEXTURE;
2173 aop = WINED3DTOP_SELECTARG1;
2175 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2177 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2179 aarg2 = WINED3DTA_TEXTURE;
2180 aop = WINED3DTOP_MODULATE;
2182 else aarg1 = WINED3DTA_TEXTURE;
2184 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2186 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2188 aarg1 = WINED3DTA_TEXTURE;
2189 aop = WINED3DTOP_MODULATE;
2191 else aarg2 = WINED3DTA_TEXTURE;
2197 if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
2198 aarg1, aarg2, aarg0)) {
2201 aarg1 = WINED3DTA_CURRENT;
2202 aop = WINED3DTOP_SELECTARG1;
2205 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2206 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2207 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2208 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2209 settings->op[i].projected = proj_count3;
2210 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2211 settings->op[i].projected = proj_count4;
2213 settings->op[i].projected = proj_none;
2216 settings->op[i].projected = proj_none;
2219 settings->op[i].cop = cop;
2220 settings->op[i].aop = aop;
2221 settings->op[i].carg0 = carg0;
2222 settings->op[i].carg1 = carg1;
2223 settings->op[i].carg2 = carg2;
2224 settings->op[i].aarg0 = aarg0;
2225 settings->op[i].aarg1 = aarg1;
2226 settings->op[i].aarg2 = aarg2;
2228 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2229 settings->op[i].dst = tempreg;
2231 settings->op[i].dst = resultreg;
2235 /* Clear unsupported stages */
2236 for(; i < MAX_TEXTURES; i++) {
2237 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2240 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2241 settings->fog = FOG_OFF;
2242 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2243 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2244 settings->fog = FOG_LINEAR;
2246 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2247 case WINED3DFOG_NONE:
2248 case WINED3DFOG_LINEAR:
2249 settings->fog = FOG_LINEAR;
2251 case WINED3DFOG_EXP:
2252 settings->fog = FOG_EXP;
2254 case WINED3DFOG_EXP2:
2255 settings->fog = FOG_EXP2;
2260 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2261 case WINED3DFOG_LINEAR:
2262 settings->fog = FOG_LINEAR;
2264 case WINED3DFOG_EXP:
2265 settings->fog = FOG_EXP;
2267 case WINED3DFOG_EXP2:
2268 settings->fog = FOG_EXP2;
2272 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2273 settings->sRGB_write = 1;
2275 settings->sRGB_write = 0;
2278 #undef GLINFO_LOCATION
2280 const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
2281 const struct ffp_frag_settings *settings)
2283 return hash_table_get(fragment_shaders, settings);
2286 void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *desc) {
2287 struct ffp_frag_settings *key = HeapAlloc(GetProcessHeap(), 0, sizeof(*key));
2288 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2289 * whereas desc points to an extended structure with implementation specific parts.
2290 * Make a copy of the key because hash_table_put takes ownership of it
2292 *key = desc->settings;
2293 hash_table_put(shaders, key, desc);
2296 /* Activates the texture dimension according to the bound D3D texture.
2297 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2298 * Requires the caller to activate the correct unit before
2300 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2301 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2302 if(stateblock->textures[stage]) {
2303 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2305 glDisable(GL_TEXTURE_3D);
2306 checkGLcall("glDisable(GL_TEXTURE_3D)");
2307 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2308 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2309 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2311 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2312 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2313 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2315 glEnable(GL_TEXTURE_2D);
2316 checkGLcall("glEnable(GL_TEXTURE_2D)");
2318 case GL_TEXTURE_RECTANGLE_ARB:
2319 glDisable(GL_TEXTURE_2D);
2320 checkGLcall("glDisable(GL_TEXTURE_2D)");
2321 glDisable(GL_TEXTURE_3D);
2322 checkGLcall("glDisable(GL_TEXTURE_3D)");
2323 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2324 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2325 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2327 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2328 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2331 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2332 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2333 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2335 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2336 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2337 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2339 glDisable(GL_TEXTURE_2D);
2340 checkGLcall("glDisable(GL_TEXTURE_2D)");
2341 glEnable(GL_TEXTURE_3D);
2342 checkGLcall("glEnable(GL_TEXTURE_3D)");
2344 case GL_TEXTURE_CUBE_MAP_ARB:
2345 glDisable(GL_TEXTURE_2D);
2346 checkGLcall("glDisable(GL_TEXTURE_2D)");
2347 glDisable(GL_TEXTURE_3D);
2348 checkGLcall("glDisable(GL_TEXTURE_3D)");
2349 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2350 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2351 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2353 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2354 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2358 glEnable(GL_TEXTURE_2D);
2359 checkGLcall("glEnable(GL_TEXTURE_2D)");
2360 glDisable(GL_TEXTURE_3D);
2361 checkGLcall("glDisable(GL_TEXTURE_3D)");
2362 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2363 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2364 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2366 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2367 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2368 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2370 /* Binding textures is done by samplers. A dummy texture will be bound */
2374 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2375 DWORD sampler = state - STATE_SAMPLER(0);
2376 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2378 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2379 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2380 * will take care of this business
2382 if(mapped_stage == -1 || mapped_stage >= GL_LIMITS(textures)) return;
2383 if(sampler >= stateblock->lowest_disabled_stage) return;
2384 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2386 texture_activate_dimensions(sampler, stateblock, context);
2388 #undef GLINFO_LOCATION
2390 unsigned int ffp_frag_program_key_hash(const void *key)
2392 const struct ffp_frag_settings *k = key;
2393 unsigned int hash = 0, i;
2396 /* This takes the texture op settings of stage 0 and 1 into account.
2397 * how exactly depends on the memory laybout of the compiler, but it
2398 * should not matter too much. Stages > 1 are used rarely, so there's
2399 * no need to process them. Even if they're used it is likely that
2400 * the ffp setup has distinct stage 0 and 1 settings.
2402 for(i = 0; i < 2; i++) {
2403 blob = (const DWORD *)&k->op[i];
2404 hash ^= blob[0] ^ blob[1];
2407 hash += ~(hash << 15);
2408 hash ^= (hash >> 10);
2409 hash += (hash << 3);
2410 hash ^= (hash >> 6);
2411 hash += ~(hash << 11);
2412 hash ^= (hash >> 16);
2417 BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb)
2419 const struct ffp_frag_settings *ka = keya;
2420 const struct ffp_frag_settings *kb = keyb;
2422 return memcmp(ka, kb, sizeof(*ka)) == 0;
2425 UINT wined3d_log2i(UINT32 x)
2427 static const BYTE l[] =
2429 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2430 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2431 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2432 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2433 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2434 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2435 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2436 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2437 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2438 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2439 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2440 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2441 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2442 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2443 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2444 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2448 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];