2 * Utility functions for the WineD3D Library
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2008 Henri Verbeet
9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wined3d_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
31 struct StaticPixelFormatDesc
34 DWORD alphaMask, redMask, greenMask, blueMask;
36 short depthSize, stencilSize;
40 /*****************************************************************************
43 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
44 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
45 * high masks do not fit into the 32 bit values needed for ddraw. It is only
46 * used for ddraw mostly, and to figure out if the format has alpha at all, so
47 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
48 * formats are not usable in 2D rendering because ddraw doesn't support them.
50 static const struct StaticPixelFormatDesc formats[] =
52 /* WINED3DFORMAT alphamask redmask greenmask bluemask bpp depth stencil isFourcc */
53 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, FALSE},
54 /* FourCC formats, kept here to have WINED3DFMT_R8G8B8(=20) at position 20 */
55 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
56 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
57 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
58 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
59 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
60 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
61 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
62 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
63 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
64 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
65 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
67 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
68 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
69 {WINED3DFMT_R32G32B32_FLOAT, 0x0, 0x0, 0x0, 0x0, 12, 0, 0, FALSE},
70 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0, FALSE},
72 {WINED3DFMT_CxV8U8, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
74 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
75 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
76 {WINED3DFMT_R16G16_SINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
77 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
78 {WINED3DFMT_R16G16B16A16_SINT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
79 /* Palettized formats */
80 {WINED3DFMT_A8P8, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
81 {WINED3DFMT_P8, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
82 /* Standard ARGB formats. */
83 {WINED3DFMT_R8G8B8, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0, FALSE},
84 {WINED3DFMT_A8R8G8B8, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0, FALSE},
85 {WINED3DFMT_X8R8G8B8, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0, FALSE},
86 {WINED3DFMT_R5G6B5, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0, FALSE},
87 {WINED3DFMT_X1R5G5B5, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0, FALSE},
88 {WINED3DFMT_A1R5G5B5, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0, FALSE},
89 {WINED3DFMT_A4R4G4B4, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0, FALSE},
90 {WINED3DFMT_R3G3B2, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0, FALSE},
91 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
92 {WINED3DFMT_A8R3G3B2, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0, FALSE},
93 {WINED3DFMT_X4R4G4B4, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0, FALSE},
94 {WINED3DFMT_R10G10B10A2_UNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
95 {WINED3DFMT_R10G10B10A2_UINT, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
96 {WINED3DFMT_R10G10B10A2_SNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
97 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
98 {WINED3DFMT_R8G8B8A8_UINT, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
99 {WINED3DFMT_X8B8G8R8, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
100 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0, FALSE},
101 {WINED3DFMT_A2R10G10B10, 0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0, FALSE},
102 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0, FALSE},
104 {WINED3DFMT_L8, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
105 {WINED3DFMT_A8L8, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
106 {WINED3DFMT_A4L4, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
107 /* Bump mapping stuff */
108 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
109 {WINED3DFMT_L6V5U5, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
110 {WINED3DFMT_X8L8V8U8, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
111 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
112 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
113 {WINED3DFMT_W11V11U10, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
114 {WINED3DFMT_A2W10V10U10, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
115 /* Depth stencil formats */
116 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
117 {WINED3DFMT_D32, 0x0, 0x0, 0x0, 0x0, 4, 32, 0, FALSE},
118 {WINED3DFMT_D15S1, 0x0, 0x0, 0x0, 0x0, 2, 15, 1, FALSE},
119 {WINED3DFMT_D24S8, 0x0, 0x0, 0x0, 0x0, 4, 24, 8, FALSE},
120 {WINED3DFMT_D24X8, 0x0, 0x0, 0x0, 0x0, 4, 24, 0, FALSE},
121 {WINED3DFMT_D24X4S4, 0x0, 0x0, 0x0, 0x0, 4, 24, 4, FALSE},
122 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
123 {WINED3DFMT_L16, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
124 {WINED3DFMT_D32F_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 4, 32, 0, FALSE},
125 {WINED3DFMT_D24FS8, 0x0, 0x0, 0x0, 0x0, 4, 24, 8, FALSE},
126 /* Is this a vertex buffer? */
127 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, FALSE},
128 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
129 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
130 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
131 /* Vendor-specific formats */
132 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
133 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
134 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
137 struct wined3d_format_compression_info
139 WINED3DFORMAT format;
142 UINT block_byte_count;
145 static const struct wined3d_format_compression_info format_compression_info[] =
147 {WINED3DFMT_DXT1, 4, 4, 8},
148 {WINED3DFMT_DXT2, 4, 4, 16},
149 {WINED3DFMT_DXT3, 4, 4, 16},
150 {WINED3DFMT_DXT4, 4, 4, 16},
151 {WINED3DFMT_DXT5, 4, 4, 16},
152 {WINED3DFMT_ATI2N, 4, 4, 16},
155 struct wined3d_format_vertex_info
157 WINED3DFORMAT format;
158 enum wined3d_ffp_emit_idx emit_idx;
159 GLint component_count;
162 GLboolean gl_normalized;
163 unsigned int component_size;
166 static const struct wined3d_format_vertex_info format_vertex_info[] =
168 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
169 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
170 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
171 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
172 {WINED3DFMT_A8R8G8B8, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
173 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
174 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
175 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
176 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
177 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
178 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
179 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
180 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
181 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
182 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
183 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
184 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
189 GLint glInternal, glGammaInternal, rtInternal, glFormat, glType;
191 GL_SupportedExt extension;
192 } GlPixelFormatDescTemplate;
194 /*****************************************************************************
195 * OpenGL format template. Contains unexciting formats which do not need
196 * extension checks. The order in this table is independent of the order in
197 * the table StaticPixelFormatDesc above. Not all formats have to be in this
200 static const GlPixelFormatDescTemplate gl_formats_template[] = {
201 /* WINED3DFORMAT internal srgbInternal rtInternal
206 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
207 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
208 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
209 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
212 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
213 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
214 WINED3DFMT_FLAG_FILTERING,
215 WINED3D_GL_EXT_NONE},
216 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
217 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE,
218 WINED3DFMT_FLAG_FILTERING,
220 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
221 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
222 WINED3DFMT_FLAG_FILTERING,
223 WINED3D_GL_EXT_NONE},
224 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
225 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE,
226 WINED3DFMT_FLAG_FILTERING,
228 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
229 GL_ALPHA, GL_UNSIGNED_BYTE,
230 WINED3DFMT_FLAG_FILTERING,
231 WINED3D_GL_EXT_NONE},
232 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
233 GL_RGBA, GL_UNSIGNED_BYTE,
234 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
235 EXT_TEXTURE_COMPRESSION_S3TC},
236 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
237 GL_RGBA, GL_UNSIGNED_BYTE,
238 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
239 EXT_TEXTURE_COMPRESSION_S3TC},
240 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
241 GL_RGBA, GL_UNSIGNED_BYTE,
242 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
243 EXT_TEXTURE_COMPRESSION_S3TC},
244 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
245 GL_RGBA, GL_UNSIGNED_BYTE,
246 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
247 EXT_TEXTURE_COMPRESSION_S3TC},
248 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
249 GL_RGBA, GL_UNSIGNED_BYTE,
250 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
251 EXT_TEXTURE_COMPRESSION_S3TC},
253 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
255 WINED3DFMT_FLAG_RENDERTARGET,
257 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
259 WINED3DFMT_FLAG_RENDERTARGET,
261 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
263 WINED3DFMT_FLAG_RENDERTARGET,
265 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
267 WINED3DFMT_FLAG_RENDERTARGET,
269 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
271 WINED3DFMT_FLAG_RENDERTARGET,
274 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
275 GL_RED, GL_HALF_FLOAT_ARB,
276 WINED3DFMT_FLAG_RENDERTARGET,
278 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
279 GL_RED, GL_HALF_FLOAT_ARB,
280 WINED3DFMT_FLAG_RENDERTARGET,
282 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
283 GL_RGB, GL_HALF_FLOAT_ARB,
284 WINED3DFMT_FLAG_RENDERTARGET,
286 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
287 GL_RG, GL_HALF_FLOAT_ARB,
288 WINED3DFMT_FLAG_RENDERTARGET,
290 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
291 GL_RGBA, GL_HALF_FLOAT_ARB,
292 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
294 /* Palettized formats */
295 {WINED3DFMT_P8, GL_RGBA, GL_RGBA, 0,
296 GL_RGBA, GL_UNSIGNED_BYTE,
297 WINED3DFMT_FLAG_GETDC,
298 ARB_FRAGMENT_PROGRAM},
299 {WINED3DFMT_P8, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
300 GL_COLOR_INDEX, GL_UNSIGNED_BYTE,
301 WINED3DFMT_FLAG_GETDC,
302 EXT_PALETTED_TEXTURE},
303 /* Standard ARGB formats */
304 {WINED3DFMT_R8G8B8, GL_RGB8, GL_RGB8, 0,
305 GL_BGR, GL_UNSIGNED_BYTE,
306 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET |
307 WINED3DFMT_FLAG_GETDC,
308 WINED3D_GL_EXT_NONE},
309 {WINED3DFMT_A8R8G8B8, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
310 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
311 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET |
312 WINED3DFMT_FLAG_GETDC,
313 WINED3D_GL_EXT_NONE},
314 {WINED3DFMT_X8R8G8B8, GL_RGB8, GL_SRGB8_EXT, 0,
315 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
316 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET |
317 WINED3DFMT_FLAG_GETDC,
318 WINED3D_GL_EXT_NONE},
319 {WINED3DFMT_R5G6B5, GL_RGB5, GL_RGB5, GL_RGB8,
320 GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
321 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET |
322 WINED3DFMT_FLAG_GETDC,
323 WINED3D_GL_EXT_NONE},
324 {WINED3DFMT_X1R5G5B5, GL_RGB5, GL_RGB5_A1, 0,
325 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
326 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING |
327 WINED3DFMT_FLAG_GETDC,
328 WINED3D_GL_EXT_NONE},
329 {WINED3DFMT_A1R5G5B5, GL_RGB5_A1, GL_RGB5_A1, 0,
330 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
331 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING |
332 WINED3DFMT_FLAG_GETDC,
333 WINED3D_GL_EXT_NONE},
334 {WINED3DFMT_A4R4G4B4, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
335 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
336 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING |
337 WINED3DFMT_FLAG_GETDC,
338 WINED3D_GL_EXT_NONE},
339 {WINED3DFMT_R3G3B2, GL_R3_G3_B2, GL_R3_G3_B2, 0,
340 GL_RGB, GL_UNSIGNED_BYTE_3_3_2,
341 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
342 WINED3D_GL_EXT_NONE},
343 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
344 GL_ALPHA, GL_UNSIGNED_BYTE,
345 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
346 WINED3D_GL_EXT_NONE},
347 {WINED3DFMT_X4R4G4B4, GL_RGB4, GL_RGB4, 0,
348 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
349 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_GETDC,
350 WINED3D_GL_EXT_NONE},
351 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
352 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV,
353 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
354 WINED3D_GL_EXT_NONE},
355 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
356 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
357 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_GETDC,
358 WINED3D_GL_EXT_NONE},
359 {WINED3DFMT_X8B8G8R8, GL_RGB8, GL_RGB8, 0,
360 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
361 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_GETDC,
362 WINED3D_GL_EXT_NONE},
363 {WINED3DFMT_R16G16_UNORM, GL_RGB16_EXT, GL_RGB16_EXT, GL_RGBA16_EXT,
364 GL_RGB, GL_UNSIGNED_SHORT,
365 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
366 WINED3D_GL_EXT_NONE},
367 {WINED3DFMT_A2R10G10B10, GL_RGB10_A2, GL_RGB10_A2, 0,
368 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV,
369 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
370 WINED3D_GL_EXT_NONE},
371 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16_EXT, GL_RGBA16_EXT, 0,
372 GL_RGBA, GL_UNSIGNED_SHORT,
373 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
374 WINED3D_GL_EXT_NONE},
376 {WINED3DFMT_L8, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
377 GL_LUMINANCE, GL_UNSIGNED_BYTE,
378 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
379 WINED3D_GL_EXT_NONE},
380 {WINED3DFMT_A8L8, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
381 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
382 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
383 WINED3D_GL_EXT_NONE},
384 {WINED3DFMT_A4L4, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
385 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
387 WINED3D_GL_EXT_NONE},
388 /* Bump mapping stuff */
389 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
390 GL_BGR, GL_UNSIGNED_BYTE,
391 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
392 WINED3D_GL_EXT_NONE},
393 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
395 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
397 {WINED3DFMT_L6V5U5, GL_RGB5, GL_RGB5, 0,
398 GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
399 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
400 WINED3D_GL_EXT_NONE},
401 {WINED3DFMT_L6V5U5, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
402 GL_DSDT_MAG_NV, GL_BYTE,
403 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
405 {WINED3DFMT_X8L8V8U8, GL_RGB8, GL_RGB8, 0,
406 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
407 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
408 WINED3D_GL_EXT_NONE},
409 {WINED3DFMT_X8L8V8U8, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
410 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV,
411 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
413 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
414 GL_BGRA, GL_UNSIGNED_BYTE,
415 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
416 WINED3D_GL_EXT_NONE},
417 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
419 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
421 {WINED3DFMT_R16G16_SNORM, GL_RGB16_EXT, GL_RGB16_EXT, 0,
422 GL_BGR, GL_UNSIGNED_SHORT,
423 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
424 WINED3D_GL_EXT_NONE},
425 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
426 GL_HILO_NV, GL_SHORT,
427 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
429 /* Depth stencil formats */
430 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
431 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
432 WINED3DFMT_FLAG_DEPTH,
434 {WINED3DFMT_D32, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
435 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
436 WINED3DFMT_FLAG_DEPTH,
438 {WINED3DFMT_D15S1, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
439 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
440 WINED3DFMT_FLAG_DEPTH,
442 {WINED3DFMT_D15S1, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
443 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
444 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
445 EXT_PACKED_DEPTH_STENCIL},
446 {WINED3DFMT_D24S8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
447 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
448 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
450 {WINED3DFMT_D24S8, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
451 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
452 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
453 EXT_PACKED_DEPTH_STENCIL},
454 {WINED3DFMT_D24X8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
455 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
456 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
458 {WINED3DFMT_D24X4S4, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
459 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
460 WINED3DFMT_FLAG_DEPTH,
462 {WINED3DFMT_D24X4S4, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
463 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
464 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
465 EXT_PACKED_DEPTH_STENCIL},
466 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
467 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
468 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
470 {WINED3DFMT_L16, GL_LUMINANCE16_EXT, GL_LUMINANCE16_EXT, 0,
471 GL_LUMINANCE, GL_UNSIGNED_SHORT,
472 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
473 WINED3D_GL_EXT_NONE},
474 {WINED3DFMT_D32F_LOCKABLE, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
475 GL_DEPTH_COMPONENT, GL_FLOAT,
476 WINED3DFMT_FLAG_DEPTH,
477 ARB_DEPTH_BUFFER_FLOAT},
478 {WINED3DFMT_D24FS8, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
479 GL_DEPTH_STENCIL_EXT, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
480 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
481 ARB_DEPTH_BUFFER_FLOAT},
482 /* Vendor-specific formats */
483 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
484 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
486 ATI_TEXTURE_COMPRESSION_3DC},
487 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, 0,
488 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
490 EXT_TEXTURE_COMPRESSION_RGTC},
493 static inline int getFmtIdx(WINED3DFORMAT fmt) {
494 /* First check if the format is at the position of its value.
495 * This will catch the argb formats before the loop is entered
497 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
501 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
502 if(formats[i].format == fmt) {
510 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
512 UINT format_count = sizeof(formats) / sizeof(*formats);
515 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->gl_formats));
516 if (!gl_info->gl_formats)
518 ERR("Failed to allocate memory.\n");
522 for (i = 0; i < format_count; ++i)
524 struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
525 desc->format = formats[i].format;
526 desc->red_mask = formats[i].redMask;
527 desc->green_mask = formats[i].greenMask;
528 desc->blue_mask = formats[i].blueMask;
529 desc->alpha_mask = formats[i].alphaMask;
530 desc->byte_count = formats[i].bpp;
531 desc->depth_size = formats[i].depthSize;
532 desc->stencil_size = formats[i].stencilSize;
533 if (formats[i].isFourcc) desc->Flags |= WINED3DFMT_FLAG_FOURCC;
539 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
543 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
545 struct GlPixelFormatDesc *format_desc;
546 int fmt_idx = getFmtIdx(format_compression_info[i].format);
550 ERR("Format %s (%#x) not found.\n",
551 debug_d3dformat(format_compression_info[i].format), format_compression_info[i].format);
555 format_desc = &gl_info->gl_formats[fmt_idx];
556 format_desc->block_width = format_compression_info[i].block_width;
557 format_desc->block_height = format_compression_info[i].block_height;
558 format_desc->block_byte_count = format_compression_info[i].block_byte_count;
559 format_desc->Flags |= WINED3DFMT_FLAG_COMPRESSED;
565 #define GLINFO_LOCATION (*gl_info)
567 /* Context activation is done by the caller. */
568 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPixelFormatDesc *format_desc)
570 /* Check if the default internal format is supported as a frame buffer
571 * target, otherwise fall back to the render target internal.
573 * Try to stick to the standard format if possible, this limits precision differences. */
582 glGenTextures(1, &tex);
583 glBindTexture(GL_TEXTURE_2D, tex);
585 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glInternal, 16, 16, 0,
586 format_desc->glFormat, format_desc->glType, NULL);
587 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
588 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
590 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
592 status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
593 checkGLcall("Framebuffer format check");
595 if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
597 TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(format_desc->format));
598 format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
599 format_desc->rtInternal = format_desc->glInternal;
603 if (!format_desc->rtInternal)
605 if (format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)
607 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
608 " and no fallback specified.\n", debug_d3dformat(format_desc->format));
609 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
613 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format_desc->format));
615 format_desc->rtInternal = format_desc->glInternal;
619 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
620 debug_d3dformat(format_desc->format));
624 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0));
626 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->rtInternal, 16, 16, 0,
627 format_desc->glFormat, format_desc->glType, NULL);
628 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
629 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
631 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
633 status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
634 checkGLcall("Framebuffer format check");
636 if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
638 TRACE("Format %s rtInternal format is supported as FBO color attachment\n",
639 debug_d3dformat(format_desc->format));
643 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
644 debug_d3dformat(format_desc->format));
645 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
650 if (status == GL_FRAMEBUFFER_COMPLETE_EXT && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
654 if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
656 GL_EXTCALL(glGenRenderbuffersEXT(1, &rb));
657 GL_EXTCALL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb));
658 GL_EXTCALL(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, 16, 16));
659 GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
660 GL_RENDERBUFFER_EXT, rb));
661 GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
662 GL_RENDERBUFFER_EXT, rb));
663 checkGLcall("RB attachment");
667 glClear(GL_COLOR_BUFFER_BIT);
668 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION_EXT)
671 TRACE("Format doesn't support post-pixelshader blending.\n");
672 format_desc->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
675 if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
677 GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
678 GL_RENDERBUFFER_EXT, 0));
679 GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
680 GL_RENDERBUFFER_EXT, 0));
681 GL_EXTCALL(glDeleteRenderbuffersEXT(1, &rb));
682 checkGLcall("RB cleanup");
686 glDeleteTextures(1, &tex);
691 /* Context activation is done by the caller. */
692 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
697 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
701 GL_EXTCALL(glGenFramebuffersEXT(1, &fbo));
702 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
707 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
709 struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
711 if (!desc->glInternal) continue;
713 if (desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
715 TRACE("Skipping format %s because it's a depth/stencil format.\n",
716 debug_d3dformat(desc->format));
720 if (desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
722 TRACE("Skipping format %s because it's a compressed format.\n",
723 debug_d3dformat(desc->format));
727 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
729 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc->format));
730 check_fbo_compat(gl_info, desc);
734 desc->rtInternal = desc->glInternal;
738 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
742 GL_EXTCALL(glDeleteFramebuffersEXT(1, &fbo));
748 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
752 for (i = 0; i < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); ++i)
754 int fmt_idx = getFmtIdx(gl_formats_template[i].fmt);
755 struct GlPixelFormatDesc *desc;
759 ERR("Format %s (%#x) not found.\n",
760 debug_d3dformat(gl_formats_template[i].fmt), gl_formats_template[i].fmt);
764 if (!GL_SUPPORT(gl_formats_template[i].extension)) continue;
766 desc = &gl_info->gl_formats[fmt_idx];
767 desc->glInternal = gl_formats_template[i].glInternal;
768 desc->glGammaInternal = gl_formats_template[i].glGammaInternal;
769 desc->rtInternal = gl_formats_template[i].rtInternal;
770 desc->glFormat = gl_formats_template[i].glFormat;
771 desc->glType = gl_formats_template[i].glType;
772 desc->color_fixup = COLOR_FIXUP_IDENTITY;
773 desc->Flags |= gl_formats_template[i].Flags;
774 desc->heightscale = 1.0f;
780 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
782 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
784 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
786 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
788 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
792 /* A context is provided by the caller */
793 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
795 GLuint tex, fbo, buffer;
796 const DWORD data[] = {0x00000000, 0xffffffff};
797 DWORD readback[16 * 1];
800 /* Render a filtered texture and see what happens. This is intended to detect the lack of
801 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
802 * falling back to software. If this changes in the future this code will get fooled and
803 * apps might hit the software path due to incorrectly advertised caps.
805 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
806 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
807 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
813 glGenTextures(1, &buffer);
814 glBindTexture(GL_TEXTURE_2D, buffer);
815 memset(readback, 0x7e, sizeof(readback));
816 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
817 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
818 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
819 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
820 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
821 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
823 glGenTextures(1, &tex);
824 glBindTexture(GL_TEXTURE_2D, tex);
825 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
826 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
827 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
828 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
829 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
830 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
831 glEnable(GL_TEXTURE_2D);
833 GL_EXTCALL(glGenFramebuffersEXT(1, &fbo));
834 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
835 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, buffer, 0));
836 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
838 glViewport(0, 0, 16, 1);
839 glDisable(GL_LIGHTING);
840 glMatrixMode(GL_MODELVIEW);
842 glMatrixMode(GL_PROJECTION);
845 glClearColor(0, 1, 0, 0);
846 glClear(GL_COLOR_BUFFER_BIT);
848 glBegin(GL_TRIANGLE_STRIP);
849 glTexCoord2f(0.0, 0.0);
850 glVertex2f(-1.0f, -1.0f);
851 glTexCoord2f(1.0, 0.0);
852 glVertex2f(1.0f, -1.0f);
853 glTexCoord2f(0.0, 1.0);
854 glVertex2f(-1.0f, 1.0f);
855 glTexCoord2f(1.0, 1.0);
856 glVertex2f(1.0f, 1.0f);
859 glBindTexture(GL_TEXTURE_2D, buffer);
860 memset(readback, 0x7f, sizeof(readback));
861 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
862 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
863 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
865 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
866 readback[6], readback[9]);
871 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
872 readback[6], readback[9]);
876 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
877 GL_EXTCALL(glDeleteFramebuffersEXT(1, &fbo));
878 glDeleteTextures(1, &tex);
879 glDeleteTextures(1, &buffer);
883 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
890 static void init_format_filter_info(struct wined3d_gl_info *gl_info)
892 unsigned int fmt_idx, i;
893 WINED3DFORMAT fmts16[] = {
894 WINED3DFMT_R16_FLOAT,
895 WINED3DFMT_R16G16_FLOAT,
896 WINED3DFMT_R16G16B16A16_FLOAT,
899 struct GlPixelFormatDesc *desc;
901 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
903 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
904 if(gl_info->gl_vendor == VENDOR_NVIDIA && GL_SUPPORT(ARB_TEXTURE_FLOAT))
906 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
909 else if(GL_LIMITS(glsl_varyings > 44))
911 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
916 TRACE("Assuming no float16 blending\n");
922 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
924 fmt_idx = getFmtIdx(fmts16[i]);
925 gl_info->gl_formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
931 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
933 fmt_idx = getFmtIdx(fmts16[i]);
934 desc = &gl_info->gl_formats[fmt_idx];
935 if(!desc->glInternal) continue; /* Not supported by GL */
937 filtered = check_filter(gl_info, gl_info->gl_formats[fmt_idx].glInternal);
940 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
941 desc->Flags |= WINED3DFMT_FLAG_FILTERING;
945 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
950 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
954 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
955 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
956 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
958 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
959 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
960 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
962 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
963 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
964 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
966 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
967 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
968 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
970 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
971 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
972 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
974 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
975 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
976 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
977 * the only driver that implements it(fglrx) has a buggy implementation.
979 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
980 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
981 * conversion for this format.
983 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
985 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
986 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
987 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
988 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
989 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
990 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
994 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
995 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
996 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
997 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
998 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
999 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1002 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
1004 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1007 idx = getFmtIdx(WINED3DFMT_L6V5U5);
1008 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1009 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1010 idx = getFmtIdx(WINED3DFMT_X8L8V8U8);
1011 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1012 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1013 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1014 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1015 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1019 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1020 * are converted at surface loading time, but they do not need any modification in
1021 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1022 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1026 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC))
1028 idx = getFmtIdx(WINED3DFMT_ATI2N);
1029 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1030 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1032 else if (GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC))
1034 idx = getFmtIdx(WINED3DFMT_ATI2N);
1035 gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
1036 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1039 if (!GL_SUPPORT(APPLE_YCBCR_422))
1041 idx = getFmtIdx(WINED3DFMT_YUY2);
1042 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
1044 idx = getFmtIdx(WINED3DFMT_UYVY);
1045 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
1048 idx = getFmtIdx(WINED3DFMT_YV12);
1049 gl_info->gl_formats[idx].heightscale = 1.5f;
1050 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
1052 if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
1054 idx = getFmtIdx(WINED3DFMT_A8R8G8B8);
1055 gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
1058 if (GL_SUPPORT(ARB_HALF_FLOAT_VERTEX))
1060 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1061 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1062 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1063 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1065 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1066 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1070 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1074 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1076 struct GlPixelFormatDesc *format_desc;
1077 int fmt_idx = getFmtIdx(format_vertex_info[i].format);
1081 ERR("Format %s (%#x) not found.\n",
1082 debug_d3dformat(format_vertex_info[i].format), format_vertex_info[i].format);
1086 format_desc = &gl_info->gl_formats[fmt_idx];
1087 format_desc->emit_idx = format_vertex_info[i].emit_idx;
1088 format_desc->component_count = format_vertex_info[i].component_count;
1089 format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1090 format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1091 format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
1092 format_desc->component_size = format_vertex_info[i].component_size;
1098 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1100 if (!init_format_base_info(gl_info)) return FALSE;
1102 if (!init_format_compression_info(gl_info))
1104 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1111 /* Context activation is done by the caller. */
1112 BOOL initPixelFormats(struct wined3d_gl_info *gl_info)
1114 if (!init_format_base_info(gl_info)) return FALSE;
1116 if (!init_format_compression_info(gl_info)) goto fail;
1117 if (!init_format_texture_info(gl_info)) goto fail;
1118 if (!init_format_vertex_info(gl_info)) goto fail;
1120 apply_format_fixups(gl_info);
1121 init_format_fbo_compat_info(gl_info);
1122 init_format_filter_info(gl_info);
1127 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1131 #undef GLINFO_LOCATION
1133 #define GLINFO_LOCATION This->adapter->gl_info
1135 const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info)
1137 int idx = getFmtIdx(fmt);
1140 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
1141 /* Get the caller a valid pointer */
1142 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1145 return &gl_info->gl_formats[idx];
1148 /*****************************************************************************
1149 * Trace formatting of useful values
1151 const char* debug_d3dformat(WINED3DFORMAT fmt) {
1153 #define FMT_TO_STR(fmt) case fmt: return #fmt
1154 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1155 FMT_TO_STR(WINED3DFMT_R8G8B8);
1156 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
1157 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
1158 FMT_TO_STR(WINED3DFMT_R5G6B5);
1159 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
1160 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
1161 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
1162 FMT_TO_STR(WINED3DFMT_R3G3B2);
1163 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
1164 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
1165 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
1166 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
1167 FMT_TO_STR(WINED3DFMT_A8P8);
1168 FMT_TO_STR(WINED3DFMT_P8);
1169 FMT_TO_STR(WINED3DFMT_L8);
1170 FMT_TO_STR(WINED3DFMT_A8L8);
1171 FMT_TO_STR(WINED3DFMT_A4L4);
1172 FMT_TO_STR(WINED3DFMT_L6V5U5);
1173 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
1174 FMT_TO_STR(WINED3DFMT_W11V11U10);
1175 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
1176 FMT_TO_STR(WINED3DFMT_UYVY);
1177 FMT_TO_STR(WINED3DFMT_YUY2);
1178 FMT_TO_STR(WINED3DFMT_YV12);
1179 FMT_TO_STR(WINED3DFMT_DXT1);
1180 FMT_TO_STR(WINED3DFMT_DXT2);
1181 FMT_TO_STR(WINED3DFMT_DXT3);
1182 FMT_TO_STR(WINED3DFMT_DXT4);
1183 FMT_TO_STR(WINED3DFMT_DXT5);
1184 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1185 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1186 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1187 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1188 FMT_TO_STR(WINED3DFMT_D32);
1189 FMT_TO_STR(WINED3DFMT_D15S1);
1190 FMT_TO_STR(WINED3DFMT_D24S8);
1191 FMT_TO_STR(WINED3DFMT_D24X8);
1192 FMT_TO_STR(WINED3DFMT_D24X4S4);
1193 FMT_TO_STR(WINED3DFMT_L16);
1194 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
1195 FMT_TO_STR(WINED3DFMT_D24FS8);
1196 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1197 FMT_TO_STR(WINED3DFMT_CxV8U8);
1198 FMT_TO_STR(WINED3DFMT_ATI2N);
1199 FMT_TO_STR(WINED3DFMT_NVHU);
1200 FMT_TO_STR(WINED3DFMT_NVHS);
1201 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1202 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1203 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1204 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1205 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1206 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1207 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1208 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1209 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1210 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1211 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1212 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1213 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1214 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1215 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1216 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1217 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1218 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1219 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1220 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1221 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1222 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1223 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1224 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1225 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1226 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1227 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1228 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1229 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1230 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1231 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1232 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1233 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1234 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1235 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1236 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1237 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1238 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1239 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1240 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1241 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1242 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1243 FMT_TO_STR(WINED3DFMT_R32_UINT);
1244 FMT_TO_STR(WINED3DFMT_R32_SINT);
1245 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1246 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1247 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1248 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1249 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1250 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1251 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1252 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1253 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1254 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1255 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1256 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1257 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1258 FMT_TO_STR(WINED3DFMT_R16_UINT);
1259 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1260 FMT_TO_STR(WINED3DFMT_R16_SINT);
1261 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1262 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1263 FMT_TO_STR(WINED3DFMT_R8_UINT);
1264 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1265 FMT_TO_STR(WINED3DFMT_R8_SINT);
1266 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1267 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1268 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1269 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1270 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1271 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1272 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1273 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1274 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1275 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1276 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1277 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1278 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1279 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1280 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1281 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1282 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1283 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1284 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1285 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1286 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1287 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1288 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1289 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1294 fourcc[0] = (char)(fmt);
1295 fourcc[1] = (char)(fmt >> 8);
1296 fourcc[2] = (char)(fmt >> 16);
1297 fourcc[3] = (char)(fmt >> 24);
1299 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
1300 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
1302 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
1304 return "unrecognized";
1308 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
1310 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1311 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1312 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1313 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1314 #undef DEVTYPE_TO_STR
1316 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1317 return "unrecognized";
1321 const char *debug_d3dusage(DWORD usage)
1326 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1327 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1328 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1329 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1330 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1331 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1332 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1333 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1334 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1335 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1336 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1337 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1338 #undef WINED3DUSAGE_TO_STR
1339 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1341 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1344 const char *debug_d3dusagequery(DWORD usagequery)
1349 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1350 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1351 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1352 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1353 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1354 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1355 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1356 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1357 #undef WINED3DUSAGEQUERY_TO_STR
1358 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1360 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1363 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1365 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1366 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1367 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1368 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1369 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1370 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1371 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1372 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1373 #undef WINED3DDECLMETHOD_TO_STR
1375 FIXME("Unrecognized %u declaration method!\n", method);
1376 return "unrecognized";
1380 const char* debug_d3ddeclusage(BYTE usage) {
1382 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1383 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1384 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1385 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1386 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1387 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1388 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1389 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1390 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1391 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1392 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1393 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1394 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1395 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1396 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1397 #undef WINED3DDECLUSAGE_TO_STR
1399 FIXME("Unrecognized %u declaration usage!\n", usage);
1400 return "unrecognized";
1404 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1406 #define RES_TO_STR(res) case res: return #res
1407 RES_TO_STR(WINED3DRTYPE_SURFACE);
1408 RES_TO_STR(WINED3DRTYPE_VOLUME);
1409 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1410 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1411 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1412 RES_TO_STR(WINED3DRTYPE_BUFFER);
1415 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1416 return "unrecognized";
1420 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1421 switch (PrimitiveType) {
1422 #define PRIM_TO_STR(prim) case prim: return #prim
1423 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1424 PRIM_TO_STR(WINED3DPT_POINTLIST);
1425 PRIM_TO_STR(WINED3DPT_LINELIST);
1426 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1427 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1428 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1429 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1430 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1431 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1432 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1433 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1436 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1437 return "unrecognized";
1441 const char* debug_d3drenderstate(DWORD state) {
1443 #define D3DSTATE_TO_STR(u) case u: return #u
1444 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
1445 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1446 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
1447 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1448 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1449 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1450 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1451 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1452 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1453 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1454 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1455 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1456 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1457 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1458 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1459 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1460 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
1461 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
1462 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1463 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1464 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
1465 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1466 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1467 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1468 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1469 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1470 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1471 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1472 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1473 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1474 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1475 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1476 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1477 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1478 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1479 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1480 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1481 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1482 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1483 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1484 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1485 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
1486 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
1487 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
1488 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1489 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1490 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1491 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1492 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1493 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1494 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1495 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1496 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1497 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1498 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1499 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1500 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1501 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1502 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1503 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
1504 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
1505 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
1506 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
1507 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
1508 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
1509 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
1510 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
1511 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
1512 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
1513 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
1514 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
1515 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
1516 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
1517 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
1518 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
1519 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
1520 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
1521 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
1522 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
1523 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
1524 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
1525 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
1526 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
1527 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
1528 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
1529 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
1530 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
1531 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
1532 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
1533 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
1534 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
1535 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1536 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1537 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1538 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1539 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1540 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1541 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1542 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1543 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1544 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1545 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1546 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1547 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1548 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1549 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1550 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1551 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1552 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1553 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1554 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1555 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1556 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1557 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1558 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1559 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1560 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1561 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1562 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1563 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1564 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1565 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1566 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1567 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1568 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1569 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1570 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1571 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1572 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1573 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1574 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1575 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1576 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1577 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1578 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1579 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1580 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1581 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1582 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1583 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1584 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1585 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1586 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1587 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1588 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1589 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1590 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1591 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1592 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1593 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1594 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1595 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1596 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1597 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1598 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1599 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1600 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1601 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1602 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1603 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1604 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1605 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1606 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1607 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1608 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1609 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1610 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1611 #undef D3DSTATE_TO_STR
1613 FIXME("Unrecognized %u render state!\n", state);
1614 return "unrecognized";
1618 const char* debug_d3dsamplerstate(DWORD state) {
1620 #define D3DSTATE_TO_STR(u) case u: return #u
1621 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1622 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1623 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1624 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1625 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1626 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1627 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1628 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1629 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1630 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1631 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1632 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1633 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1634 #undef D3DSTATE_TO_STR
1636 FIXME("Unrecognized %u sampler state!\n", state);
1637 return "unrecognized";
1641 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1642 switch (filter_type) {
1643 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1644 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1645 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1646 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1647 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1648 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1649 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1650 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1651 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1652 #undef D3DTEXTUREFILTERTYPE_TO_STR
1654 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1655 return "unrecognized";
1659 const char* debug_d3dtexturestate(DWORD state) {
1661 #define D3DSTATE_TO_STR(u) case u: return #u
1662 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1663 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1664 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1665 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1666 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1667 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1668 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1669 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1670 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1671 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1672 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1673 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1674 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1675 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1676 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1677 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1678 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1679 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1680 #undef D3DSTATE_TO_STR
1682 FIXME("Unrecognized %u texture state!\n", state);
1683 return "unrecognized";
1687 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1689 #define D3DTOP_TO_STR(u) case u: return #u
1690 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1691 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1692 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1693 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1694 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1695 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1696 D3DTOP_TO_STR(WINED3DTOP_ADD);
1697 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1698 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1699 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1700 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1701 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1702 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1703 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1704 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1705 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1706 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1707 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1708 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1709 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1710 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1711 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1712 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1713 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1714 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1715 D3DTOP_TO_STR(WINED3DTOP_LERP);
1716 #undef D3DTOP_TO_STR
1718 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1719 return "unrecognized";
1723 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1725 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1726 TSTYPE_TO_STR(WINED3DTS_VIEW);
1727 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1728 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1729 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1730 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1731 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1732 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1733 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1734 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1735 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1736 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1737 #undef TSTYPE_TO_STR
1739 if (tstype > 256 && tstype < 512) {
1740 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1741 return ("WINED3DTS_WORLDMATRIX > 0");
1743 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1744 return "unrecognized";
1748 const char* debug_d3dpool(WINED3DPOOL Pool) {
1750 #define POOL_TO_STR(p) case p: return #p
1751 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1752 POOL_TO_STR(WINED3DPOOL_MANAGED);
1753 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1754 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1757 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1758 return "unrecognized";
1762 const char *debug_fbostatus(GLenum status) {
1764 #define FBOSTATUS_TO_STR(u) case u: return #u
1765 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1766 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1767 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1768 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1769 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1770 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1771 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1772 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
1773 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1774 #undef FBOSTATUS_TO_STR
1776 FIXME("Unrecognied FBO status 0x%08x\n", status);
1777 return "unrecognized";
1781 const char *debug_glerror(GLenum error) {
1783 #define GLERROR_TO_STR(u) case u: return #u
1784 GLERROR_TO_STR(GL_NO_ERROR);
1785 GLERROR_TO_STR(GL_INVALID_ENUM);
1786 GLERROR_TO_STR(GL_INVALID_VALUE);
1787 GLERROR_TO_STR(GL_INVALID_OPERATION);
1788 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1789 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1790 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1791 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1792 #undef GLERROR_TO_STR
1794 FIXME("Unrecognied GL error 0x%08x\n", error);
1795 return "unrecognized";
1799 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1801 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1802 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1803 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1804 default: return "unrecognized";
1808 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1810 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1811 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1812 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1813 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1814 default: return "unrecognized";
1818 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
1822 #define WINED3D_TO_STR(x) case x: return #x
1823 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1824 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1825 WINED3D_TO_STR(CHANNEL_SOURCE_X);
1826 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1827 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1828 WINED3D_TO_STR(CHANNEL_SOURCE_W);
1829 WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1830 WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1831 #undef WINED3D_TO_STR
1833 FIXME("Unrecognized fixup_channel_source %#x\n", source);
1834 return "unrecognized";
1838 static const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1842 #define WINED3D_TO_STR(x) case x: return #x
1843 WINED3D_TO_STR(YUV_FIXUP_YUY2);
1844 WINED3D_TO_STR(YUV_FIXUP_UYVY);
1845 WINED3D_TO_STR(YUV_FIXUP_YV12);
1846 #undef WINED3D_TO_STR
1848 FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1849 return "unrecognized";
1853 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1855 if (is_yuv_fixup(fixup))
1857 TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1861 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1862 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1863 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1864 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1867 const char *debug_surflocation(DWORD flag) {
1871 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
1872 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
1873 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
1874 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
1875 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
1878 /*****************************************************************************
1879 * Useful functions mapping GL <-> D3D values
1881 GLenum StencilOp(DWORD op) {
1883 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1884 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1885 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1886 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1887 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1888 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1889 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1890 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1892 FIXME("Unrecognized stencil op %d\n", op);
1897 GLenum CompareFunc(DWORD func) {
1898 switch ((WINED3DCMPFUNC)func) {
1899 case WINED3DCMP_NEVER : return GL_NEVER;
1900 case WINED3DCMP_LESS : return GL_LESS;
1901 case WINED3DCMP_EQUAL : return GL_EQUAL;
1902 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1903 case WINED3DCMP_GREATER : return GL_GREATER;
1904 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1905 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1906 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1908 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1913 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1914 if (op == WINED3DTOP_DISABLE) return FALSE;
1915 if (This->stateBlock->textures[stage]) return FALSE;
1917 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1918 && op != WINED3DTOP_SELECTARG2) return TRUE;
1919 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1920 && op != WINED3DTOP_SELECTARG1) return TRUE;
1921 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1922 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1927 /* Setup this textures matrix according to the texture flags*/
1928 /* GL locking is done by the caller (state handler) */
1929 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
1930 WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
1934 glMatrixMode(GL_TEXTURE);
1935 checkGLcall("glMatrixMode(GL_TEXTURE)");
1937 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1939 checkGLcall("glLoadIdentity()");
1943 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1944 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1948 memcpy(mat, smat, 16 * sizeof(float));
1950 if (flags & WINED3DTTFF_PROJECTED) {
1951 if(!ffp_proj_control) {
1952 switch (flags & ~WINED3DTTFF_PROJECTED) {
1953 case WINED3DTTFF_COUNT2:
1954 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1955 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1957 case WINED3DTTFF_COUNT3:
1958 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1959 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1963 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1964 if(!calculatedCoords) {
1967 case WINED3DFMT_R32_FLOAT:
1968 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1969 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1970 * the input value to the transformation will be 0, so the matrix value is irrelevant
1977 case WINED3DFMT_R32G32_FLOAT:
1978 /* See above, just 3rd and 4th coord
1985 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
1986 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
1988 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1989 * into a bad place. The division elimination below will apply to make sure the
1990 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1992 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
1995 FIXME("Unexpected fixed function texture coord input\n");
1998 if(!ffp_proj_control) {
1999 switch (flags & ~WINED3DTTFF_PROJECTED) {
2000 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2001 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2002 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2003 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2004 * the 4th coord evaluates to 1.0 to eliminate that.
2006 * If the fixed function pipeline is used, the 4th value remains unused,
2007 * so there is no danger in doing this. With vertex shaders we have a
2008 * problem. Should an app hit that problem, the code here would have to
2009 * check for pixel shaders, and the shader has to undo the default gl divide.
2011 * A more serious problem occurs if the app passes 4 coordinates in, and the
2012 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2013 * or a replacement shader
2015 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2021 checkGLcall("glLoadMatrixf(mat)");
2023 #undef GLINFO_LOCATION
2025 /* This small helper function is used to convert a bitmask into the number of masked bits */
2026 unsigned int count_bits(unsigned int mask)
2029 for (count = 0; mask; ++count)
2036 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2037 * The later function requires individual color components. */
2038 BOOL getColorBits(const struct GlPixelFormatDesc *format_desc,
2039 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2041 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2042 switch(format_desc->format)
2044 case WINED3DFMT_X8R8G8B8:
2045 case WINED3DFMT_R8G8B8:
2046 case WINED3DFMT_A8R8G8B8:
2047 case WINED3DFMT_R8G8B8A8_UNORM:
2048 case WINED3DFMT_A2R10G10B10:
2049 case WINED3DFMT_X1R5G5B5:
2050 case WINED3DFMT_A1R5G5B5:
2051 case WINED3DFMT_R5G6B5:
2052 case WINED3DFMT_X4R4G4B4:
2053 case WINED3DFMT_A4R4G4B4:
2054 case WINED3DFMT_R3G3B2:
2055 case WINED3DFMT_A8P8:
2059 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
2063 *redSize = count_bits(format_desc->red_mask);
2064 *greenSize = count_bits(format_desc->green_mask);
2065 *blueSize = count_bits(format_desc->blue_mask);
2066 *alphaSize = count_bits(format_desc->alpha_mask);
2067 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2069 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
2070 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
2074 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2075 BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize)
2077 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2078 switch(format_desc->format)
2080 case WINED3DFMT_D16_LOCKABLE:
2081 case WINED3DFMT_D16_UNORM:
2082 case WINED3DFMT_D15S1:
2083 case WINED3DFMT_D24X8:
2084 case WINED3DFMT_D24X4S4:
2085 case WINED3DFMT_D24S8:
2086 case WINED3DFMT_D24FS8:
2087 case WINED3DFMT_D32:
2088 case WINED3DFMT_D32F_LOCKABLE:
2091 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
2095 *depthSize = format_desc->depth_size;
2096 *stencilSize = format_desc->stencil_size;
2098 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
2099 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
2103 /* DirectDraw stuff */
2104 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2106 case 8: return WINED3DFMT_P8;
2107 case 15: return WINED3DFMT_X1R5G5B5;
2108 case 16: return WINED3DFMT_R5G6B5;
2109 case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
2110 case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
2111 default: return WINED3DFMT_UNKNOWN;
2115 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2118 /* Now do the multiplication 'by hand'.
2119 I know that all this could be optimised, but this will be done later :-) */
2120 temp.u.s._11 = (src1->u.s._11 * src2->u.s._11) + (src1->u.s._21 * src2->u.s._12) + (src1->u.s._31 * src2->u.s._13) + (src1->u.s._41 * src2->u.s._14);
2121 temp.u.s._21 = (src1->u.s._11 * src2->u.s._21) + (src1->u.s._21 * src2->u.s._22) + (src1->u.s._31 * src2->u.s._23) + (src1->u.s._41 * src2->u.s._24);
2122 temp.u.s._31 = (src1->u.s._11 * src2->u.s._31) + (src1->u.s._21 * src2->u.s._32) + (src1->u.s._31 * src2->u.s._33) + (src1->u.s._41 * src2->u.s._34);
2123 temp.u.s._41 = (src1->u.s._11 * src2->u.s._41) + (src1->u.s._21 * src2->u.s._42) + (src1->u.s._31 * src2->u.s._43) + (src1->u.s._41 * src2->u.s._44);
2125 temp.u.s._12 = (src1->u.s._12 * src2->u.s._11) + (src1->u.s._22 * src2->u.s._12) + (src1->u.s._32 * src2->u.s._13) + (src1->u.s._42 * src2->u.s._14);
2126 temp.u.s._22 = (src1->u.s._12 * src2->u.s._21) + (src1->u.s._22 * src2->u.s._22) + (src1->u.s._32 * src2->u.s._23) + (src1->u.s._42 * src2->u.s._24);
2127 temp.u.s._32 = (src1->u.s._12 * src2->u.s._31) + (src1->u.s._22 * src2->u.s._32) + (src1->u.s._32 * src2->u.s._33) + (src1->u.s._42 * src2->u.s._34);
2128 temp.u.s._42 = (src1->u.s._12 * src2->u.s._41) + (src1->u.s._22 * src2->u.s._42) + (src1->u.s._32 * src2->u.s._43) + (src1->u.s._42 * src2->u.s._44);
2130 temp.u.s._13 = (src1->u.s._13 * src2->u.s._11) + (src1->u.s._23 * src2->u.s._12) + (src1->u.s._33 * src2->u.s._13) + (src1->u.s._43 * src2->u.s._14);
2131 temp.u.s._23 = (src1->u.s._13 * src2->u.s._21) + (src1->u.s._23 * src2->u.s._22) + (src1->u.s._33 * src2->u.s._23) + (src1->u.s._43 * src2->u.s._24);
2132 temp.u.s._33 = (src1->u.s._13 * src2->u.s._31) + (src1->u.s._23 * src2->u.s._32) + (src1->u.s._33 * src2->u.s._33) + (src1->u.s._43 * src2->u.s._34);
2133 temp.u.s._43 = (src1->u.s._13 * src2->u.s._41) + (src1->u.s._23 * src2->u.s._42) + (src1->u.s._33 * src2->u.s._43) + (src1->u.s._43 * src2->u.s._44);
2135 temp.u.s._14 = (src1->u.s._14 * src2->u.s._11) + (src1->u.s._24 * src2->u.s._12) + (src1->u.s._34 * src2->u.s._13) + (src1->u.s._44 * src2->u.s._14);
2136 temp.u.s._24 = (src1->u.s._14 * src2->u.s._21) + (src1->u.s._24 * src2->u.s._22) + (src1->u.s._34 * src2->u.s._23) + (src1->u.s._44 * src2->u.s._24);
2137 temp.u.s._34 = (src1->u.s._14 * src2->u.s._31) + (src1->u.s._24 * src2->u.s._32) + (src1->u.s._34 * src2->u.s._33) + (src1->u.s._44 * src2->u.s._34);
2138 temp.u.s._44 = (src1->u.s._14 * src2->u.s._41) + (src1->u.s._24 * src2->u.s._42) + (src1->u.s._34 * src2->u.s._43) + (src1->u.s._44 * src2->u.s._44);
2140 /* And copy the new matrix in the good storage.. */
2141 memcpy(dest, &temp, 16 * sizeof(float));
2144 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2147 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2149 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2150 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2151 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2152 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2153 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2154 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2155 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2156 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2157 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2158 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2159 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2160 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2161 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2162 default: ERR("Unexpected position mask\n");
2164 for (i = 0; i < numTextures; i++) {
2165 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2171 /***********************************************************************
2174 * Calculates the dimensions of the opengl texture used for blits.
2175 * Handled oversized opengl textures and updates the source rectangle
2179 * This: Surface to operate on
2180 * Rect: Requested rectangle
2183 * TRUE if the texture part can be loaded,
2186 *********************************************************************/
2187 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
2189 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
2190 int x1 = Rect->left, x2 = Rect->right;
2191 int y1 = Rect->top, y2 = Rect->bottom;
2192 GLint maxSize = GL_LIMITS(texture_size);
2194 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2195 Rect->left, Rect->top, Rect->right, Rect->bottom);
2197 /* The sizes might be reversed */
2198 if(Rect->left > Rect->right) {
2202 if(Rect->top > Rect->bottom) {
2207 /* No oversized texture? This is easy */
2208 if(!(This->Flags & SFLAG_OVERSIZE)) {
2209 /* Which rect from the texture do I need? */
2210 if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
2212 glTexCoord[0] = (float) Rect->left;
2213 glTexCoord[2] = (float) Rect->top;
2214 glTexCoord[1] = (float) Rect->right;
2215 glTexCoord[3] = (float) Rect->bottom;
2217 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2218 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2219 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2220 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2225 /* Check if we can succeed at all */
2226 if( (x2 - x1) > maxSize ||
2227 (y2 - y1) > maxSize ) {
2228 TRACE("Requested rectangle is too large for gl\n");
2232 /* A part of the texture has to be picked. First, check if
2233 * some texture part is loaded already, if yes try to re-use it.
2234 * If the texture is dirty, or the part can't be used,
2235 * re-position the part to load
2237 if(This->Flags & SFLAG_INTEXTURE) {
2238 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2239 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2240 /* Ok, the rectangle is ok, re-use it */
2241 TRACE("Using existing gl Texture\n");
2243 /* Rectangle is not ok, dirtify the texture to reload it */
2244 TRACE("Dirtifying texture to force reload\n");
2245 This->Flags &= ~SFLAG_INTEXTURE;
2249 /* Now if we are dirty(no else if!) */
2250 if(!(This->Flags & SFLAG_INTEXTURE)) {
2251 /* Set the new rectangle. Use the following strategy:
2252 * 1) Use as big textures as possible.
2253 * 2) Place the texture part in the way that the requested
2254 * part is in the middle of the texture(well, almost)
2255 * 3) If the texture is moved over the edges of the
2256 * surface, replace it nicely
2257 * 4) If the coord is not limiting the texture size,
2258 * use the whole size
2260 if((This->pow2Width) > maxSize) {
2261 This->glRect.left = x1 - maxSize / 2;
2262 if(This->glRect.left < 0) {
2263 This->glRect.left = 0;
2265 This->glRect.right = This->glRect.left + maxSize;
2266 if(This->glRect.right > This->currentDesc.Width) {
2267 This->glRect.right = This->currentDesc.Width;
2268 This->glRect.left = This->glRect.right - maxSize;
2271 This->glRect.left = 0;
2272 This->glRect.right = This->pow2Width;
2275 if(This->pow2Height > maxSize) {
2276 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2277 if(This->glRect.top < 0) This->glRect.top = 0;
2278 This->glRect.bottom = This->glRect.left + maxSize;
2279 if(This->glRect.bottom > This->currentDesc.Height) {
2280 This->glRect.bottom = This->currentDesc.Height;
2281 This->glRect.top = This->glRect.bottom - maxSize;
2284 This->glRect.top = 0;
2285 This->glRect.bottom = This->pow2Height;
2287 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2288 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2291 /* Re-calculate the rect to draw */
2292 Rect->left -= This->glRect.left;
2293 Rect->right -= This->glRect.left;
2294 Rect->top -= This->glRect.top;
2295 Rect->bottom -= This->glRect.top;
2297 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2298 * or the pow2Width / pow2Height of the surface.
2300 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
2301 * as regular GL_TEXTURE_2D.
2303 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2304 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2305 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2306 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2310 #undef GLINFO_LOCATION
2312 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2313 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2317 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2319 /* D3DTOP_DISABLE */ 0,
2320 /* D3DTOP_SELECTARG1 */ ARG1,
2321 /* D3DTOP_SELECTARG2 */ ARG2,
2322 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2323 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2324 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2325 /* D3DTOP_ADD */ ARG1 | ARG2,
2326 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2327 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2328 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2329 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2330 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2331 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2332 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2333 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2334 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2335 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2336 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2337 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2338 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2339 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2340 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2341 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2342 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2343 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2344 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2348 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2349 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2351 for(i = 0; i < GL_LIMITS(texture_stages); i++) {
2352 IWineD3DBaseTextureImpl *texture;
2353 settings->op[i].padding = 0;
2354 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2355 settings->op[i].cop = WINED3DTOP_DISABLE;
2356 settings->op[i].aop = WINED3DTOP_DISABLE;
2357 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2358 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2359 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2360 settings->op[i].dst = resultreg;
2361 settings->op[i].tex_type = tex_1d;
2362 settings->op[i].projected = proj_none;
2367 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2369 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2370 if(ignore_textype) {
2371 settings->op[i].tex_type = tex_1d;
2373 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2375 settings->op[i].tex_type = tex_1d;
2378 settings->op[i].tex_type = tex_2d;
2381 settings->op[i].tex_type = tex_3d;
2383 case GL_TEXTURE_CUBE_MAP_ARB:
2384 settings->op[i].tex_type = tex_cube;
2386 case GL_TEXTURE_RECTANGLE_ARB:
2387 settings->op[i].tex_type = tex_rect;
2392 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2393 settings->op[i].tex_type = tex_1d;
2396 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2397 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2399 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2400 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2401 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2403 if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2406 carg1 = WINED3DTA_CURRENT;
2407 cop = WINED3DTOP_SELECTARG1;
2410 if(cop == WINED3DTOP_DOTPRODUCT3) {
2411 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2412 * the color result to the alpha component of the destination
2419 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2420 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2421 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2424 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2426 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2428 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2430 IWineD3DSurfaceImpl *surf;
2431 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2433 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2435 if (aop == WINED3DTOP_DISABLE)
2437 aarg1 = WINED3DTA_TEXTURE;
2438 aop = WINED3DTOP_SELECTARG1;
2440 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2442 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2444 aarg2 = WINED3DTA_TEXTURE;
2445 aop = WINED3DTOP_MODULATE;
2447 else aarg1 = WINED3DTA_TEXTURE;
2449 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2451 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2453 aarg1 = WINED3DTA_TEXTURE;
2454 aop = WINED3DTOP_MODULATE;
2456 else aarg2 = WINED3DTA_TEXTURE;
2462 if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2465 aarg1 = WINED3DTA_CURRENT;
2466 aop = WINED3DTOP_SELECTARG1;
2469 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2470 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2471 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2472 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2473 settings->op[i].projected = proj_count3;
2474 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2475 settings->op[i].projected = proj_count4;
2477 settings->op[i].projected = proj_none;
2480 settings->op[i].projected = proj_none;
2483 settings->op[i].cop = cop;
2484 settings->op[i].aop = aop;
2485 settings->op[i].carg0 = carg0;
2486 settings->op[i].carg1 = carg1;
2487 settings->op[i].carg2 = carg2;
2488 settings->op[i].aarg0 = aarg0;
2489 settings->op[i].aarg1 = aarg1;
2490 settings->op[i].aarg2 = aarg2;
2492 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2493 settings->op[i].dst = tempreg;
2495 settings->op[i].dst = resultreg;
2499 /* Clear unsupported stages */
2500 for(; i < MAX_TEXTURES; i++) {
2501 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2504 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2505 settings->fog = FOG_OFF;
2506 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2507 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2508 settings->fog = FOG_LINEAR;
2510 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2511 case WINED3DFOG_NONE:
2512 case WINED3DFOG_LINEAR:
2513 settings->fog = FOG_LINEAR;
2515 case WINED3DFOG_EXP:
2516 settings->fog = FOG_EXP;
2518 case WINED3DFOG_EXP2:
2519 settings->fog = FOG_EXP2;
2524 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2525 case WINED3DFOG_LINEAR:
2526 settings->fog = FOG_LINEAR;
2528 case WINED3DFOG_EXP:
2529 settings->fog = FOG_EXP;
2531 case WINED3DFOG_EXP2:
2532 settings->fog = FOG_EXP2;
2536 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2537 settings->sRGB_write = 1;
2539 settings->sRGB_write = 0;
2541 if(device->vs_clipping || !use_vs(stateblock) || !stateblock->renderState[WINED3DRS_CLIPPING] ||
2542 !stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
2543 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2544 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2545 * if no clipplane is enabled
2547 settings->emul_clipplanes = 0;
2549 settings->emul_clipplanes = 1;
2552 #undef GLINFO_LOCATION
2554 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2555 const struct ffp_frag_settings *settings)
2557 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2558 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2561 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2563 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2564 * whereas desc points to an extended structure with implementation specific parts. */
2565 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2567 ERR("Failed to insert ffp frag shader.\n");
2571 /* Activates the texture dimension according to the bound D3D texture.
2572 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2573 * Requires the caller to activate the correct unit before
2575 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2576 /* GL locking is done by the caller (state handler) */
2577 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2579 if(stateblock->textures[stage]) {
2580 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2582 glDisable(GL_TEXTURE_3D);
2583 checkGLcall("glDisable(GL_TEXTURE_3D)");
2584 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2585 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2586 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2588 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2589 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2590 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2592 glEnable(GL_TEXTURE_2D);
2593 checkGLcall("glEnable(GL_TEXTURE_2D)");
2595 case GL_TEXTURE_RECTANGLE_ARB:
2596 glDisable(GL_TEXTURE_2D);
2597 checkGLcall("glDisable(GL_TEXTURE_2D)");
2598 glDisable(GL_TEXTURE_3D);
2599 checkGLcall("glDisable(GL_TEXTURE_3D)");
2600 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2601 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2602 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2604 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2605 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2608 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2609 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2610 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2612 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2613 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2614 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2616 glDisable(GL_TEXTURE_2D);
2617 checkGLcall("glDisable(GL_TEXTURE_2D)");
2618 glEnable(GL_TEXTURE_3D);
2619 checkGLcall("glEnable(GL_TEXTURE_3D)");
2621 case GL_TEXTURE_CUBE_MAP_ARB:
2622 glDisable(GL_TEXTURE_2D);
2623 checkGLcall("glDisable(GL_TEXTURE_2D)");
2624 glDisable(GL_TEXTURE_3D);
2625 checkGLcall("glDisable(GL_TEXTURE_3D)");
2626 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2627 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2628 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2630 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2631 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2635 glEnable(GL_TEXTURE_2D);
2636 checkGLcall("glEnable(GL_TEXTURE_2D)");
2637 glDisable(GL_TEXTURE_3D);
2638 checkGLcall("glDisable(GL_TEXTURE_3D)");
2639 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2640 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2641 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2643 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2644 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2645 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2647 /* Binding textures is done by samplers. A dummy texture will be bound */
2651 /* GL locking is done by the caller (state handler) */
2652 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2654 DWORD sampler = state - STATE_SAMPLER(0);
2655 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2657 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2658 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2659 * will take care of this business
2661 if(mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= GL_LIMITS(textures)) return;
2662 if(sampler >= stateblock->lowest_disabled_stage) return;
2663 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2665 texture_activate_dimensions(sampler, stateblock, context);
2667 #undef GLINFO_LOCATION
2669 void *wined3d_rb_alloc(size_t size)
2671 return HeapAlloc(GetProcessHeap(), 0, size);
2674 void *wined3d_rb_realloc(void *ptr, size_t size)
2676 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
2679 void wined3d_rb_free(void *ptr)
2681 HeapFree(GetProcessHeap(), 0, ptr);
2684 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
2686 const struct ffp_frag_settings *ka = key;
2687 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
2689 return memcmp(ka, kb, sizeof(*ka));
2692 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
2697 ffp_frag_program_key_compare,
2700 UINT wined3d_log2i(UINT32 x)
2702 static const UINT l[] =
2704 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2705 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2706 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2707 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2708 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2709 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2710 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2711 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2712 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2713 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2714 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2715 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2716 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2717 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2718 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2719 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2723 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];