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_info->max_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);
1115 gl_info->gl_formats = NULL;
1122 /* Context activation is done by the caller. */
1123 BOOL initPixelFormats(struct wined3d_gl_info *gl_info)
1125 if (!init_format_base_info(gl_info)) return FALSE;
1127 if (!init_format_compression_info(gl_info)) goto fail;
1128 if (!init_format_texture_info(gl_info)) goto fail;
1129 if (!init_format_vertex_info(gl_info)) goto fail;
1131 apply_format_fixups(gl_info);
1132 init_format_fbo_compat_info(gl_info);
1133 init_format_filter_info(gl_info);
1138 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1139 gl_info->gl_formats = NULL;
1143 const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info)
1145 int idx = getFmtIdx(fmt);
1148 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
1149 /* Get the caller a valid pointer */
1150 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1153 return &gl_info->gl_formats[idx];
1156 /*****************************************************************************
1157 * Trace formatting of useful values
1159 const char* debug_d3dformat(WINED3DFORMAT fmt) {
1161 #define FMT_TO_STR(fmt) case fmt: return #fmt
1162 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1163 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1164 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1165 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1166 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1167 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1168 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1169 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1170 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1171 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1172 FMT_TO_STR(WINED3DFMT_P8_UINT);
1173 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1174 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1175 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1176 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1177 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1178 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1179 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1180 FMT_TO_STR(WINED3DFMT_UYVY);
1181 FMT_TO_STR(WINED3DFMT_YUY2);
1182 FMT_TO_STR(WINED3DFMT_YV12);
1183 FMT_TO_STR(WINED3DFMT_DXT1);
1184 FMT_TO_STR(WINED3DFMT_DXT2);
1185 FMT_TO_STR(WINED3DFMT_DXT3);
1186 FMT_TO_STR(WINED3DFMT_DXT4);
1187 FMT_TO_STR(WINED3DFMT_DXT5);
1188 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1189 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1190 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1191 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1192 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1193 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1194 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_UNORM);
1195 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1196 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1197 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1198 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1199 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1200 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1201 FMT_TO_STR(WINED3DFMT_ATI2N);
1202 FMT_TO_STR(WINED3DFMT_NVHU);
1203 FMT_TO_STR(WINED3DFMT_NVHS);
1204 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1205 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1206 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1207 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1208 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1209 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1210 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1211 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1212 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1213 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1214 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1215 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1216 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1217 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1218 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1219 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1220 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1221 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1222 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1223 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1224 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1225 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1226 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1227 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1228 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1229 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1230 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1231 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1232 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1233 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1234 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1235 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1236 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1237 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1238 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1239 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1240 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1241 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1242 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1243 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1244 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1245 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1246 FMT_TO_STR(WINED3DFMT_R32_UINT);
1247 FMT_TO_STR(WINED3DFMT_R32_SINT);
1248 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1249 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1250 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1251 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1252 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1253 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1254 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1255 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1256 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1257 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1258 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1259 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1260 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1261 FMT_TO_STR(WINED3DFMT_R16_UINT);
1262 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1263 FMT_TO_STR(WINED3DFMT_R16_SINT);
1264 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1265 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1266 FMT_TO_STR(WINED3DFMT_R8_UINT);
1267 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1268 FMT_TO_STR(WINED3DFMT_R8_SINT);
1269 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1270 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1271 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1272 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1273 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1274 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1275 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1276 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1277 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1278 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1279 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1280 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1281 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1282 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1283 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1284 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1285 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1286 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1287 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1288 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1289 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1290 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1291 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1292 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1297 fourcc[0] = (char)(fmt);
1298 fourcc[1] = (char)(fmt >> 8);
1299 fourcc[2] = (char)(fmt >> 16);
1300 fourcc[3] = (char)(fmt >> 24);
1302 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
1303 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
1305 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
1307 return "unrecognized";
1311 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
1313 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1314 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1315 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1316 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1317 #undef DEVTYPE_TO_STR
1319 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1320 return "unrecognized";
1324 const char *debug_d3dusage(DWORD usage)
1329 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1330 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1331 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1332 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1333 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1334 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1335 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1336 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1337 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1338 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1339 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1340 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1341 #undef WINED3DUSAGE_TO_STR
1342 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1344 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1347 const char *debug_d3dusagequery(DWORD usagequery)
1352 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1353 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1354 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1355 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1356 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1357 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1358 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1359 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1360 #undef WINED3DUSAGEQUERY_TO_STR
1361 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1363 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1366 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1368 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1369 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1370 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1371 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1372 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1373 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1374 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1375 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1376 #undef WINED3DDECLMETHOD_TO_STR
1378 FIXME("Unrecognized %u declaration method!\n", method);
1379 return "unrecognized";
1383 const char* debug_d3ddeclusage(BYTE usage) {
1385 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1386 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1387 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1388 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1389 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1390 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1391 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1392 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1393 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1394 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1395 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1396 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1397 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1398 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1399 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1400 #undef WINED3DDECLUSAGE_TO_STR
1402 FIXME("Unrecognized %u declaration usage!\n", usage);
1403 return "unrecognized";
1407 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1409 #define RES_TO_STR(res) case res: return #res
1410 RES_TO_STR(WINED3DRTYPE_SURFACE);
1411 RES_TO_STR(WINED3DRTYPE_VOLUME);
1412 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1413 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1414 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1415 RES_TO_STR(WINED3DRTYPE_BUFFER);
1418 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1419 return "unrecognized";
1423 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1424 switch (PrimitiveType) {
1425 #define PRIM_TO_STR(prim) case prim: return #prim
1426 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1427 PRIM_TO_STR(WINED3DPT_POINTLIST);
1428 PRIM_TO_STR(WINED3DPT_LINELIST);
1429 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1430 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1431 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1432 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1433 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1434 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1435 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1436 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1439 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1440 return "unrecognized";
1444 const char* debug_d3drenderstate(DWORD state) {
1446 #define D3DSTATE_TO_STR(u) case u: return #u
1447 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
1448 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1449 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
1450 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1451 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1452 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1453 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1454 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1455 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1456 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1457 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1458 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1459 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1460 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1461 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1462 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1463 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
1464 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
1465 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1466 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1467 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
1468 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1469 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1470 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1471 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1472 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1473 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1474 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1475 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1476 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1477 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1478 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1479 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1480 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1481 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1482 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1483 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1484 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1485 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1486 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1487 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1488 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
1489 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
1490 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
1491 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1492 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1493 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1494 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1495 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1496 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1497 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1498 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1499 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1500 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1501 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1502 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1503 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1504 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1505 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1506 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
1507 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
1508 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
1509 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
1510 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
1511 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
1512 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
1513 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
1514 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
1515 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
1516 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
1517 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
1518 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
1519 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
1520 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
1521 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
1522 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
1523 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
1524 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
1525 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
1526 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
1527 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
1528 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
1529 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
1530 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
1531 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
1532 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
1533 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
1534 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
1535 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
1536 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
1537 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
1538 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1539 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1540 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1541 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1542 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1543 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1544 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1545 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1546 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1547 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1548 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1549 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1550 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1551 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1552 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1553 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1554 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1555 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1556 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1557 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1558 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1559 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1560 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1561 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1562 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1563 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1564 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1565 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1566 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1567 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1568 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1569 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1570 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1571 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1572 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1573 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1574 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1575 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1576 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1577 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1578 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1579 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1580 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1581 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1582 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1583 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1584 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1585 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1586 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1587 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1588 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1589 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1590 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1591 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1592 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1593 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1594 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1595 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1596 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1597 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1598 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1599 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1600 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1601 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1602 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1603 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1604 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1605 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1606 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1607 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1608 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1609 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1610 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1611 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1612 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1613 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1614 #undef D3DSTATE_TO_STR
1616 FIXME("Unrecognized %u render state!\n", state);
1617 return "unrecognized";
1621 const char* debug_d3dsamplerstate(DWORD state) {
1623 #define D3DSTATE_TO_STR(u) case u: return #u
1624 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1625 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1626 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1627 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1628 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1629 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1630 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1631 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1632 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1633 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1634 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1635 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1636 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1637 #undef D3DSTATE_TO_STR
1639 FIXME("Unrecognized %u sampler state!\n", state);
1640 return "unrecognized";
1644 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1645 switch (filter_type) {
1646 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1647 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1648 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1649 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1650 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1651 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1652 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1653 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1654 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1655 #undef D3DTEXTUREFILTERTYPE_TO_STR
1657 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1658 return "unrecognized";
1662 const char* debug_d3dtexturestate(DWORD state) {
1664 #define D3DSTATE_TO_STR(u) case u: return #u
1665 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1666 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1667 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1668 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1669 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1670 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1671 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1672 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1673 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1674 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1675 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1676 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1677 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1678 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1679 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1680 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1681 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1682 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1683 #undef D3DSTATE_TO_STR
1685 FIXME("Unrecognized %u texture state!\n", state);
1686 return "unrecognized";
1690 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1692 #define D3DTOP_TO_STR(u) case u: return #u
1693 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1694 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1695 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1696 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1697 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1698 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1699 D3DTOP_TO_STR(WINED3DTOP_ADD);
1700 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1701 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1702 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1703 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1704 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1705 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1706 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1707 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1708 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1709 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1710 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1711 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1712 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1713 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1714 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1715 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1716 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1717 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1718 D3DTOP_TO_STR(WINED3DTOP_LERP);
1719 #undef D3DTOP_TO_STR
1721 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1722 return "unrecognized";
1726 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1728 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1729 TSTYPE_TO_STR(WINED3DTS_VIEW);
1730 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1731 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1732 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1733 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1734 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1735 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1736 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1737 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1738 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1739 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1740 #undef TSTYPE_TO_STR
1742 if (tstype > 256 && tstype < 512) {
1743 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1744 return ("WINED3DTS_WORLDMATRIX > 0");
1746 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1747 return "unrecognized";
1751 const char* debug_d3dpool(WINED3DPOOL Pool) {
1753 #define POOL_TO_STR(p) case p: return #p
1754 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1755 POOL_TO_STR(WINED3DPOOL_MANAGED);
1756 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1757 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1760 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1761 return "unrecognized";
1765 const char *debug_fbostatus(GLenum status) {
1767 #define FBOSTATUS_TO_STR(u) case u: return #u
1768 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
1769 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
1770 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
1771 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1772 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1773 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
1774 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
1775 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
1776 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
1777 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
1778 #undef FBOSTATUS_TO_STR
1780 FIXME("Unrecognied FBO status 0x%08x\n", status);
1781 return "unrecognized";
1785 const char *debug_glerror(GLenum error) {
1787 #define GLERROR_TO_STR(u) case u: return #u
1788 GLERROR_TO_STR(GL_NO_ERROR);
1789 GLERROR_TO_STR(GL_INVALID_ENUM);
1790 GLERROR_TO_STR(GL_INVALID_VALUE);
1791 GLERROR_TO_STR(GL_INVALID_OPERATION);
1792 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1793 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1794 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1795 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
1796 #undef GLERROR_TO_STR
1798 FIXME("Unrecognied GL error 0x%08x\n", error);
1799 return "unrecognized";
1803 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1805 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1806 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1807 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1808 default: return "unrecognized";
1812 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1814 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1815 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1816 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1817 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1818 default: return "unrecognized";
1822 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
1826 #define WINED3D_TO_STR(x) case x: return #x
1827 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1828 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1829 WINED3D_TO_STR(CHANNEL_SOURCE_X);
1830 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1831 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1832 WINED3D_TO_STR(CHANNEL_SOURCE_W);
1833 WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1834 WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1835 #undef WINED3D_TO_STR
1837 FIXME("Unrecognized fixup_channel_source %#x\n", source);
1838 return "unrecognized";
1842 static const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1846 #define WINED3D_TO_STR(x) case x: return #x
1847 WINED3D_TO_STR(YUV_FIXUP_YUY2);
1848 WINED3D_TO_STR(YUV_FIXUP_UYVY);
1849 WINED3D_TO_STR(YUV_FIXUP_YV12);
1850 #undef WINED3D_TO_STR
1852 FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1853 return "unrecognized";
1857 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1859 if (is_yuv_fixup(fixup))
1861 TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1865 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1866 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1867 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1868 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1871 const char *debug_surflocation(DWORD flag) {
1875 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
1876 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
1877 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
1878 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
1879 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
1882 /*****************************************************************************
1883 * Useful functions mapping GL <-> D3D values
1885 GLenum StencilOp(DWORD op) {
1887 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1888 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1889 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1890 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1891 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1892 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1893 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1894 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1896 FIXME("Unrecognized stencil op %d\n", op);
1901 GLenum CompareFunc(DWORD func) {
1902 switch ((WINED3DCMPFUNC)func) {
1903 case WINED3DCMP_NEVER : return GL_NEVER;
1904 case WINED3DCMP_LESS : return GL_LESS;
1905 case WINED3DCMP_EQUAL : return GL_EQUAL;
1906 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1907 case WINED3DCMP_GREATER : return GL_GREATER;
1908 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1909 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1910 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1912 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1917 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1918 if (op == WINED3DTOP_DISABLE) return FALSE;
1919 if (This->stateBlock->textures[stage]) return FALSE;
1921 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1922 && op != WINED3DTOP_SELECTARG2) return TRUE;
1923 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1924 && op != WINED3DTOP_SELECTARG1) return TRUE;
1925 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1926 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1931 /* Setup this textures matrix according to the texture flags*/
1932 /* GL locking is done by the caller (state handler) */
1933 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
1934 WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
1938 glMatrixMode(GL_TEXTURE);
1939 checkGLcall("glMatrixMode(GL_TEXTURE)");
1941 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1943 checkGLcall("glLoadIdentity()");
1947 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1948 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1952 memcpy(mat, smat, 16 * sizeof(float));
1954 if (flags & WINED3DTTFF_PROJECTED) {
1955 if(!ffp_proj_control) {
1956 switch (flags & ~WINED3DTTFF_PROJECTED) {
1957 case WINED3DTTFF_COUNT2:
1958 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1959 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1961 case WINED3DTTFF_COUNT3:
1962 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1963 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1967 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1968 if(!calculatedCoords) {
1971 case WINED3DFMT_R32_FLOAT:
1972 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1973 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1974 * the input value to the transformation will be 0, so the matrix value is irrelevant
1981 case WINED3DFMT_R32G32_FLOAT:
1982 /* See above, just 3rd and 4th coord
1989 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
1990 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
1992 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1993 * into a bad place. The division elimination below will apply to make sure the
1994 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1996 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
1999 FIXME("Unexpected fixed function texture coord input\n");
2002 if(!ffp_proj_control) {
2003 switch (flags & ~WINED3DTTFF_PROJECTED) {
2004 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2005 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2006 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2007 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2008 * the 4th coord evaluates to 1.0 to eliminate that.
2010 * If the fixed function pipeline is used, the 4th value remains unused,
2011 * so there is no danger in doing this. With vertex shaders we have a
2012 * problem. Should an app hit that problem, the code here would have to
2013 * check for pixel shaders, and the shader has to undo the default gl divide.
2015 * A more serious problem occurs if the app passes 4 coordinates in, and the
2016 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2017 * or a replacement shader
2019 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2025 checkGLcall("glLoadMatrixf(mat)");
2028 /* This small helper function is used to convert a bitmask into the number of masked bits */
2029 unsigned int count_bits(unsigned int mask)
2032 for (count = 0; mask; ++count)
2039 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2040 * The later function requires individual color components. */
2041 BOOL getColorBits(const struct GlPixelFormatDesc *format_desc,
2042 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2044 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2045 switch(format_desc->format)
2047 case WINED3DFMT_B8G8R8X8_UNORM:
2048 case WINED3DFMT_B8G8R8_UNORM:
2049 case WINED3DFMT_B8G8R8A8_UNORM:
2050 case WINED3DFMT_R8G8B8A8_UNORM:
2051 case WINED3DFMT_B10G10R10A2_UNORM:
2052 case WINED3DFMT_B5G5R5X1_UNORM:
2053 case WINED3DFMT_B5G5R5A1_UNORM:
2054 case WINED3DFMT_B5G6R5_UNORM:
2055 case WINED3DFMT_B4G4R4X4_UNORM:
2056 case WINED3DFMT_B4G4R4A4_UNORM:
2057 case WINED3DFMT_B2G3R3_UNORM:
2058 case WINED3DFMT_P8_UINT_A8_UNORM:
2059 case WINED3DFMT_P8_UINT:
2062 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
2066 *redSize = count_bits(format_desc->red_mask);
2067 *greenSize = count_bits(format_desc->green_mask);
2068 *blueSize = count_bits(format_desc->blue_mask);
2069 *alphaSize = count_bits(format_desc->alpha_mask);
2070 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2072 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
2073 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
2077 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2078 BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize)
2080 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2081 switch(format_desc->format)
2083 case WINED3DFMT_D16_LOCKABLE:
2084 case WINED3DFMT_D16_UNORM:
2085 case WINED3DFMT_S1_UINT_D15_UNORM:
2086 case WINED3DFMT_X8D24_UNORM:
2087 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2088 case WINED3DFMT_S8_UINT_D24_UNORM:
2089 case WINED3DFMT_S8_UINT_D24_FLOAT:
2090 case WINED3DFMT_D32_UNORM:
2091 case WINED3DFMT_D32_FLOAT:
2094 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
2098 *depthSize = format_desc->depth_size;
2099 *stencilSize = format_desc->stencil_size;
2101 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
2102 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
2106 /* DirectDraw stuff */
2107 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2109 case 8: return WINED3DFMT_P8_UINT;
2110 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2111 case 16: return WINED3DFMT_B5G6R5_UNORM;
2112 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2113 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2114 default: return WINED3DFMT_UNKNOWN;
2118 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2121 /* Now do the multiplication 'by hand'.
2122 I know that all this could be optimised, but this will be done later :-) */
2123 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);
2124 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);
2125 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);
2126 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);
2128 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);
2129 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);
2130 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);
2131 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);
2133 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);
2134 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);
2135 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);
2136 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);
2138 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);
2139 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);
2140 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);
2141 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);
2143 /* And copy the new matrix in the good storage.. */
2144 memcpy(dest, &temp, 16 * sizeof(float));
2147 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2150 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2152 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2153 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2154 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2155 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2156 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2157 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2158 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2159 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2160 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2161 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2162 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2163 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2164 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2165 default: ERR("Unexpected position mask\n");
2167 for (i = 0; i < numTextures; i++) {
2168 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2174 /***********************************************************************
2177 * Calculates the dimensions of the opengl texture used for blits.
2178 * Handled oversized opengl textures and updates the source rectangle
2182 * This: Surface to operate on
2183 * Rect: Requested rectangle
2186 * TRUE if the texture part can be loaded,
2189 *********************************************************************/
2190 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4])
2192 const struct wined3d_gl_info *gl_info = &This->resource.wineD3DDevice->adapter->gl_info;
2193 int x1 = Rect->left, x2 = Rect->right;
2194 int y1 = Rect->top, y2 = Rect->bottom;
2195 GLint maxSize = gl_info->max_texture_size;
2197 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2198 Rect->left, Rect->top, Rect->right, Rect->bottom);
2200 /* The sizes might be reversed */
2201 if(Rect->left > Rect->right) {
2205 if(Rect->top > Rect->bottom) {
2210 /* No oversized texture? This is easy */
2211 if(!(This->Flags & SFLAG_OVERSIZE)) {
2212 /* Which rect from the texture do I need? */
2213 if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
2215 glTexCoord[0] = (float) Rect->left;
2216 glTexCoord[2] = (float) Rect->top;
2217 glTexCoord[1] = (float) Rect->right;
2218 glTexCoord[3] = (float) Rect->bottom;
2220 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2221 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2222 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2223 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2228 /* Check if we can succeed at all */
2229 if( (x2 - x1) > maxSize ||
2230 (y2 - y1) > maxSize ) {
2231 TRACE("Requested rectangle is too large for gl\n");
2235 /* A part of the texture has to be picked. First, check if
2236 * some texture part is loaded already, if yes try to re-use it.
2237 * If the texture is dirty, or the part can't be used,
2238 * re-position the part to load
2240 if(This->Flags & SFLAG_INTEXTURE) {
2241 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2242 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2243 /* Ok, the rectangle is ok, re-use it */
2244 TRACE("Using existing gl Texture\n");
2246 /* Rectangle is not ok, dirtify the texture to reload it */
2247 TRACE("Dirtifying texture to force reload\n");
2248 This->Flags &= ~SFLAG_INTEXTURE;
2252 /* Now if we are dirty(no else if!) */
2253 if(!(This->Flags & SFLAG_INTEXTURE)) {
2254 /* Set the new rectangle. Use the following strategy:
2255 * 1) Use as big textures as possible.
2256 * 2) Place the texture part in the way that the requested
2257 * part is in the middle of the texture(well, almost)
2258 * 3) If the texture is moved over the edges of the
2259 * surface, replace it nicely
2260 * 4) If the coord is not limiting the texture size,
2261 * use the whole size
2263 if((This->pow2Width) > maxSize) {
2264 This->glRect.left = x1 - maxSize / 2;
2265 if(This->glRect.left < 0) {
2266 This->glRect.left = 0;
2268 This->glRect.right = This->glRect.left + maxSize;
2269 if(This->glRect.right > This->currentDesc.Width) {
2270 This->glRect.right = This->currentDesc.Width;
2271 This->glRect.left = This->glRect.right - maxSize;
2274 This->glRect.left = 0;
2275 This->glRect.right = This->pow2Width;
2278 if(This->pow2Height > maxSize) {
2279 This->glRect.top = x1 - gl_info->max_texture_size / 2;
2280 if(This->glRect.top < 0) This->glRect.top = 0;
2281 This->glRect.bottom = This->glRect.left + maxSize;
2282 if(This->glRect.bottom > This->currentDesc.Height) {
2283 This->glRect.bottom = This->currentDesc.Height;
2284 This->glRect.top = This->glRect.bottom - maxSize;
2287 This->glRect.top = 0;
2288 This->glRect.bottom = This->pow2Height;
2290 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2291 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2294 /* Re-calculate the rect to draw */
2295 Rect->left -= This->glRect.left;
2296 Rect->right -= This->glRect.left;
2297 Rect->top -= This->glRect.top;
2298 Rect->bottom -= This->glRect.top;
2300 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2301 * or the pow2Width / pow2Height of the surface.
2303 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
2304 * as regular GL_TEXTURE_2D.
2306 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2307 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2308 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2309 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2314 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2318 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2320 /* D3DTOP_DISABLE */ 0,
2321 /* D3DTOP_SELECTARG1 */ ARG1,
2322 /* D3DTOP_SELECTARG2 */ ARG2,
2323 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2324 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2325 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2326 /* D3DTOP_ADD */ ARG1 | ARG2,
2327 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2328 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2329 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2330 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2331 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2332 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2333 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2334 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2335 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2336 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2337 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2338 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2339 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2340 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2341 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2342 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2343 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2344 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2345 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2349 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2350 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2351 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2353 for (i = 0; i < gl_info->max_texture_stages; ++i)
2355 IWineD3DBaseTextureImpl *texture;
2356 settings->op[i].padding = 0;
2357 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2358 settings->op[i].cop = WINED3DTOP_DISABLE;
2359 settings->op[i].aop = WINED3DTOP_DISABLE;
2360 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2361 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2362 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2363 settings->op[i].dst = resultreg;
2364 settings->op[i].tex_type = tex_1d;
2365 settings->op[i].projected = proj_none;
2370 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2372 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2373 if(ignore_textype) {
2374 settings->op[i].tex_type = tex_1d;
2376 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2378 settings->op[i].tex_type = tex_1d;
2381 settings->op[i].tex_type = tex_2d;
2384 settings->op[i].tex_type = tex_3d;
2386 case GL_TEXTURE_CUBE_MAP_ARB:
2387 settings->op[i].tex_type = tex_cube;
2389 case GL_TEXTURE_RECTANGLE_ARB:
2390 settings->op[i].tex_type = tex_rect;
2395 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2396 settings->op[i].tex_type = tex_1d;
2399 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2400 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2402 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2403 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2404 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2406 if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2409 carg1 = WINED3DTA_CURRENT;
2410 cop = WINED3DTOP_SELECTARG1;
2413 if(cop == WINED3DTOP_DOTPRODUCT3) {
2414 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2415 * the color result to the alpha component of the destination
2422 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2423 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2424 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2427 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2429 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2431 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2433 IWineD3DSurfaceImpl *surf;
2434 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2436 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2438 if (aop == WINED3DTOP_DISABLE)
2440 aarg1 = WINED3DTA_TEXTURE;
2441 aop = WINED3DTOP_SELECTARG1;
2443 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2445 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2447 aarg2 = WINED3DTA_TEXTURE;
2448 aop = WINED3DTOP_MODULATE;
2450 else aarg1 = WINED3DTA_TEXTURE;
2452 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2454 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2456 aarg1 = WINED3DTA_TEXTURE;
2457 aop = WINED3DTOP_MODULATE;
2459 else aarg2 = WINED3DTA_TEXTURE;
2465 if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2468 aarg1 = WINED3DTA_CURRENT;
2469 aop = WINED3DTOP_SELECTARG1;
2472 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2473 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2474 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2475 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2476 settings->op[i].projected = proj_count3;
2477 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2478 settings->op[i].projected = proj_count4;
2480 settings->op[i].projected = proj_none;
2483 settings->op[i].projected = proj_none;
2486 settings->op[i].cop = cop;
2487 settings->op[i].aop = aop;
2488 settings->op[i].carg0 = carg0;
2489 settings->op[i].carg1 = carg1;
2490 settings->op[i].carg2 = carg2;
2491 settings->op[i].aarg0 = aarg0;
2492 settings->op[i].aarg1 = aarg1;
2493 settings->op[i].aarg2 = aarg2;
2495 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2496 settings->op[i].dst = tempreg;
2498 settings->op[i].dst = resultreg;
2502 /* Clear unsupported stages */
2503 for(; i < MAX_TEXTURES; i++) {
2504 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2507 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2508 settings->fog = FOG_OFF;
2509 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2510 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2511 settings->fog = FOG_LINEAR;
2513 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2514 case WINED3DFOG_NONE:
2515 case WINED3DFOG_LINEAR:
2516 settings->fog = FOG_LINEAR;
2518 case WINED3DFOG_EXP:
2519 settings->fog = FOG_EXP;
2521 case WINED3DFOG_EXP2:
2522 settings->fog = FOG_EXP2;
2527 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2528 case WINED3DFOG_LINEAR:
2529 settings->fog = FOG_LINEAR;
2531 case WINED3DFOG_EXP:
2532 settings->fog = FOG_EXP;
2534 case WINED3DFOG_EXP2:
2535 settings->fog = FOG_EXP2;
2539 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2540 settings->sRGB_write = 1;
2542 settings->sRGB_write = 0;
2544 if(device->vs_clipping || !use_vs(stateblock) || !stateblock->renderState[WINED3DRS_CLIPPING] ||
2545 !stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
2546 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2547 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2548 * if no clipplane is enabled
2550 settings->emul_clipplanes = 0;
2552 settings->emul_clipplanes = 1;
2556 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2557 const struct ffp_frag_settings *settings)
2559 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2560 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2563 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2565 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2566 * whereas desc points to an extended structure with implementation specific parts. */
2567 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2569 ERR("Failed to insert ffp frag shader.\n");
2573 /* Activates the texture dimension according to the bound D3D texture.
2574 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2575 * Requires the caller to activate the correct unit before
2577 /* GL locking is done by the caller (state handler) */
2578 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2580 const struct wined3d_gl_info *gl_info = context->gl_info;
2582 if (stateblock->textures[stage])
2584 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2586 glDisable(GL_TEXTURE_3D);
2587 checkGLcall("glDisable(GL_TEXTURE_3D)");
2588 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2589 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2590 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2592 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2593 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2594 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2596 glEnable(GL_TEXTURE_2D);
2597 checkGLcall("glEnable(GL_TEXTURE_2D)");
2599 case GL_TEXTURE_RECTANGLE_ARB:
2600 glDisable(GL_TEXTURE_2D);
2601 checkGLcall("glDisable(GL_TEXTURE_2D)");
2602 glDisable(GL_TEXTURE_3D);
2603 checkGLcall("glDisable(GL_TEXTURE_3D)");
2604 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2605 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2606 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2608 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2609 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2612 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2613 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2614 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2616 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2617 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2618 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2620 glDisable(GL_TEXTURE_2D);
2621 checkGLcall("glDisable(GL_TEXTURE_2D)");
2622 glEnable(GL_TEXTURE_3D);
2623 checkGLcall("glEnable(GL_TEXTURE_3D)");
2625 case GL_TEXTURE_CUBE_MAP_ARB:
2626 glDisable(GL_TEXTURE_2D);
2627 checkGLcall("glDisable(GL_TEXTURE_2D)");
2628 glDisable(GL_TEXTURE_3D);
2629 checkGLcall("glDisable(GL_TEXTURE_3D)");
2630 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2631 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2632 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2634 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2635 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2639 glEnable(GL_TEXTURE_2D);
2640 checkGLcall("glEnable(GL_TEXTURE_2D)");
2641 glDisable(GL_TEXTURE_3D);
2642 checkGLcall("glDisable(GL_TEXTURE_3D)");
2643 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2644 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2645 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2647 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2648 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2649 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2651 /* Binding textures is done by samplers. A dummy texture will be bound */
2655 /* GL locking is done by the caller (state handler) */
2656 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2658 DWORD sampler = state - STATE_SAMPLER(0);
2659 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2661 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2662 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2663 * will take care of this business
2665 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->max_textures) return;
2666 if(sampler >= stateblock->lowest_disabled_stage) return;
2667 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2669 texture_activate_dimensions(sampler, stateblock, context);
2672 void *wined3d_rb_alloc(size_t size)
2674 return HeapAlloc(GetProcessHeap(), 0, size);
2677 void *wined3d_rb_realloc(void *ptr, size_t size)
2679 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
2682 void wined3d_rb_free(void *ptr)
2684 HeapFree(GetProcessHeap(), 0, ptr);
2687 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
2689 const struct ffp_frag_settings *ka = key;
2690 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
2692 return memcmp(ka, kb, sizeof(*ka));
2695 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
2700 ffp_frag_program_key_compare,
2703 UINT wined3d_log2i(UINT32 x)
2705 static const UINT l[] =
2707 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2708 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2709 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2710 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2711 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2712 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2713 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2714 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2715 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2716 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2717 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2718 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2719 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
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,
2726 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];