2 * Utility functions for the WineD3D Library
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2008 Henri Verbeet
9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
10 * Copyright 2009 Henri Verbeet for CodeWeavers
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wined3d_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
32 struct StaticPixelFormatDesc
35 DWORD alphaMask, redMask, greenMask, blueMask;
37 short depthSize, stencilSize;
41 /*****************************************************************************
44 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
45 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
46 * high masks do not fit into the 32 bit values needed for ddraw. It is only
47 * used for ddraw mostly, and to figure out if the format has alpha at all, so
48 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
49 * formats are not usable in 2D rendering because ddraw doesn't support them.
51 static const struct StaticPixelFormatDesc formats[] =
53 /* WINED3DFORMAT alphamask redmask greenmask bluemask bpp depth stencil isFourcc */
54 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, FALSE},
56 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
57 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
58 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
59 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
60 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
61 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
62 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
63 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
64 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
65 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
66 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
68 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
69 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
70 {WINED3DFMT_R32G32B32_FLOAT, 0x0, 0x0, 0x0, 0x0, 12, 0, 0, FALSE},
71 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0, FALSE},
73 {WINED3DFMT_R8G8_SNORM_Cx, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
75 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
76 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
77 {WINED3DFMT_R16G16_SINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
78 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
79 {WINED3DFMT_R16G16B16A16_SINT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
80 /* Palettized formats */
81 {WINED3DFMT_P8_UINT_A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
82 {WINED3DFMT_P8_UINT, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
83 /* Standard ARGB formats. */
84 {WINED3DFMT_B8G8R8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0, FALSE},
85 {WINED3DFMT_B8G8R8A8_UNORM, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0, FALSE},
86 {WINED3DFMT_B8G8R8X8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0, FALSE},
87 {WINED3DFMT_B5G6R5_UNORM, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0, FALSE},
88 {WINED3DFMT_B5G5R5X1_UNORM, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0, FALSE},
89 {WINED3DFMT_B5G5R5A1_UNORM, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0, FALSE},
90 {WINED3DFMT_B4G4R4A4_UNORM, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0, FALSE},
91 {WINED3DFMT_B2G3R3_UNORM, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0, FALSE},
92 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
93 {WINED3DFMT_B2G3R3A8_UNORM, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0, FALSE},
94 {WINED3DFMT_B4G4R4X4_UNORM, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0, FALSE},
95 {WINED3DFMT_R10G10B10A2_UNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
96 {WINED3DFMT_R10G10B10A2_UINT, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
97 {WINED3DFMT_R10G10B10A2_SNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
98 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
99 {WINED3DFMT_R8G8B8A8_UINT, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
100 {WINED3DFMT_R8G8B8X8_UNORM, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
101 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0, FALSE},
102 {WINED3DFMT_B10G10R10A2_UNORM, 0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0, FALSE},
103 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0, FALSE},
105 {WINED3DFMT_L8_UNORM, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
106 {WINED3DFMT_L8A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
107 {WINED3DFMT_L4A4_UNORM, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
108 {WINED3DFMT_L16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
109 /* Bump mapping stuff */
110 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
111 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
112 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
113 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
114 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
115 {WINED3DFMT_R10G11B11_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
116 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM,0xb0000000,0x0, 0x0, 0x0, 4, 0, 0, FALSE},
117 /* Depth stencil formats */
118 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
119 {WINED3DFMT_D32_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 32, 0, FALSE},
120 {WINED3DFMT_S1_UINT_D15_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 15, 1, FALSE},
121 {WINED3DFMT_S8_UINT_D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 8, FALSE},
122 {WINED3DFMT_X8D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 0, FALSE},
123 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 4, FALSE},
124 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
125 {WINED3DFMT_D32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 32, 0, FALSE},
126 {WINED3DFMT_S8_UINT_D24_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8, FALSE},
127 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, FALSE},
128 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
129 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
130 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
131 /* Vendor-specific formats */
132 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
133 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
134 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
137 struct wined3d_format_compression_info
139 WINED3DFORMAT format;
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_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
173 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
174 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
175 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
176 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
177 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
178 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
179 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
180 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
181 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
182 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
183 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
184 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
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_UINT, GL_RGBA, GL_RGBA, 0,
296 GL_RGBA, GL_UNSIGNED_BYTE,
297 WINED3DFMT_FLAG_GETDC,
298 ARB_FRAGMENT_PROGRAM},
299 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
300 GL_COLOR_INDEX, GL_UNSIGNED_BYTE,
301 WINED3DFMT_FLAG_GETDC,
302 EXT_PALETTED_TEXTURE},
303 /* Standard ARGB formats */
304 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
305 GL_BGR, GL_UNSIGNED_BYTE,
306 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET |
307 WINED3DFMT_FLAG_GETDC,
308 WINED3D_GL_EXT_NONE},
309 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
310 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
311 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET |
312 WINED3DFMT_FLAG_GETDC,
313 WINED3D_GL_EXT_NONE},
314 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
315 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
316 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET |
317 WINED3DFMT_FLAG_GETDC,
318 WINED3D_GL_EXT_NONE},
319 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
320 GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
321 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET |
322 WINED3DFMT_FLAG_GETDC,
323 WINED3D_GL_EXT_NONE},
324 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
325 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
326 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING |
327 WINED3DFMT_FLAG_GETDC,
328 WINED3D_GL_EXT_NONE},
329 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
330 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
331 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING |
332 WINED3DFMT_FLAG_GETDC,
333 WINED3D_GL_EXT_NONE},
334 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
335 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
336 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING |
337 WINED3DFMT_FLAG_GETDC,
338 WINED3D_GL_EXT_NONE},
339 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
340 GL_RGB, GL_UNSIGNED_BYTE_3_3_2,
341 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
342 WINED3D_GL_EXT_NONE},
343 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
344 GL_ALPHA, GL_UNSIGNED_BYTE,
345 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
346 WINED3D_GL_EXT_NONE},
347 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
348 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
349 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_GETDC,
350 WINED3D_GL_EXT_NONE},
351 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
352 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV,
353 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
354 WINED3D_GL_EXT_NONE},
355 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
356 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
357 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_GETDC,
358 WINED3D_GL_EXT_NONE},
359 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
360 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
361 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_GETDC,
362 WINED3D_GL_EXT_NONE},
363 {WINED3DFMT_R16G16_UNORM, GL_RGB16_EXT, GL_RGB16_EXT, GL_RGBA16_EXT,
364 GL_RGB, GL_UNSIGNED_SHORT,
365 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
366 WINED3D_GL_EXT_NONE},
367 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
368 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV,
369 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
370 WINED3D_GL_EXT_NONE},
371 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16_EXT, GL_RGBA16_EXT, 0,
372 GL_RGBA, GL_UNSIGNED_SHORT,
373 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
374 WINED3D_GL_EXT_NONE},
376 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
377 GL_LUMINANCE, GL_UNSIGNED_BYTE,
378 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
379 WINED3D_GL_EXT_NONE},
380 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
381 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
382 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
383 WINED3D_GL_EXT_NONE},
384 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
385 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
387 WINED3D_GL_EXT_NONE},
388 /* Bump mapping stuff */
389 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
390 GL_BGR, GL_UNSIGNED_BYTE,
391 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
392 WINED3D_GL_EXT_NONE},
393 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
395 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
397 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
398 GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
399 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
400 WINED3D_GL_EXT_NONE},
401 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
402 GL_DSDT_MAG_NV, GL_BYTE,
403 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
405 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
406 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
407 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
408 WINED3D_GL_EXT_NONE},
409 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
410 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV,
411 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
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_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
435 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
436 WINED3DFMT_FLAG_DEPTH,
438 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
439 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
440 WINED3DFMT_FLAG_DEPTH,
442 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
443 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
444 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
445 EXT_PACKED_DEPTH_STENCIL},
446 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
447 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
448 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
449 ARB_FRAMEBUFFER_OBJECT},
450 {WINED3DFMT_S8_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
451 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
452 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
454 {WINED3DFMT_S8_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
455 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
456 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
457 EXT_PACKED_DEPTH_STENCIL},
458 {WINED3DFMT_S8_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
459 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
460 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
461 ARB_FRAMEBUFFER_OBJECT},
462 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
463 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
464 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
466 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
467 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
468 WINED3DFMT_FLAG_DEPTH,
470 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
471 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
472 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
473 EXT_PACKED_DEPTH_STENCIL},
474 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
475 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
476 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
477 ARB_FRAMEBUFFER_OBJECT},
478 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
479 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
480 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
482 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16_EXT, GL_LUMINANCE16_EXT, 0,
483 GL_LUMINANCE, GL_UNSIGNED_SHORT,
484 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
485 WINED3D_GL_EXT_NONE},
486 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
487 GL_DEPTH_COMPONENT, GL_FLOAT,
488 WINED3DFMT_FLAG_DEPTH,
489 ARB_DEPTH_BUFFER_FLOAT},
490 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
491 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
492 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
493 ARB_DEPTH_BUFFER_FLOAT},
494 /* Vendor-specific formats */
495 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
496 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
498 ATI_TEXTURE_COMPRESSION_3DC},
499 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, 0,
500 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
502 EXT_TEXTURE_COMPRESSION_RGTC},
505 static inline int getFmtIdx(WINED3DFORMAT fmt) {
506 /* First check if the format is at the position of its value.
507 * This will catch the argb formats before the loop is entered
509 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
513 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
514 if(formats[i].format == fmt) {
522 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
524 UINT format_count = sizeof(formats) / sizeof(*formats);
527 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->gl_formats));
528 if (!gl_info->gl_formats)
530 ERR("Failed to allocate memory.\n");
534 for (i = 0; i < format_count; ++i)
536 struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
537 desc->format = formats[i].format;
538 desc->red_mask = formats[i].redMask;
539 desc->green_mask = formats[i].greenMask;
540 desc->blue_mask = formats[i].blueMask;
541 desc->alpha_mask = formats[i].alphaMask;
542 desc->byte_count = formats[i].bpp;
543 desc->depth_size = formats[i].depthSize;
544 desc->stencil_size = formats[i].stencilSize;
545 if (formats[i].isFourcc) desc->Flags |= WINED3DFMT_FLAG_FOURCC;
551 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
555 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
557 struct GlPixelFormatDesc *format_desc;
558 int fmt_idx = getFmtIdx(format_compression_info[i].format);
562 ERR("Format %s (%#x) not found.\n",
563 debug_d3dformat(format_compression_info[i].format), format_compression_info[i].format);
567 format_desc = &gl_info->gl_formats[fmt_idx];
568 format_desc->block_width = format_compression_info[i].block_width;
569 format_desc->block_height = format_compression_info[i].block_height;
570 format_desc->block_byte_count = format_compression_info[i].block_byte_count;
571 format_desc->Flags |= WINED3DFMT_FLAG_COMPRESSED;
577 #define GLINFO_LOCATION (*gl_info)
579 /* Context activation is done by the caller. */
580 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPixelFormatDesc *format_desc)
582 /* Check if the default internal format is supported as a frame buffer
583 * target, otherwise fall back to the render target internal.
585 * Try to stick to the standard format if possible, this limits precision differences. */
594 glGenTextures(1, &tex);
595 glBindTexture(GL_TEXTURE_2D, tex);
597 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glInternal, 16, 16, 0,
598 format_desc->glFormat, format_desc->glType, NULL);
599 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
600 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
602 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
604 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
605 checkGLcall("Framebuffer format check");
607 if (status == GL_FRAMEBUFFER_COMPLETE)
609 TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(format_desc->format));
610 format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
611 format_desc->rtInternal = format_desc->glInternal;
615 if (!format_desc->rtInternal)
617 if (format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)
619 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
620 " and no fallback specified.\n", debug_d3dformat(format_desc->format));
621 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
625 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format_desc->format));
627 format_desc->rtInternal = format_desc->glInternal;
631 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
632 debug_d3dformat(format_desc->format));
636 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
638 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->rtInternal, 16, 16, 0,
639 format_desc->glFormat, format_desc->glType, NULL);
640 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
641 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
643 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
645 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
646 checkGLcall("Framebuffer format check");
648 if (status == GL_FRAMEBUFFER_COMPLETE)
650 TRACE("Format %s rtInternal format is supported as FBO color attachment\n",
651 debug_d3dformat(format_desc->format));
655 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
656 debug_d3dformat(format_desc->format));
657 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
662 if (status == GL_FRAMEBUFFER_COMPLETE && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
666 if (GL_SUPPORT(ARB_FRAMEBUFFER_OBJECT)
667 || GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
669 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
670 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
671 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
672 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
673 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
674 checkGLcall("RB attachment");
678 glClear(GL_COLOR_BUFFER_BIT);
679 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
682 TRACE("Format doesn't support post-pixelshader blending.\n");
683 format_desc->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
686 if (GL_SUPPORT(ARB_FRAMEBUFFER_OBJECT)
687 || GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
689 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
690 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
691 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
692 checkGLcall("RB cleanup");
696 glDeleteTextures(1, &tex);
701 /* Context activation is done by the caller. */
702 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
707 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
711 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
712 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
717 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
719 struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
721 if (!desc->glInternal) continue;
723 if (desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
725 TRACE("Skipping format %s because it's a depth/stencil format.\n",
726 debug_d3dformat(desc->format));
730 if (desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
732 TRACE("Skipping format %s because it's a compressed format.\n",
733 debug_d3dformat(desc->format));
737 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
739 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc->format));
740 check_fbo_compat(gl_info, desc);
744 desc->rtInternal = desc->glInternal;
748 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
752 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
758 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
762 for (i = 0; i < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); ++i)
764 int fmt_idx = getFmtIdx(gl_formats_template[i].fmt);
765 struct GlPixelFormatDesc *desc;
769 ERR("Format %s (%#x) not found.\n",
770 debug_d3dformat(gl_formats_template[i].fmt), gl_formats_template[i].fmt);
774 if (!GL_SUPPORT(gl_formats_template[i].extension)) continue;
776 desc = &gl_info->gl_formats[fmt_idx];
777 desc->glInternal = gl_formats_template[i].glInternal;
778 desc->glGammaInternal = gl_formats_template[i].glGammaInternal;
779 desc->rtInternal = gl_formats_template[i].rtInternal;
780 desc->glFormat = gl_formats_template[i].glFormat;
781 desc->glType = gl_formats_template[i].glType;
782 desc->color_fixup = COLOR_FIXUP_IDENTITY;
783 desc->Flags |= gl_formats_template[i].Flags;
784 desc->heightscale = 1.0f;
790 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
792 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
794 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
796 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
798 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
802 /* A context is provided by the caller */
803 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
805 GLuint tex, fbo, buffer;
806 const DWORD data[] = {0x00000000, 0xffffffff};
807 DWORD readback[16 * 1];
810 /* Render a filtered texture and see what happens. This is intended to detect the lack of
811 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
812 * falling back to software. If this changes in the future this code will get fooled and
813 * apps might hit the software path due to incorrectly advertised caps.
815 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
816 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
817 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
823 glGenTextures(1, &buffer);
824 glBindTexture(GL_TEXTURE_2D, buffer);
825 memset(readback, 0x7e, sizeof(readback));
826 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
827 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
828 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
829 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
830 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
831 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
833 glGenTextures(1, &tex);
834 glBindTexture(GL_TEXTURE_2D, tex);
835 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
836 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
837 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
838 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
839 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
840 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
841 glEnable(GL_TEXTURE_2D);
843 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
844 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
845 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
846 glDrawBuffer(GL_COLOR_ATTACHMENT0);
848 glViewport(0, 0, 16, 1);
849 glDisable(GL_LIGHTING);
850 glMatrixMode(GL_MODELVIEW);
852 glMatrixMode(GL_PROJECTION);
855 glClearColor(0, 1, 0, 0);
856 glClear(GL_COLOR_BUFFER_BIT);
858 glBegin(GL_TRIANGLE_STRIP);
859 glTexCoord2f(0.0, 0.0);
860 glVertex2f(-1.0f, -1.0f);
861 glTexCoord2f(1.0, 0.0);
862 glVertex2f(1.0f, -1.0f);
863 glTexCoord2f(0.0, 1.0);
864 glVertex2f(-1.0f, 1.0f);
865 glTexCoord2f(1.0, 1.0);
866 glVertex2f(1.0f, 1.0f);
869 glBindTexture(GL_TEXTURE_2D, buffer);
870 memset(readback, 0x7f, sizeof(readback));
871 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
872 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
873 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
875 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
876 readback[6], readback[9]);
881 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
882 readback[6], readback[9]);
886 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
887 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
888 glDeleteTextures(1, &tex);
889 glDeleteTextures(1, &buffer);
893 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
900 static void init_format_filter_info(struct wined3d_gl_info *gl_info)
902 unsigned int fmt_idx, i;
903 WINED3DFORMAT fmts16[] = {
904 WINED3DFMT_R16_FLOAT,
905 WINED3DFMT_R16G16_FLOAT,
906 WINED3DFMT_R16G16B16A16_FLOAT,
909 struct GlPixelFormatDesc *desc;
911 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
913 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
914 if(gl_info->gl_vendor == VENDOR_NVIDIA && GL_SUPPORT(ARB_TEXTURE_FLOAT))
916 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
919 else if(GL_LIMITS(glsl_varyings > 44))
921 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
926 TRACE("Assuming no float16 blending\n");
932 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
934 fmt_idx = getFmtIdx(fmts16[i]);
935 gl_info->gl_formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
941 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
943 fmt_idx = getFmtIdx(fmts16[i]);
944 desc = &gl_info->gl_formats[fmt_idx];
945 if(!desc->glInternal) continue; /* Not supported by GL */
947 filtered = check_filter(gl_info, gl_info->gl_formats[fmt_idx].glInternal);
950 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
951 desc->Flags |= WINED3DFMT_FLAG_FILTERING;
955 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
960 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
964 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
965 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
966 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
968 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
969 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
970 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
972 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
973 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
974 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
976 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
977 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
978 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
980 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
981 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
982 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
984 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
985 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
986 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
987 * the only driver that implements it(fglrx) has a buggy implementation.
989 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
990 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
991 * conversion for this format.
993 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
995 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
996 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
997 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
998 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
999 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1000 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1004 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1005 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1006 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1007 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1008 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1009 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1012 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
1014 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1017 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1018 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1019 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1020 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1021 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1022 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1023 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1024 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1025 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1029 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1030 * are converted at surface loading time, but they do not need any modification in
1031 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1032 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1036 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC))
1038 idx = getFmtIdx(WINED3DFMT_ATI2N);
1039 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1040 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1042 else if (GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC))
1044 idx = getFmtIdx(WINED3DFMT_ATI2N);
1045 gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
1046 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1049 if (!GL_SUPPORT(APPLE_YCBCR_422))
1051 idx = getFmtIdx(WINED3DFMT_YUY2);
1052 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
1054 idx = getFmtIdx(WINED3DFMT_UYVY);
1055 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
1058 idx = getFmtIdx(WINED3DFMT_YV12);
1059 gl_info->gl_formats[idx].heightscale = 1.5f;
1060 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
1062 if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
1064 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1065 gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
1068 if (GL_SUPPORT(ARB_HALF_FLOAT_VERTEX))
1070 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1071 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1072 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1073 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1075 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1076 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1080 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1084 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1086 struct GlPixelFormatDesc *format_desc;
1087 int fmt_idx = getFmtIdx(format_vertex_info[i].format);
1091 ERR("Format %s (%#x) not found.\n",
1092 debug_d3dformat(format_vertex_info[i].format), format_vertex_info[i].format);
1096 format_desc = &gl_info->gl_formats[fmt_idx];
1097 format_desc->emit_idx = format_vertex_info[i].emit_idx;
1098 format_desc->component_count = format_vertex_info[i].component_count;
1099 format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1100 format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1101 format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
1102 format_desc->component_size = format_vertex_info[i].component_size;
1108 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1110 if (!init_format_base_info(gl_info)) return FALSE;
1112 if (!init_format_compression_info(gl_info))
1114 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1121 /* Context activation is done by the caller. */
1122 BOOL initPixelFormats(struct wined3d_gl_info *gl_info)
1124 if (!init_format_base_info(gl_info)) return FALSE;
1126 if (!init_format_compression_info(gl_info)) goto fail;
1127 if (!init_format_texture_info(gl_info)) goto fail;
1128 if (!init_format_vertex_info(gl_info)) goto fail;
1130 apply_format_fixups(gl_info);
1131 init_format_fbo_compat_info(gl_info);
1132 init_format_filter_info(gl_info);
1137 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1141 #undef GLINFO_LOCATION
1143 #define GLINFO_LOCATION This->adapter->gl_info
1145 const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info)
1147 int idx = getFmtIdx(fmt);
1150 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
1151 /* Get the caller a valid pointer */
1152 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1155 return &gl_info->gl_formats[idx];
1158 /*****************************************************************************
1159 * Trace formatting of useful values
1161 const char* debug_d3dformat(WINED3DFORMAT fmt) {
1163 #define FMT_TO_STR(fmt) case fmt: return #fmt
1164 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1165 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1166 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1167 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1168 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1169 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1170 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1171 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1172 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1173 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1174 FMT_TO_STR(WINED3DFMT_P8_UINT);
1175 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1176 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1177 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1178 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1179 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1180 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1181 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1182 FMT_TO_STR(WINED3DFMT_UYVY);
1183 FMT_TO_STR(WINED3DFMT_YUY2);
1184 FMT_TO_STR(WINED3DFMT_YV12);
1185 FMT_TO_STR(WINED3DFMT_DXT1);
1186 FMT_TO_STR(WINED3DFMT_DXT2);
1187 FMT_TO_STR(WINED3DFMT_DXT3);
1188 FMT_TO_STR(WINED3DFMT_DXT4);
1189 FMT_TO_STR(WINED3DFMT_DXT5);
1190 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1191 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1192 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1193 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1194 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1195 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1196 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_UNORM);
1197 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1198 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1199 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1200 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1201 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1202 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1203 FMT_TO_STR(WINED3DFMT_ATI2N);
1204 FMT_TO_STR(WINED3DFMT_NVHU);
1205 FMT_TO_STR(WINED3DFMT_NVHS);
1206 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1207 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1208 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1209 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1210 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1211 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1212 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1213 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1214 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1215 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1216 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1217 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1218 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1219 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1220 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1221 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1222 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1223 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1224 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1225 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1226 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1227 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1228 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1229 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1230 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1231 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1232 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1233 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1234 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1235 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1236 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1237 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1238 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1239 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1240 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1241 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1242 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1243 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1244 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1245 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1246 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1247 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1248 FMT_TO_STR(WINED3DFMT_R32_UINT);
1249 FMT_TO_STR(WINED3DFMT_R32_SINT);
1250 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1251 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1252 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1253 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1254 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1255 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1256 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1257 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1258 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1259 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1260 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1261 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1262 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1263 FMT_TO_STR(WINED3DFMT_R16_UINT);
1264 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1265 FMT_TO_STR(WINED3DFMT_R16_SINT);
1266 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1267 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1268 FMT_TO_STR(WINED3DFMT_R8_UINT);
1269 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1270 FMT_TO_STR(WINED3DFMT_R8_SINT);
1271 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1272 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1273 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1274 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1275 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1276 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1277 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1278 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1279 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1280 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1281 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1282 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1283 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1284 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1285 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1286 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1287 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1288 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1289 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1290 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1291 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1292 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1293 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1294 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1299 fourcc[0] = (char)(fmt);
1300 fourcc[1] = (char)(fmt >> 8);
1301 fourcc[2] = (char)(fmt >> 16);
1302 fourcc[3] = (char)(fmt >> 24);
1304 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
1305 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
1307 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
1309 return "unrecognized";
1313 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
1315 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1316 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1317 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1318 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1319 #undef DEVTYPE_TO_STR
1321 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1322 return "unrecognized";
1326 const char *debug_d3dusage(DWORD usage)
1331 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1332 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1333 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1334 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1335 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1336 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1337 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1338 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1339 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1340 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1341 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1342 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1343 #undef WINED3DUSAGE_TO_STR
1344 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1346 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1349 const char *debug_d3dusagequery(DWORD usagequery)
1354 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1355 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1356 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1357 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1358 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1359 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1360 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1361 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1362 #undef WINED3DUSAGEQUERY_TO_STR
1363 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1365 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1368 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1370 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1371 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1372 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1373 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1374 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1375 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1376 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1377 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1378 #undef WINED3DDECLMETHOD_TO_STR
1380 FIXME("Unrecognized %u declaration method!\n", method);
1381 return "unrecognized";
1385 const char* debug_d3ddeclusage(BYTE usage) {
1387 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1388 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1389 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1390 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1391 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1392 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1393 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1394 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1395 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1396 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1397 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1398 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1399 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1400 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1401 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1402 #undef WINED3DDECLUSAGE_TO_STR
1404 FIXME("Unrecognized %u declaration usage!\n", usage);
1405 return "unrecognized";
1409 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1411 #define RES_TO_STR(res) case res: return #res
1412 RES_TO_STR(WINED3DRTYPE_SURFACE);
1413 RES_TO_STR(WINED3DRTYPE_VOLUME);
1414 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1415 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1416 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1417 RES_TO_STR(WINED3DRTYPE_BUFFER);
1420 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1421 return "unrecognized";
1425 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1426 switch (PrimitiveType) {
1427 #define PRIM_TO_STR(prim) case prim: return #prim
1428 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1429 PRIM_TO_STR(WINED3DPT_POINTLIST);
1430 PRIM_TO_STR(WINED3DPT_LINELIST);
1431 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1432 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1433 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1434 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1435 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1436 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1437 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1438 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1441 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1442 return "unrecognized";
1446 const char* debug_d3drenderstate(DWORD state) {
1448 #define D3DSTATE_TO_STR(u) case u: return #u
1449 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
1450 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1451 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
1452 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1453 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1454 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1455 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1456 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1457 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1458 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1459 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1460 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1461 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1462 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1463 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1464 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1465 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
1466 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
1467 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1468 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1469 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
1470 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1471 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1472 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1473 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1474 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1475 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1476 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1477 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1478 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1479 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1480 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1481 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1482 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1483 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1484 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1485 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1486 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1487 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1488 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1489 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1490 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
1491 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
1492 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
1493 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1494 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1495 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1496 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1497 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1498 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1499 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1500 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1501 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1502 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1503 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1504 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1505 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1506 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1507 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1508 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
1509 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
1510 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
1511 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
1512 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
1513 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
1514 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
1515 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
1516 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
1517 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
1518 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
1519 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
1520 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
1521 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
1522 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
1523 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
1524 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
1525 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
1526 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
1527 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
1528 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
1529 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
1530 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
1531 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
1532 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
1533 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
1534 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
1535 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
1536 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
1537 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
1538 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
1539 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
1540 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1541 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1542 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1543 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1544 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1545 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1546 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1547 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1548 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1549 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1550 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1551 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1552 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1553 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1554 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1555 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1556 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1557 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1558 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1559 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1560 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1561 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1562 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1563 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1564 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1565 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1566 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1567 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1568 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1569 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1570 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1571 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1572 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1573 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1574 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1575 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1576 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1577 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1578 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1579 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1580 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1581 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1582 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1583 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1584 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1585 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1586 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1587 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1588 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1589 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1590 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1591 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1592 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1593 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1594 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1595 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1596 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1597 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1598 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1599 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1600 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1601 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1602 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1603 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1604 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1605 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1606 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1607 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1608 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1609 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1610 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1611 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1612 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1613 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1614 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1615 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1616 #undef D3DSTATE_TO_STR
1618 FIXME("Unrecognized %u render state!\n", state);
1619 return "unrecognized";
1623 const char* debug_d3dsamplerstate(DWORD state) {
1625 #define D3DSTATE_TO_STR(u) case u: return #u
1626 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1627 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1628 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1629 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1630 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1631 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1632 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1633 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1634 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1635 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1636 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1637 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1638 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1639 #undef D3DSTATE_TO_STR
1641 FIXME("Unrecognized %u sampler state!\n", state);
1642 return "unrecognized";
1646 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1647 switch (filter_type) {
1648 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1649 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1650 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1651 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1652 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1653 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1654 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1655 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1656 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1657 #undef D3DTEXTUREFILTERTYPE_TO_STR
1659 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1660 return "unrecognized";
1664 const char* debug_d3dtexturestate(DWORD state) {
1666 #define D3DSTATE_TO_STR(u) case u: return #u
1667 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1668 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1669 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1670 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1671 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1672 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1673 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1674 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1675 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1676 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1677 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1678 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1679 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1680 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1681 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1682 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1683 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1684 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1685 #undef D3DSTATE_TO_STR
1687 FIXME("Unrecognized %u texture state!\n", state);
1688 return "unrecognized";
1692 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1694 #define D3DTOP_TO_STR(u) case u: return #u
1695 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1696 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1697 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1698 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1699 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1700 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1701 D3DTOP_TO_STR(WINED3DTOP_ADD);
1702 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1703 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1704 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1705 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1706 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1707 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1708 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1709 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1710 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1711 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1712 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1713 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1714 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1715 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1716 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1717 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1718 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1719 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1720 D3DTOP_TO_STR(WINED3DTOP_LERP);
1721 #undef D3DTOP_TO_STR
1723 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1724 return "unrecognized";
1728 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1730 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1731 TSTYPE_TO_STR(WINED3DTS_VIEW);
1732 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1733 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1734 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1735 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1736 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1737 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1738 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1739 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1740 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1741 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1742 #undef TSTYPE_TO_STR
1744 if (tstype > 256 && tstype < 512) {
1745 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1746 return ("WINED3DTS_WORLDMATRIX > 0");
1748 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1749 return "unrecognized";
1753 const char* debug_d3dpool(WINED3DPOOL Pool) {
1755 #define POOL_TO_STR(p) case p: return #p
1756 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1757 POOL_TO_STR(WINED3DPOOL_MANAGED);
1758 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1759 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1762 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1763 return "unrecognized";
1767 const char *debug_fbostatus(GLenum status) {
1769 #define FBOSTATUS_TO_STR(u) case u: return #u
1770 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
1771 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
1772 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
1773 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1774 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1775 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
1776 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
1777 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
1778 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
1779 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
1780 #undef FBOSTATUS_TO_STR
1782 FIXME("Unrecognied FBO status 0x%08x\n", status);
1783 return "unrecognized";
1787 const char *debug_glerror(GLenum error) {
1789 #define GLERROR_TO_STR(u) case u: return #u
1790 GLERROR_TO_STR(GL_NO_ERROR);
1791 GLERROR_TO_STR(GL_INVALID_ENUM);
1792 GLERROR_TO_STR(GL_INVALID_VALUE);
1793 GLERROR_TO_STR(GL_INVALID_OPERATION);
1794 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1795 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1796 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1797 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
1798 #undef GLERROR_TO_STR
1800 FIXME("Unrecognied GL error 0x%08x\n", error);
1801 return "unrecognized";
1805 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1807 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1808 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1809 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1810 default: return "unrecognized";
1814 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1816 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1817 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1818 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1819 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1820 default: return "unrecognized";
1824 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
1828 #define WINED3D_TO_STR(x) case x: return #x
1829 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1830 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1831 WINED3D_TO_STR(CHANNEL_SOURCE_X);
1832 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1833 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1834 WINED3D_TO_STR(CHANNEL_SOURCE_W);
1835 WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1836 WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1837 #undef WINED3D_TO_STR
1839 FIXME("Unrecognized fixup_channel_source %#x\n", source);
1840 return "unrecognized";
1844 static const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1848 #define WINED3D_TO_STR(x) case x: return #x
1849 WINED3D_TO_STR(YUV_FIXUP_YUY2);
1850 WINED3D_TO_STR(YUV_FIXUP_UYVY);
1851 WINED3D_TO_STR(YUV_FIXUP_YV12);
1852 #undef WINED3D_TO_STR
1854 FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1855 return "unrecognized";
1859 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1861 if (is_yuv_fixup(fixup))
1863 TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1867 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1868 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1869 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1870 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1873 const char *debug_surflocation(DWORD flag) {
1877 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
1878 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
1879 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
1880 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
1881 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
1884 /*****************************************************************************
1885 * Useful functions mapping GL <-> D3D values
1887 GLenum StencilOp(DWORD op) {
1889 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1890 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1891 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1892 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1893 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1894 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1895 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1896 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1898 FIXME("Unrecognized stencil op %d\n", op);
1903 GLenum CompareFunc(DWORD func) {
1904 switch ((WINED3DCMPFUNC)func) {
1905 case WINED3DCMP_NEVER : return GL_NEVER;
1906 case WINED3DCMP_LESS : return GL_LESS;
1907 case WINED3DCMP_EQUAL : return GL_EQUAL;
1908 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1909 case WINED3DCMP_GREATER : return GL_GREATER;
1910 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1911 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1912 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1914 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1919 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1920 if (op == WINED3DTOP_DISABLE) return FALSE;
1921 if (This->stateBlock->textures[stage]) return FALSE;
1923 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1924 && op != WINED3DTOP_SELECTARG2) return TRUE;
1925 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1926 && op != WINED3DTOP_SELECTARG1) return TRUE;
1927 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1928 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1933 /* Setup this textures matrix according to the texture flags*/
1934 /* GL locking is done by the caller (state handler) */
1935 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
1936 WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
1940 glMatrixMode(GL_TEXTURE);
1941 checkGLcall("glMatrixMode(GL_TEXTURE)");
1943 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1945 checkGLcall("glLoadIdentity()");
1949 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1950 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1954 memcpy(mat, smat, 16 * sizeof(float));
1956 if (flags & WINED3DTTFF_PROJECTED) {
1957 if(!ffp_proj_control) {
1958 switch (flags & ~WINED3DTTFF_PROJECTED) {
1959 case WINED3DTTFF_COUNT2:
1960 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1961 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1963 case WINED3DTTFF_COUNT3:
1964 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1965 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1969 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1970 if(!calculatedCoords) {
1973 case WINED3DFMT_R32_FLOAT:
1974 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1975 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1976 * the input value to the transformation will be 0, so the matrix value is irrelevant
1983 case WINED3DFMT_R32G32_FLOAT:
1984 /* See above, just 3rd and 4th coord
1991 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
1992 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
1994 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1995 * into a bad place. The division elimination below will apply to make sure the
1996 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1998 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2001 FIXME("Unexpected fixed function texture coord input\n");
2004 if(!ffp_proj_control) {
2005 switch (flags & ~WINED3DTTFF_PROJECTED) {
2006 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2007 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2008 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2009 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2010 * the 4th coord evaluates to 1.0 to eliminate that.
2012 * If the fixed function pipeline is used, the 4th value remains unused,
2013 * so there is no danger in doing this. With vertex shaders we have a
2014 * problem. Should an app hit that problem, the code here would have to
2015 * check for pixel shaders, and the shader has to undo the default gl divide.
2017 * A more serious problem occurs if the app passes 4 coordinates in, and the
2018 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2019 * or a replacement shader
2021 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2027 checkGLcall("glLoadMatrixf(mat)");
2029 #undef GLINFO_LOCATION
2031 /* This small helper function is used to convert a bitmask into the number of masked bits */
2032 unsigned int count_bits(unsigned int mask)
2035 for (count = 0; mask; ++count)
2042 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2043 * The later function requires individual color components. */
2044 BOOL getColorBits(const struct GlPixelFormatDesc *format_desc,
2045 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2047 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2048 switch(format_desc->format)
2050 case WINED3DFMT_B8G8R8X8_UNORM:
2051 case WINED3DFMT_B8G8R8_UNORM:
2052 case WINED3DFMT_B8G8R8A8_UNORM:
2053 case WINED3DFMT_R8G8B8A8_UNORM:
2054 case WINED3DFMT_B10G10R10A2_UNORM:
2055 case WINED3DFMT_B5G5R5X1_UNORM:
2056 case WINED3DFMT_B5G5R5A1_UNORM:
2057 case WINED3DFMT_B5G6R5_UNORM:
2058 case WINED3DFMT_B4G4R4X4_UNORM:
2059 case WINED3DFMT_B4G4R4A4_UNORM:
2060 case WINED3DFMT_B2G3R3_UNORM:
2061 case WINED3DFMT_P8_UINT_A8_UNORM:
2062 case WINED3DFMT_P8_UINT:
2065 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
2069 *redSize = count_bits(format_desc->red_mask);
2070 *greenSize = count_bits(format_desc->green_mask);
2071 *blueSize = count_bits(format_desc->blue_mask);
2072 *alphaSize = count_bits(format_desc->alpha_mask);
2073 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2075 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
2076 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
2080 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2081 BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize)
2083 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2084 switch(format_desc->format)
2086 case WINED3DFMT_D16_LOCKABLE:
2087 case WINED3DFMT_D16_UNORM:
2088 case WINED3DFMT_S1_UINT_D15_UNORM:
2089 case WINED3DFMT_X8D24_UNORM:
2090 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2091 case WINED3DFMT_S8_UINT_D24_UNORM:
2092 case WINED3DFMT_S8_UINT_D24_FLOAT:
2093 case WINED3DFMT_D32_UNORM:
2094 case WINED3DFMT_D32_FLOAT:
2097 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
2101 *depthSize = format_desc->depth_size;
2102 *stencilSize = format_desc->stencil_size;
2104 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
2105 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
2109 /* DirectDraw stuff */
2110 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2112 case 8: return WINED3DFMT_P8_UINT;
2113 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2114 case 16: return WINED3DFMT_B5G6R5_UNORM;
2115 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2116 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2117 default: return WINED3DFMT_UNKNOWN;
2121 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2124 /* Now do the multiplication 'by hand'.
2125 I know that all this could be optimised, but this will be done later :-) */
2126 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);
2127 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);
2128 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);
2129 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);
2131 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);
2132 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);
2133 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);
2134 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);
2136 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);
2137 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);
2138 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);
2139 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);
2141 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);
2142 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);
2143 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);
2144 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);
2146 /* And copy the new matrix in the good storage.. */
2147 memcpy(dest, &temp, 16 * sizeof(float));
2150 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2153 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2155 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2156 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2157 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2158 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2159 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2160 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2161 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2162 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2163 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2164 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2165 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2166 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2167 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2168 default: ERR("Unexpected position mask\n");
2170 for (i = 0; i < numTextures; i++) {
2171 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2177 /***********************************************************************
2180 * Calculates the dimensions of the opengl texture used for blits.
2181 * Handled oversized opengl textures and updates the source rectangle
2185 * This: Surface to operate on
2186 * Rect: Requested rectangle
2189 * TRUE if the texture part can be loaded,
2192 *********************************************************************/
2193 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
2195 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
2196 int x1 = Rect->left, x2 = Rect->right;
2197 int y1 = Rect->top, y2 = Rect->bottom;
2198 GLint maxSize = GL_LIMITS(texture_size);
2200 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2201 Rect->left, Rect->top, Rect->right, Rect->bottom);
2203 /* The sizes might be reversed */
2204 if(Rect->left > Rect->right) {
2208 if(Rect->top > Rect->bottom) {
2213 /* No oversized texture? This is easy */
2214 if(!(This->Flags & SFLAG_OVERSIZE)) {
2215 /* Which rect from the texture do I need? */
2216 if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
2218 glTexCoord[0] = (float) Rect->left;
2219 glTexCoord[2] = (float) Rect->top;
2220 glTexCoord[1] = (float) Rect->right;
2221 glTexCoord[3] = (float) Rect->bottom;
2223 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2224 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2225 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2226 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2231 /* Check if we can succeed at all */
2232 if( (x2 - x1) > maxSize ||
2233 (y2 - y1) > maxSize ) {
2234 TRACE("Requested rectangle is too large for gl\n");
2238 /* A part of the texture has to be picked. First, check if
2239 * some texture part is loaded already, if yes try to re-use it.
2240 * If the texture is dirty, or the part can't be used,
2241 * re-position the part to load
2243 if(This->Flags & SFLAG_INTEXTURE) {
2244 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2245 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2246 /* Ok, the rectangle is ok, re-use it */
2247 TRACE("Using existing gl Texture\n");
2249 /* Rectangle is not ok, dirtify the texture to reload it */
2250 TRACE("Dirtifying texture to force reload\n");
2251 This->Flags &= ~SFLAG_INTEXTURE;
2255 /* Now if we are dirty(no else if!) */
2256 if(!(This->Flags & SFLAG_INTEXTURE)) {
2257 /* Set the new rectangle. Use the following strategy:
2258 * 1) Use as big textures as possible.
2259 * 2) Place the texture part in the way that the requested
2260 * part is in the middle of the texture(well, almost)
2261 * 3) If the texture is moved over the edges of the
2262 * surface, replace it nicely
2263 * 4) If the coord is not limiting the texture size,
2264 * use the whole size
2266 if((This->pow2Width) > maxSize) {
2267 This->glRect.left = x1 - maxSize / 2;
2268 if(This->glRect.left < 0) {
2269 This->glRect.left = 0;
2271 This->glRect.right = This->glRect.left + maxSize;
2272 if(This->glRect.right > This->currentDesc.Width) {
2273 This->glRect.right = This->currentDesc.Width;
2274 This->glRect.left = This->glRect.right - maxSize;
2277 This->glRect.left = 0;
2278 This->glRect.right = This->pow2Width;
2281 if(This->pow2Height > maxSize) {
2282 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2283 if(This->glRect.top < 0) This->glRect.top = 0;
2284 This->glRect.bottom = This->glRect.left + maxSize;
2285 if(This->glRect.bottom > This->currentDesc.Height) {
2286 This->glRect.bottom = This->currentDesc.Height;
2287 This->glRect.top = This->glRect.bottom - maxSize;
2290 This->glRect.top = 0;
2291 This->glRect.bottom = This->pow2Height;
2293 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2294 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2297 /* Re-calculate the rect to draw */
2298 Rect->left -= This->glRect.left;
2299 Rect->right -= This->glRect.left;
2300 Rect->top -= This->glRect.top;
2301 Rect->bottom -= This->glRect.top;
2303 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2304 * or the pow2Width / pow2Height of the surface.
2306 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
2307 * as regular GL_TEXTURE_2D.
2309 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2310 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2311 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2312 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2316 #undef GLINFO_LOCATION
2318 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2319 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2323 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2325 /* D3DTOP_DISABLE */ 0,
2326 /* D3DTOP_SELECTARG1 */ ARG1,
2327 /* D3DTOP_SELECTARG2 */ ARG2,
2328 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2329 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2330 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2331 /* D3DTOP_ADD */ ARG1 | ARG2,
2332 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2333 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2334 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2335 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2336 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2337 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2338 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2339 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2340 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2341 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2342 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2343 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2344 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2345 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2346 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2347 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2348 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2349 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2350 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2354 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2355 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2357 for(i = 0; i < GL_LIMITS(texture_stages); i++) {
2358 IWineD3DBaseTextureImpl *texture;
2359 settings->op[i].padding = 0;
2360 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2361 settings->op[i].cop = WINED3DTOP_DISABLE;
2362 settings->op[i].aop = WINED3DTOP_DISABLE;
2363 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2364 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2365 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2366 settings->op[i].dst = resultreg;
2367 settings->op[i].tex_type = tex_1d;
2368 settings->op[i].projected = proj_none;
2373 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2375 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2376 if(ignore_textype) {
2377 settings->op[i].tex_type = tex_1d;
2379 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2381 settings->op[i].tex_type = tex_1d;
2384 settings->op[i].tex_type = tex_2d;
2387 settings->op[i].tex_type = tex_3d;
2389 case GL_TEXTURE_CUBE_MAP_ARB:
2390 settings->op[i].tex_type = tex_cube;
2392 case GL_TEXTURE_RECTANGLE_ARB:
2393 settings->op[i].tex_type = tex_rect;
2398 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2399 settings->op[i].tex_type = tex_1d;
2402 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2403 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2405 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2406 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2407 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2409 if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2412 carg1 = WINED3DTA_CURRENT;
2413 cop = WINED3DTOP_SELECTARG1;
2416 if(cop == WINED3DTOP_DOTPRODUCT3) {
2417 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2418 * the color result to the alpha component of the destination
2425 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2426 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2427 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2430 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2432 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2434 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2436 IWineD3DSurfaceImpl *surf;
2437 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2439 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2441 if (aop == WINED3DTOP_DISABLE)
2443 aarg1 = WINED3DTA_TEXTURE;
2444 aop = WINED3DTOP_SELECTARG1;
2446 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2448 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2450 aarg2 = WINED3DTA_TEXTURE;
2451 aop = WINED3DTOP_MODULATE;
2453 else aarg1 = WINED3DTA_TEXTURE;
2455 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2457 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2459 aarg1 = WINED3DTA_TEXTURE;
2460 aop = WINED3DTOP_MODULATE;
2462 else aarg2 = WINED3DTA_TEXTURE;
2468 if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2471 aarg1 = WINED3DTA_CURRENT;
2472 aop = WINED3DTOP_SELECTARG1;
2475 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2476 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2477 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2478 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2479 settings->op[i].projected = proj_count3;
2480 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2481 settings->op[i].projected = proj_count4;
2483 settings->op[i].projected = proj_none;
2486 settings->op[i].projected = proj_none;
2489 settings->op[i].cop = cop;
2490 settings->op[i].aop = aop;
2491 settings->op[i].carg0 = carg0;
2492 settings->op[i].carg1 = carg1;
2493 settings->op[i].carg2 = carg2;
2494 settings->op[i].aarg0 = aarg0;
2495 settings->op[i].aarg1 = aarg1;
2496 settings->op[i].aarg2 = aarg2;
2498 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2499 settings->op[i].dst = tempreg;
2501 settings->op[i].dst = resultreg;
2505 /* Clear unsupported stages */
2506 for(; i < MAX_TEXTURES; i++) {
2507 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2510 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2511 settings->fog = FOG_OFF;
2512 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2513 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2514 settings->fog = FOG_LINEAR;
2516 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2517 case WINED3DFOG_NONE:
2518 case WINED3DFOG_LINEAR:
2519 settings->fog = FOG_LINEAR;
2521 case WINED3DFOG_EXP:
2522 settings->fog = FOG_EXP;
2524 case WINED3DFOG_EXP2:
2525 settings->fog = FOG_EXP2;
2530 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2531 case WINED3DFOG_LINEAR:
2532 settings->fog = FOG_LINEAR;
2534 case WINED3DFOG_EXP:
2535 settings->fog = FOG_EXP;
2537 case WINED3DFOG_EXP2:
2538 settings->fog = FOG_EXP2;
2542 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2543 settings->sRGB_write = 1;
2545 settings->sRGB_write = 0;
2547 if(device->vs_clipping || !use_vs(stateblock) || !stateblock->renderState[WINED3DRS_CLIPPING] ||
2548 !stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
2549 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2550 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2551 * if no clipplane is enabled
2553 settings->emul_clipplanes = 0;
2555 settings->emul_clipplanes = 1;
2558 #undef GLINFO_LOCATION
2560 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2561 const struct ffp_frag_settings *settings)
2563 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2564 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2567 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2569 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2570 * whereas desc points to an extended structure with implementation specific parts. */
2571 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2573 ERR("Failed to insert ffp frag shader.\n");
2577 /* Activates the texture dimension according to the bound D3D texture.
2578 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2579 * Requires the caller to activate the correct unit before
2581 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2582 /* GL locking is done by the caller (state handler) */
2583 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2585 if(stateblock->textures[stage]) {
2586 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2588 glDisable(GL_TEXTURE_3D);
2589 checkGLcall("glDisable(GL_TEXTURE_3D)");
2590 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2591 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2592 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2594 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2595 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2596 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2598 glEnable(GL_TEXTURE_2D);
2599 checkGLcall("glEnable(GL_TEXTURE_2D)");
2601 case GL_TEXTURE_RECTANGLE_ARB:
2602 glDisable(GL_TEXTURE_2D);
2603 checkGLcall("glDisable(GL_TEXTURE_2D)");
2604 glDisable(GL_TEXTURE_3D);
2605 checkGLcall("glDisable(GL_TEXTURE_3D)");
2606 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2607 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2608 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2610 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2611 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2614 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2615 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2616 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2618 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2619 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2620 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2622 glDisable(GL_TEXTURE_2D);
2623 checkGLcall("glDisable(GL_TEXTURE_2D)");
2624 glEnable(GL_TEXTURE_3D);
2625 checkGLcall("glEnable(GL_TEXTURE_3D)");
2627 case GL_TEXTURE_CUBE_MAP_ARB:
2628 glDisable(GL_TEXTURE_2D);
2629 checkGLcall("glDisable(GL_TEXTURE_2D)");
2630 glDisable(GL_TEXTURE_3D);
2631 checkGLcall("glDisable(GL_TEXTURE_3D)");
2632 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2633 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2634 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2636 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2637 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2641 glEnable(GL_TEXTURE_2D);
2642 checkGLcall("glEnable(GL_TEXTURE_2D)");
2643 glDisable(GL_TEXTURE_3D);
2644 checkGLcall("glDisable(GL_TEXTURE_3D)");
2645 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2646 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2647 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2649 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2650 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2651 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2653 /* Binding textures is done by samplers. A dummy texture will be bound */
2657 /* GL locking is done by the caller (state handler) */
2658 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2660 DWORD sampler = state - STATE_SAMPLER(0);
2661 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2663 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2664 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2665 * will take care of this business
2667 if(mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= GL_LIMITS(textures)) return;
2668 if(sampler >= stateblock->lowest_disabled_stage) return;
2669 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2671 texture_activate_dimensions(sampler, stateblock, context);
2673 #undef GLINFO_LOCATION
2675 void *wined3d_rb_alloc(size_t size)
2677 return HeapAlloc(GetProcessHeap(), 0, size);
2680 void *wined3d_rb_realloc(void *ptr, size_t size)
2682 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
2685 void wined3d_rb_free(void *ptr)
2687 HeapFree(GetProcessHeap(), 0, ptr);
2690 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
2692 const struct ffp_frag_settings *ka = key;
2693 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
2695 return memcmp(ka, kb, sizeof(*ka));
2698 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
2703 ffp_frag_program_key_compare,
2706 UINT wined3d_log2i(UINT32 x)
2708 static const UINT l[] =
2710 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2711 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2712 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2713 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2714 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2715 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2716 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2717 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
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,
2720 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2721 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2722 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2723 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2724 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2725 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2729 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];