dplayx: Adjust GetCaps behaviour to documentation
[wine/gsoc_dplay.git] / dlls / wined3d / utils.c
blob3c25ebeb3e0ad7cce94cba904fb9645a1e38daad
1 /*
2 * Utility functions for the WineD3D Library
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2008 Henri Verbeet
9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "config.h"
27 #include "wined3d_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
31 struct StaticPixelFormatDesc
33 WINED3DFORMAT format;
34 DWORD alphaMask, redMask, greenMask, blueMask;
35 UINT bpp;
36 short depthSize, stencilSize;
37 BOOL isFourcc;
40 /*****************************************************************************
41 * Pixel format array
43 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
44 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
45 * high masks do not fit into the 32 bit values needed for ddraw. It is only
46 * used for ddraw mostly, and to figure out if the format has alpha at all, so
47 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
48 * formats are not usable in 2D rendering because ddraw doesn't support them.
50 static const struct StaticPixelFormatDesc formats[] =
52 /* WINED3DFORMAT alphamask redmask greenmask bluemask bpp depth stencil isFourcc */
53 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, FALSE},
54 /* FourCC formats, kept here to have WINED3DFMT_R8G8B8(=20) at position 20 */
55 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
56 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
57 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
58 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
59 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
60 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
61 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
62 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
63 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
64 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
65 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE },
66 /* IEEE formats */
67 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
68 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
69 {WINED3DFMT_R32G32B32_FLOAT, 0x0, 0x0, 0x0, 0x0, 12, 0, 0, FALSE},
70 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0, FALSE},
71 /* Hmm? */
72 {WINED3DFMT_CxV8U8, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
73 /* Float */
74 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
75 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
76 {WINED3DFMT_R16G16_SINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
77 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
78 {WINED3DFMT_R16G16B16A16_SINT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
79 /* Palettized formats */
80 {WINED3DFMT_A8P8, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
81 {WINED3DFMT_P8, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
82 /* Standard ARGB formats. */
83 {WINED3DFMT_R8G8B8, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0, FALSE},
84 {WINED3DFMT_A8R8G8B8, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0, FALSE},
85 {WINED3DFMT_X8R8G8B8, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0, FALSE},
86 {WINED3DFMT_R5G6B5, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0, FALSE},
87 {WINED3DFMT_X1R5G5B5, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0, FALSE},
88 {WINED3DFMT_A1R5G5B5, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0, FALSE},
89 {WINED3DFMT_A4R4G4B4, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0, FALSE},
90 {WINED3DFMT_R3G3B2, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0, FALSE},
91 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
92 {WINED3DFMT_A8R3G3B2, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0, FALSE},
93 {WINED3DFMT_X4R4G4B4, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0, FALSE},
94 {WINED3DFMT_R10G10B10A2_UNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
95 {WINED3DFMT_R10G10B10A2_UINT, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
96 {WINED3DFMT_R10G10B10A2_SNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE},
97 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
98 {WINED3DFMT_R8G8B8A8_UINT, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
99 {WINED3DFMT_X8B8G8R8, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE},
100 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0, FALSE},
101 {WINED3DFMT_A2R10G10B10, 0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0, FALSE},
102 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0, FALSE},
103 /* Luminance */
104 {WINED3DFMT_L8, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
105 {WINED3DFMT_A8L8, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
106 {WINED3DFMT_A4L4, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE},
107 /* Bump mapping stuff */
108 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
109 {WINED3DFMT_L6V5U5, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
110 {WINED3DFMT_X8L8V8U8, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
111 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
112 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
113 {WINED3DFMT_W11V11U10, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
114 {WINED3DFMT_A2W10V10U10, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
115 /* Depth stencil formats */
116 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
117 {WINED3DFMT_D32, 0x0, 0x0, 0x0, 0x0, 4, 32, 0, FALSE},
118 {WINED3DFMT_D15S1, 0x0, 0x0, 0x0, 0x0, 2, 15, 1, FALSE},
119 {WINED3DFMT_D24S8, 0x0, 0x0, 0x0, 0x0, 4, 24, 8, FALSE},
120 {WINED3DFMT_D24X8, 0x0, 0x0, 0x0, 0x0, 4, 24, 0, FALSE},
121 {WINED3DFMT_D24X4S4, 0x0, 0x0, 0x0, 0x0, 4, 24, 4, FALSE},
122 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
123 {WINED3DFMT_L16, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE},
124 {WINED3DFMT_D32F_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 4, 32, 0, FALSE},
125 {WINED3DFMT_D24FS8, 0x0, 0x0, 0x0, 0x0, 4, 24, 8, FALSE},
126 /* Is this a vertex buffer? */
127 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, FALSE},
128 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE},
129 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE},
130 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
131 /* Vendor-specific formats */
132 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE },
133 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
134 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE },
137 struct wined3d_format_compression_info
139 WINED3DFORMAT format;
140 UINT block_width;
141 UINT block_height;
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;
160 GLenum gl_vtx_type;
161 GLint gl_vtx_format;
162 GLboolean gl_normalized;
163 unsigned int component_size;
166 static const struct wined3d_format_vertex_info format_vertex_info[] =
168 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
169 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
170 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
171 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
172 {WINED3DFMT_A8R8G8B8, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
173 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
174 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
175 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
176 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
177 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
178 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
179 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
180 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
181 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
182 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
183 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
184 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
187 typedef struct {
188 WINED3DFORMAT fmt;
189 GLint glInternal, glGammaInternal, rtInternal, glFormat, glType;
190 unsigned int Flags;
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
198 * table.
200 static const GlPixelFormatDescTemplate gl_formats_template[] = {
201 /* WINED3DFORMAT internal srgbInternal rtInternal
202 format type
203 flags
204 extension */
205 /* FourCC formats */
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
210 * endian machine
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,
219 APPLE_YCBCR_422},
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,
227 APPLE_YCBCR_422},
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},
252 /* IEEE formats */
253 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
254 GL_RED, GL_FLOAT,
255 WINED3DFMT_FLAG_RENDERTARGET,
256 ARB_TEXTURE_FLOAT},
257 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
258 GL_RED, GL_FLOAT,
259 WINED3DFMT_FLAG_RENDERTARGET,
260 ARB_TEXTURE_RG},
261 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
262 GL_RGB, GL_FLOAT,
263 WINED3DFMT_FLAG_RENDERTARGET,
264 ARB_TEXTURE_FLOAT},
265 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
266 GL_RG, GL_FLOAT,
267 WINED3DFMT_FLAG_RENDERTARGET,
268 ARB_TEXTURE_RG},
269 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
270 GL_RGBA, GL_FLOAT,
271 WINED3DFMT_FLAG_RENDERTARGET,
272 ARB_TEXTURE_FLOAT},
273 /* Float */
274 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
275 GL_RED, GL_HALF_FLOAT_ARB,
276 WINED3DFMT_FLAG_RENDERTARGET,
277 ARB_TEXTURE_FLOAT},
278 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
279 GL_RED, GL_HALF_FLOAT_ARB,
280 WINED3DFMT_FLAG_RENDERTARGET,
281 ARB_TEXTURE_RG},
282 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
283 GL_RGB, GL_HALF_FLOAT_ARB,
284 WINED3DFMT_FLAG_RENDERTARGET,
285 ARB_TEXTURE_FLOAT},
286 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
287 GL_RG, GL_HALF_FLOAT_ARB,
288 WINED3DFMT_FLAG_RENDERTARGET,
289 ARB_TEXTURE_RG},
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,
293 ARB_TEXTURE_FLOAT},
294 /* Palettized formats */
295 {WINED3DFMT_P8, GL_RGBA, GL_RGBA, 0,
296 GL_RGBA, GL_UNSIGNED_BYTE,
298 ARB_FRAGMENT_PROGRAM},
299 {WINED3DFMT_P8, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
300 GL_COLOR_INDEX, GL_UNSIGNED_BYTE,
302 EXT_PALETTED_TEXTURE},
303 /* Standard ARGB formats */
304 {WINED3DFMT_R8G8B8, GL_RGB8, GL_RGB8, 0,
305 GL_BGR, GL_UNSIGNED_BYTE,
306 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
307 WINED3D_GL_EXT_NONE},
308 {WINED3DFMT_A8R8G8B8, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
309 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
310 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
311 WINED3D_GL_EXT_NONE},
312 {WINED3DFMT_X8R8G8B8, GL_RGB8, GL_SRGB8_EXT, 0,
313 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
314 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
315 WINED3D_GL_EXT_NONE},
316 {WINED3DFMT_R5G6B5, GL_RGB5, GL_RGB5, GL_RGB8,
317 GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
318 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
319 WINED3D_GL_EXT_NONE},
320 {WINED3DFMT_X1R5G5B5, GL_RGB5, GL_RGB5_A1, 0,
321 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
322 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
323 WINED3D_GL_EXT_NONE},
324 {WINED3DFMT_A1R5G5B5, GL_RGB5_A1, GL_RGB5_A1, 0,
325 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
326 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
327 WINED3D_GL_EXT_NONE},
328 {WINED3DFMT_A4R4G4B4, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
329 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
330 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
331 WINED3D_GL_EXT_NONE},
332 {WINED3DFMT_R3G3B2, GL_R3_G3_B2, GL_R3_G3_B2, 0,
333 GL_RGB, GL_UNSIGNED_BYTE_3_3_2,
334 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
335 WINED3D_GL_EXT_NONE},
336 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
337 GL_ALPHA, GL_UNSIGNED_BYTE,
338 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
339 WINED3D_GL_EXT_NONE},
340 {WINED3DFMT_X4R4G4B4, GL_RGB4, GL_RGB4, 0,
341 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
342 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
343 WINED3D_GL_EXT_NONE},
344 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
345 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV,
346 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
347 WINED3D_GL_EXT_NONE},
348 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
349 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
350 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
351 WINED3D_GL_EXT_NONE},
352 {WINED3DFMT_X8B8G8R8, GL_RGB8, GL_RGB8, 0,
353 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
354 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
355 WINED3D_GL_EXT_NONE},
356 {WINED3DFMT_R16G16_UNORM, GL_RGB16_EXT, GL_RGB16_EXT, GL_RGBA16_EXT,
357 GL_RGB, GL_UNSIGNED_SHORT,
358 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
359 WINED3D_GL_EXT_NONE},
360 {WINED3DFMT_A2R10G10B10, GL_RGB10_A2, GL_RGB10_A2, 0,
361 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV,
362 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
363 WINED3D_GL_EXT_NONE},
364 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16_EXT, GL_RGBA16_EXT, 0,
365 GL_RGBA, GL_UNSIGNED_SHORT,
366 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
367 WINED3D_GL_EXT_NONE},
368 /* Luminance */
369 {WINED3DFMT_L8, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
370 GL_LUMINANCE, GL_UNSIGNED_BYTE,
371 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
372 WINED3D_GL_EXT_NONE},
373 {WINED3DFMT_A8L8, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
374 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
375 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
376 WINED3D_GL_EXT_NONE},
377 {WINED3DFMT_A4L4, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
378 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
380 WINED3D_GL_EXT_NONE},
381 /* Bump mapping stuff */
382 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
383 GL_BGR, GL_UNSIGNED_BYTE,
384 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
385 WINED3D_GL_EXT_NONE},
386 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
387 GL_DSDT_NV, GL_BYTE,
388 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
389 NV_TEXTURE_SHADER},
390 {WINED3DFMT_L6V5U5, GL_RGB5, GL_RGB5, 0,
391 GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
392 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
393 WINED3D_GL_EXT_NONE},
394 {WINED3DFMT_L6V5U5, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
395 GL_DSDT_MAG_NV, GL_BYTE,
396 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
397 NV_TEXTURE_SHADER},
398 {WINED3DFMT_X8L8V8U8, GL_RGB8, GL_RGB8, 0,
399 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
400 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
401 WINED3D_GL_EXT_NONE},
402 {WINED3DFMT_X8L8V8U8, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
403 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV,
404 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
405 NV_TEXTURE_SHADER},
406 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
407 GL_BGRA, GL_UNSIGNED_BYTE,
408 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
409 WINED3D_GL_EXT_NONE},
410 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
411 GL_RGBA, GL_BYTE,
412 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
413 NV_TEXTURE_SHADER},
414 {WINED3DFMT_R16G16_SNORM, GL_RGB16_EXT, GL_RGB16_EXT, 0,
415 GL_BGR, GL_UNSIGNED_SHORT,
416 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
417 WINED3D_GL_EXT_NONE},
418 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
419 GL_HILO_NV, GL_SHORT,
420 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
421 NV_TEXTURE_SHADER},
422 /* Depth stencil formats */
423 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
424 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
425 WINED3DFMT_FLAG_DEPTH,
426 ARB_DEPTH_TEXTURE},
427 {WINED3DFMT_D32, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
428 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
429 WINED3DFMT_FLAG_DEPTH,
430 ARB_DEPTH_TEXTURE},
431 {WINED3DFMT_D15S1, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
432 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
433 WINED3DFMT_FLAG_DEPTH,
434 ARB_DEPTH_TEXTURE},
435 {WINED3DFMT_D15S1, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
436 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
437 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
438 EXT_PACKED_DEPTH_STENCIL},
439 {WINED3DFMT_D24S8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
440 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
441 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
442 ARB_DEPTH_TEXTURE},
443 {WINED3DFMT_D24S8, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
444 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
445 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
446 EXT_PACKED_DEPTH_STENCIL},
447 {WINED3DFMT_D24X8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
448 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
449 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
450 ARB_DEPTH_TEXTURE},
451 {WINED3DFMT_D24X4S4, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
452 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
453 WINED3DFMT_FLAG_DEPTH,
454 ARB_DEPTH_TEXTURE},
455 {WINED3DFMT_D24X4S4, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
456 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
457 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
458 EXT_PACKED_DEPTH_STENCIL},
459 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
460 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
461 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
462 ARB_DEPTH_TEXTURE},
463 {WINED3DFMT_L16, GL_LUMINANCE16_EXT, GL_LUMINANCE16_EXT, 0,
464 GL_LUMINANCE, GL_UNSIGNED_SHORT,
465 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
466 WINED3D_GL_EXT_NONE},
467 {WINED3DFMT_D32F_LOCKABLE, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
468 GL_DEPTH_COMPONENT, GL_FLOAT,
469 WINED3DFMT_FLAG_DEPTH,
470 ARB_DEPTH_BUFFER_FLOAT},
471 {WINED3DFMT_D24FS8, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
472 GL_DEPTH_STENCIL_EXT, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
473 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
474 ARB_DEPTH_BUFFER_FLOAT},
475 /* Vendor-specific formats */
476 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
477 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
479 ATI_TEXTURE_COMPRESSION_3DC},
480 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, 0,
481 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
483 EXT_TEXTURE_COMPRESSION_RGTC},
486 static inline int getFmtIdx(WINED3DFORMAT fmt) {
487 /* First check if the format is at the position of its value.
488 * This will catch the argb formats before the loop is entered
490 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
491 return fmt;
492 } else {
493 unsigned int i;
494 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
495 if(formats[i].format == fmt) {
496 return i;
500 return -1;
503 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
505 UINT format_count = sizeof(formats) / sizeof(*formats);
506 UINT i;
508 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->gl_formats));
509 if (!gl_info->gl_formats)
511 ERR("Failed to allocate memory.\n");
512 return FALSE;
515 for (i = 0; i < format_count; ++i)
517 struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
518 desc->format = formats[i].format;
519 desc->red_mask = formats[i].redMask;
520 desc->green_mask = formats[i].greenMask;
521 desc->blue_mask = formats[i].blueMask;
522 desc->alpha_mask = formats[i].alphaMask;
523 desc->byte_count = formats[i].bpp;
524 desc->depth_size = formats[i].depthSize;
525 desc->stencil_size = formats[i].stencilSize;
526 if (formats[i].isFourcc) desc->Flags |= WINED3DFMT_FLAG_FOURCC;
529 return TRUE;
532 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
534 unsigned int i;
536 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
538 struct GlPixelFormatDesc *format_desc;
539 int fmt_idx = getFmtIdx(format_compression_info[i].format);
541 if (fmt_idx == -1)
543 ERR("Format %s (%#x) not found.\n",
544 debug_d3dformat(format_compression_info[i].format), format_compression_info[i].format);
545 return FALSE;
548 format_desc = &gl_info->gl_formats[fmt_idx];
549 format_desc->block_width = format_compression_info[i].block_width;
550 format_desc->block_height = format_compression_info[i].block_height;
551 format_desc->block_byte_count = format_compression_info[i].block_byte_count;
552 format_desc->Flags |= WINED3DFMT_FLAG_COMPRESSED;
555 return TRUE;
558 #define GLINFO_LOCATION (*gl_info)
560 /* Context activation is done by the caller. */
561 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPixelFormatDesc *format_desc)
563 /* Check if the default internal format is supported as a frame buffer
564 * target, otherwise fall back to the render target internal.
566 * Try to stick to the standard format if possible, this limits precision differences. */
567 GLenum status;
568 GLuint tex;
570 ENTER_GL();
572 while(glGetError());
573 glDisable(GL_BLEND);
575 glGenTextures(1, &tex);
576 glBindTexture(GL_TEXTURE_2D, tex);
578 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glInternal, 16, 16, 0,
579 format_desc->glFormat, format_desc->glType, NULL);
580 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
581 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
583 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
585 status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
586 checkGLcall("Framebuffer format check");
588 if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
590 TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(format_desc->format));
591 format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
592 format_desc->rtInternal = format_desc->glInternal;
594 else
596 if (!format_desc->rtInternal)
598 if (format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)
600 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
601 " and no fallback specified.\n", debug_d3dformat(format_desc->format));
602 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
604 else
606 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format_desc->format));
608 format_desc->rtInternal = format_desc->glInternal;
610 else
612 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
613 debug_d3dformat(format_desc->format));
615 while(glGetError());
617 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0));
619 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->rtInternal, 16, 16, 0,
620 format_desc->glFormat, format_desc->glType, NULL);
621 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
622 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
624 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
626 status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
627 checkGLcall("Framebuffer format check");
629 if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
631 TRACE("Format %s rtInternal format is supported as FBO color attachment\n",
632 debug_d3dformat(format_desc->format));
634 else
636 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
637 debug_d3dformat(format_desc->format));
638 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
643 if (status == GL_FRAMEBUFFER_COMPLETE_EXT && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
645 GLuint rb;
647 if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
649 GL_EXTCALL(glGenRenderbuffersEXT(1, &rb));
650 GL_EXTCALL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb));
651 GL_EXTCALL(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, 16, 16));
652 GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
653 GL_RENDERBUFFER_EXT, rb));
654 GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
655 GL_RENDERBUFFER_EXT, rb));
656 checkGLcall("RB attachment");
659 glEnable(GL_BLEND);
660 glClear(GL_COLOR_BUFFER_BIT);
661 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION_EXT)
663 while(glGetError());
664 TRACE("Format doesn't support post-pixelshader blending.\n");
665 format_desc->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
668 if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
670 GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
671 GL_RENDERBUFFER_EXT, 0));
672 GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
673 GL_RENDERBUFFER_EXT, 0));
674 GL_EXTCALL(glDeleteRenderbuffersEXT(1, &rb));
675 checkGLcall("RB cleanup");
679 glDeleteTextures(1, &tex);
681 LEAVE_GL();
684 /* Context activation is done by the caller. */
685 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
687 unsigned int i;
688 GLuint fbo;
690 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
692 ENTER_GL();
694 GL_EXTCALL(glGenFramebuffersEXT(1, &fbo));
695 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
697 LEAVE_GL();
700 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
702 struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
704 if (!desc->glInternal) continue;
706 if (desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
708 TRACE("Skipping format %s because it's a depth/stencil format.\n",
709 debug_d3dformat(desc->format));
710 continue;
713 if (desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
715 TRACE("Skipping format %s because it's a compressed format.\n",
716 debug_d3dformat(desc->format));
717 continue;
720 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
722 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc->format));
723 check_fbo_compat(gl_info, desc);
725 else
727 desc->rtInternal = desc->glInternal;
731 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
733 ENTER_GL();
735 GL_EXTCALL(glDeleteFramebuffersEXT(1, &fbo));
737 LEAVE_GL();
741 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
743 unsigned int i;
745 for (i = 0; i < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); ++i)
747 int fmt_idx = getFmtIdx(gl_formats_template[i].fmt);
748 struct GlPixelFormatDesc *desc;
750 if (fmt_idx == -1)
752 ERR("Format %s (%#x) not found.\n",
753 debug_d3dformat(gl_formats_template[i].fmt), gl_formats_template[i].fmt);
754 return FALSE;
757 if (!GL_SUPPORT(gl_formats_template[i].extension)) continue;
759 desc = &gl_info->gl_formats[fmt_idx];
760 desc->glInternal = gl_formats_template[i].glInternal;
761 desc->glGammaInternal = gl_formats_template[i].glGammaInternal;
762 desc->rtInternal = gl_formats_template[i].rtInternal;
763 desc->glFormat = gl_formats_template[i].glFormat;
764 desc->glType = gl_formats_template[i].glType;
765 desc->color_fixup = COLOR_FIXUP_IDENTITY;
766 desc->Flags |= gl_formats_template[i].Flags;
767 desc->heightscale = 1.0f;
770 return TRUE;
773 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
775 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
776 c1 >>= 8; c2 >>= 8;
777 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
778 c1 >>= 8; c2 >>= 8;
779 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
780 c1 >>= 8; c2 >>= 8;
781 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
782 return TRUE;
785 /* A context is provided by the caller */
786 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
788 GLuint tex, fbo, buffer;
789 const DWORD data[] = {0x00000000, 0xffffffff};
790 DWORD readback[16 * 1];
791 BOOL ret = FALSE;
793 /* Render a filtered texture and see what happens. This is intended to detect the lack of
794 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
795 * falling back to software. If this changes in the future this code will get fooled and
796 * apps might hit the software path due to incorrectly advertised caps.
798 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
799 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
800 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
803 ENTER_GL();
804 while(glGetError());
806 glGenTextures(1, &buffer);
807 glBindTexture(GL_TEXTURE_2D, buffer);
808 memset(readback, 0x7e, sizeof(readback));
809 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
810 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
811 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
812 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
813 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
814 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
816 glGenTextures(1, &tex);
817 glBindTexture(GL_TEXTURE_2D, tex);
818 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
819 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
820 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
821 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
822 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
823 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
824 glEnable(GL_TEXTURE_2D);
826 GL_EXTCALL(glGenFramebuffersEXT(1, &fbo));
827 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
828 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, buffer, 0));
829 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
831 glViewport(0, 0, 16, 1);
832 glDisable(GL_LIGHTING);
833 glMatrixMode(GL_MODELVIEW);
834 glLoadIdentity();
835 glMatrixMode(GL_PROJECTION);
836 glLoadIdentity();
838 glClearColor(0, 1, 0, 0);
839 glClear(GL_COLOR_BUFFER_BIT);
841 glBegin(GL_TRIANGLE_STRIP);
842 glTexCoord2f(0.0, 0.0);
843 glVertex2f(-1.0f, -1.0f);
844 glTexCoord2f(1.0, 0.0);
845 glVertex2f(1.0f, -1.0f);
846 glTexCoord2f(0.0, 1.0);
847 glVertex2f(-1.0f, 1.0f);
848 glTexCoord2f(1.0, 1.0);
849 glVertex2f(1.0f, 1.0f);
850 glEnd();
852 glBindTexture(GL_TEXTURE_2D, buffer);
853 memset(readback, 0x7f, sizeof(readback));
854 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
855 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
856 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
858 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
859 readback[6], readback[9]);
860 ret = FALSE;
862 else
864 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
865 readback[6], readback[9]);
866 ret = TRUE;
869 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
870 GL_EXTCALL(glDeleteFramebuffersEXT(1, &fbo));
871 glDeleteTextures(1, &tex);
872 glDeleteTextures(1, &buffer);
874 if(glGetError())
876 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
877 ret = FALSE;
879 LEAVE_GL();
880 return ret;
883 static void init_format_filter_info(struct wined3d_gl_info *gl_info)
885 unsigned int fmt_idx, i;
886 WINED3DFORMAT fmts16[] = {
887 WINED3DFMT_R16_FLOAT,
888 WINED3DFMT_R16G16_FLOAT,
889 WINED3DFMT_R16G16B16A16_FLOAT,
891 BOOL filtered;
892 struct GlPixelFormatDesc *desc;
894 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
896 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
897 if(gl_info->gl_vendor == VENDOR_NVIDIA && GL_SUPPORT(ARB_TEXTURE_FLOAT))
899 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
900 filtered = TRUE;
902 else if(GL_LIMITS(glsl_varyings > 44))
904 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
905 filtered = TRUE;
907 else
909 TRACE("Assuming no float16 blending\n");
910 filtered = FALSE;
913 if(filtered)
915 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
917 fmt_idx = getFmtIdx(fmts16[i]);
918 gl_info->gl_formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
921 return;
924 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
926 fmt_idx = getFmtIdx(fmts16[i]);
927 desc = &gl_info->gl_formats[fmt_idx];
928 if(!desc->glInternal) continue; /* Not supported by GL */
930 filtered = check_filter(gl_info, gl_info->gl_formats[fmt_idx].glInternal);
931 if(filtered)
933 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
934 desc->Flags |= WINED3DFMT_FLAG_FILTERING;
936 else
938 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
943 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
945 int idx;
947 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
948 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
949 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
951 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
952 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
953 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
955 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
956 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
957 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
959 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
960 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
961 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
963 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
964 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
965 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
967 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
968 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
969 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
970 * the only driver that implements it(fglrx) has a buggy implementation.
972 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
973 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
974 * conversion for this format.
976 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
978 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
979 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
980 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
981 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
982 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
983 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
985 else
987 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
988 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
989 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
990 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
991 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
992 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
995 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
997 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
998 * with each other
1000 idx = getFmtIdx(WINED3DFMT_L6V5U5);
1001 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1002 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1003 idx = getFmtIdx(WINED3DFMT_X8L8V8U8);
1004 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1005 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1006 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1007 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1008 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1010 else
1012 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1013 * are converted at surface loading time, but they do not need any modification in
1014 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1015 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1019 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC))
1021 idx = getFmtIdx(WINED3DFMT_ATI2N);
1022 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1023 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1025 else if (GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC))
1027 idx = getFmtIdx(WINED3DFMT_ATI2N);
1028 gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
1029 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1032 if (!GL_SUPPORT(APPLE_YCBCR_422))
1034 idx = getFmtIdx(WINED3DFMT_YUY2);
1035 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
1037 idx = getFmtIdx(WINED3DFMT_UYVY);
1038 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
1041 idx = getFmtIdx(WINED3DFMT_YV12);
1042 gl_info->gl_formats[idx].heightscale = 1.5f;
1043 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
1045 if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
1047 idx = getFmtIdx(WINED3DFMT_A8R8G8B8);
1048 gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
1051 if (GL_SUPPORT(ARB_HALF_FLOAT_VERTEX))
1053 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1054 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1055 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1056 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1058 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1059 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1063 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1065 unsigned int i;
1067 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1069 struct GlPixelFormatDesc *format_desc;
1070 int fmt_idx = getFmtIdx(format_vertex_info[i].format);
1072 if (fmt_idx == -1)
1074 ERR("Format %s (%#x) not found.\n",
1075 debug_d3dformat(format_vertex_info[i].format), format_vertex_info[i].format);
1076 return FALSE;
1079 format_desc = &gl_info->gl_formats[fmt_idx];
1080 format_desc->emit_idx = format_vertex_info[i].emit_idx;
1081 format_desc->component_count = format_vertex_info[i].component_count;
1082 format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1083 format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1084 format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
1085 format_desc->component_size = format_vertex_info[i].component_size;
1088 return TRUE;
1091 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1093 if (!init_format_base_info(gl_info)) return FALSE;
1095 if (!init_format_compression_info(gl_info))
1097 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1098 return FALSE;
1101 return TRUE;
1104 /* Context activation is done by the caller. */
1105 BOOL initPixelFormats(struct wined3d_gl_info *gl_info)
1107 if (!init_format_base_info(gl_info)) return FALSE;
1109 if (!init_format_compression_info(gl_info)) goto fail;
1110 if (!init_format_texture_info(gl_info)) goto fail;
1111 if (!init_format_vertex_info(gl_info)) goto fail;
1113 apply_format_fixups(gl_info);
1114 init_format_fbo_compat_info(gl_info);
1115 init_format_filter_info(gl_info);
1117 return TRUE;
1119 fail:
1120 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1121 return FALSE;
1124 #undef GLINFO_LOCATION
1126 #define GLINFO_LOCATION This->adapter->gl_info
1128 const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info)
1130 int idx = getFmtIdx(fmt);
1132 if(idx == -1) {
1133 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
1134 /* Get the caller a valid pointer */
1135 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1138 return &gl_info->gl_formats[idx];
1141 /*****************************************************************************
1142 * Trace formatting of useful values
1144 const char* debug_d3dformat(WINED3DFORMAT fmt) {
1145 switch (fmt) {
1146 #define FMT_TO_STR(fmt) case fmt: return #fmt
1147 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1148 FMT_TO_STR(WINED3DFMT_R8G8B8);
1149 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
1150 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
1151 FMT_TO_STR(WINED3DFMT_R5G6B5);
1152 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
1153 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
1154 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
1155 FMT_TO_STR(WINED3DFMT_R3G3B2);
1156 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
1157 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
1158 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
1159 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
1160 FMT_TO_STR(WINED3DFMT_A8P8);
1161 FMT_TO_STR(WINED3DFMT_P8);
1162 FMT_TO_STR(WINED3DFMT_L8);
1163 FMT_TO_STR(WINED3DFMT_A8L8);
1164 FMT_TO_STR(WINED3DFMT_A4L4);
1165 FMT_TO_STR(WINED3DFMT_L6V5U5);
1166 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
1167 FMT_TO_STR(WINED3DFMT_W11V11U10);
1168 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
1169 FMT_TO_STR(WINED3DFMT_UYVY);
1170 FMT_TO_STR(WINED3DFMT_YUY2);
1171 FMT_TO_STR(WINED3DFMT_YV12);
1172 FMT_TO_STR(WINED3DFMT_DXT1);
1173 FMT_TO_STR(WINED3DFMT_DXT2);
1174 FMT_TO_STR(WINED3DFMT_DXT3);
1175 FMT_TO_STR(WINED3DFMT_DXT4);
1176 FMT_TO_STR(WINED3DFMT_DXT5);
1177 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1178 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1179 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1180 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1181 FMT_TO_STR(WINED3DFMT_D32);
1182 FMT_TO_STR(WINED3DFMT_D15S1);
1183 FMT_TO_STR(WINED3DFMT_D24S8);
1184 FMT_TO_STR(WINED3DFMT_D24X8);
1185 FMT_TO_STR(WINED3DFMT_D24X4S4);
1186 FMT_TO_STR(WINED3DFMT_L16);
1187 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
1188 FMT_TO_STR(WINED3DFMT_D24FS8);
1189 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1190 FMT_TO_STR(WINED3DFMT_CxV8U8);
1191 FMT_TO_STR(WINED3DFMT_ATI2N);
1192 FMT_TO_STR(WINED3DFMT_NVHU);
1193 FMT_TO_STR(WINED3DFMT_NVHS);
1194 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1195 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1196 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1197 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1198 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1199 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1200 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1201 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1202 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1203 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1204 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1205 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1206 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1207 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1208 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1209 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1210 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1211 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1212 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1213 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1214 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1215 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1216 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1217 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1218 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1219 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1220 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1221 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1222 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1223 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1224 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1225 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1226 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1227 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1228 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1229 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1230 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1231 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1232 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1233 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1234 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1235 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1236 FMT_TO_STR(WINED3DFMT_R32_UINT);
1237 FMT_TO_STR(WINED3DFMT_R32_SINT);
1238 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1239 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1240 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1241 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1242 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1243 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1244 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1245 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1246 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1247 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1248 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1249 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1250 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1251 FMT_TO_STR(WINED3DFMT_R16_UINT);
1252 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1253 FMT_TO_STR(WINED3DFMT_R16_SINT);
1254 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1255 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1256 FMT_TO_STR(WINED3DFMT_R8_UINT);
1257 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1258 FMT_TO_STR(WINED3DFMT_R8_SINT);
1259 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1260 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1261 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1262 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1263 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1264 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1265 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1266 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1267 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1268 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1269 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1270 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1271 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1272 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1273 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1274 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1275 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1276 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1277 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1278 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1279 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1280 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1281 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1282 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1283 #undef FMT_TO_STR
1284 default:
1286 char fourcc[5];
1287 fourcc[0] = (char)(fmt);
1288 fourcc[1] = (char)(fmt >> 8);
1289 fourcc[2] = (char)(fmt >> 16);
1290 fourcc[3] = (char)(fmt >> 24);
1291 fourcc[4] = 0;
1292 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
1293 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
1294 else
1295 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
1297 return "unrecognized";
1301 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
1302 switch (devtype) {
1303 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1304 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1305 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1306 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1307 #undef DEVTYPE_TO_STR
1308 default:
1309 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1310 return "unrecognized";
1314 const char *debug_d3dusage(DWORD usage)
1316 char buf[284];
1318 buf[0] = '\0';
1319 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1320 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1321 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1322 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1323 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1324 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1325 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1326 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1327 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1328 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1329 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1330 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1331 #undef WINED3DUSAGE_TO_STR
1332 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1334 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1337 const char *debug_d3dusagequery(DWORD usagequery)
1339 char buf[238];
1341 buf[0] = '\0';
1342 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1343 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1344 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1345 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1346 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1347 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1348 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1349 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1350 #undef WINED3DUSAGEQUERY_TO_STR
1351 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1353 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1356 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1357 switch (method) {
1358 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1359 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1360 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1361 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1362 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1363 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1364 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1365 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1366 #undef WINED3DDECLMETHOD_TO_STR
1367 default:
1368 FIXME("Unrecognized %u declaration method!\n", method);
1369 return "unrecognized";
1373 const char* debug_d3ddeclusage(BYTE usage) {
1374 switch (usage) {
1375 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1376 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1377 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1378 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1379 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1380 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1381 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1382 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1383 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1384 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1385 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1386 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1387 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1388 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1389 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1390 #undef WINED3DDECLUSAGE_TO_STR
1391 default:
1392 FIXME("Unrecognized %u declaration usage!\n", usage);
1393 return "unrecognized";
1397 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1398 switch (res) {
1399 #define RES_TO_STR(res) case res: return #res
1400 RES_TO_STR(WINED3DRTYPE_SURFACE);
1401 RES_TO_STR(WINED3DRTYPE_VOLUME);
1402 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1403 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1404 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1405 RES_TO_STR(WINED3DRTYPE_BUFFER);
1406 #undef RES_TO_STR
1407 default:
1408 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1409 return "unrecognized";
1413 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1414 switch (PrimitiveType) {
1415 #define PRIM_TO_STR(prim) case prim: return #prim
1416 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1417 PRIM_TO_STR(WINED3DPT_POINTLIST);
1418 PRIM_TO_STR(WINED3DPT_LINELIST);
1419 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1420 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1421 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1422 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1423 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1424 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1425 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1426 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1427 #undef PRIM_TO_STR
1428 default:
1429 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1430 return "unrecognized";
1434 const char* debug_d3drenderstate(DWORD state) {
1435 switch (state) {
1436 #define D3DSTATE_TO_STR(u) case u: return #u
1437 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
1438 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1439 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
1440 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1441 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1442 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1443 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1444 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1445 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1446 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1447 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1448 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1449 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1450 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1451 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1452 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1453 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
1454 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
1455 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1456 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1457 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
1458 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1459 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1460 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1461 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1462 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1463 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1464 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1465 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1466 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1467 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1468 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1469 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1470 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1471 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1472 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1473 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1474 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1475 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1476 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1477 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1478 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
1479 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
1480 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
1481 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1482 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1483 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1484 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1485 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1486 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1487 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1488 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1489 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1490 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1491 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1492 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1493 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1494 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1495 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1496 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
1497 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
1498 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
1499 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
1500 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
1501 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
1502 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
1503 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
1504 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
1505 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
1506 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
1507 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
1508 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
1509 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
1510 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
1511 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
1512 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
1513 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
1514 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
1515 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
1516 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
1517 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
1518 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
1519 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
1520 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
1521 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
1522 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
1523 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
1524 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
1525 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
1526 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
1527 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
1528 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1529 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1530 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1531 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1532 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1533 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1534 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1535 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1536 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1537 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1538 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1539 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1540 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1541 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1542 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1543 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1544 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1545 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1546 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1547 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1548 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1549 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1550 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1551 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1552 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1553 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1554 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1555 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1556 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1557 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1558 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1559 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1560 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1561 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1562 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1563 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1564 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1565 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1566 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1567 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1568 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1569 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1570 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1571 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1572 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1573 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1574 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1575 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1576 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1577 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1578 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1579 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1580 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1581 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1582 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1583 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1584 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1585 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1586 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1587 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1588 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1589 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1590 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1591 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1592 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1593 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1594 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1595 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1596 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1597 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1598 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1599 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1600 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1601 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1602 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1603 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1604 #undef D3DSTATE_TO_STR
1605 default:
1606 FIXME("Unrecognized %u render state!\n", state);
1607 return "unrecognized";
1611 const char* debug_d3dsamplerstate(DWORD state) {
1612 switch (state) {
1613 #define D3DSTATE_TO_STR(u) case u: return #u
1614 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1615 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1616 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1617 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1618 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1619 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1620 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1621 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1622 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1623 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1624 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1625 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1626 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1627 #undef D3DSTATE_TO_STR
1628 default:
1629 FIXME("Unrecognized %u sampler state!\n", state);
1630 return "unrecognized";
1634 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1635 switch (filter_type) {
1636 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1637 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1638 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1639 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1640 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1641 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1642 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1643 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1644 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1645 #undef D3DTEXTUREFILTERTYPE_TO_STR
1646 default:
1647 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1648 return "unrecognized";
1652 const char* debug_d3dtexturestate(DWORD state) {
1653 switch (state) {
1654 #define D3DSTATE_TO_STR(u) case u: return #u
1655 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1656 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1657 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1658 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1659 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1660 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1661 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1662 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1663 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1664 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1665 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1666 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1667 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1668 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1669 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1670 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1671 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1672 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1673 #undef D3DSTATE_TO_STR
1674 default:
1675 FIXME("Unrecognized %u texture state!\n", state);
1676 return "unrecognized";
1680 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1681 switch (d3dtop) {
1682 #define D3DTOP_TO_STR(u) case u: return #u
1683 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1684 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1685 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1686 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1687 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1688 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1689 D3DTOP_TO_STR(WINED3DTOP_ADD);
1690 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1691 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1692 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1693 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1694 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1695 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1696 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1697 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1698 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1699 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1700 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1701 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1702 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1703 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1704 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1705 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1706 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1707 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1708 D3DTOP_TO_STR(WINED3DTOP_LERP);
1709 #undef D3DTOP_TO_STR
1710 default:
1711 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1712 return "unrecognized";
1716 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1717 switch (tstype) {
1718 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1719 TSTYPE_TO_STR(WINED3DTS_VIEW);
1720 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1721 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1722 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1723 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1724 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1725 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1726 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1727 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1728 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1729 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1730 #undef TSTYPE_TO_STR
1731 default:
1732 if (tstype > 256 && tstype < 512) {
1733 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1734 return ("WINED3DTS_WORLDMATRIX > 0");
1736 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1737 return "unrecognized";
1741 const char* debug_d3dpool(WINED3DPOOL Pool) {
1742 switch (Pool) {
1743 #define POOL_TO_STR(p) case p: return #p
1744 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1745 POOL_TO_STR(WINED3DPOOL_MANAGED);
1746 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1747 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1748 #undef POOL_TO_STR
1749 default:
1750 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1751 return "unrecognized";
1755 const char *debug_fbostatus(GLenum status) {
1756 switch(status) {
1757 #define FBOSTATUS_TO_STR(u) case u: return #u
1758 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1759 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1760 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1761 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1762 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1763 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1764 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1765 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
1766 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1767 #undef FBOSTATUS_TO_STR
1768 default:
1769 FIXME("Unrecognied FBO status 0x%08x\n", status);
1770 return "unrecognized";
1774 const char *debug_glerror(GLenum error) {
1775 switch(error) {
1776 #define GLERROR_TO_STR(u) case u: return #u
1777 GLERROR_TO_STR(GL_NO_ERROR);
1778 GLERROR_TO_STR(GL_INVALID_ENUM);
1779 GLERROR_TO_STR(GL_INVALID_VALUE);
1780 GLERROR_TO_STR(GL_INVALID_OPERATION);
1781 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1782 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1783 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1784 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1785 #undef GLERROR_TO_STR
1786 default:
1787 FIXME("Unrecognied GL error 0x%08x\n", error);
1788 return "unrecognized";
1792 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1793 switch(basis) {
1794 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1795 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1796 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1797 default: return "unrecognized";
1801 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1802 switch(degree) {
1803 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1804 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1805 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1806 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1807 default: return "unrecognized";
1811 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
1813 switch(source)
1815 #define WINED3D_TO_STR(x) case x: return #x
1816 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1817 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1818 WINED3D_TO_STR(CHANNEL_SOURCE_X);
1819 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1820 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1821 WINED3D_TO_STR(CHANNEL_SOURCE_W);
1822 WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1823 WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1824 #undef WINED3D_TO_STR
1825 default:
1826 FIXME("Unrecognized fixup_channel_source %#x\n", source);
1827 return "unrecognized";
1831 static const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1833 switch(yuv_fixup)
1835 #define WINED3D_TO_STR(x) case x: return #x
1836 WINED3D_TO_STR(YUV_FIXUP_YUY2);
1837 WINED3D_TO_STR(YUV_FIXUP_UYVY);
1838 WINED3D_TO_STR(YUV_FIXUP_YV12);
1839 #undef WINED3D_TO_STR
1840 default:
1841 FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1842 return "unrecognized";
1846 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1848 if (is_yuv_fixup(fixup))
1850 TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1851 return;
1854 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1855 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1856 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1857 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1860 const char *debug_surflocation(DWORD flag) {
1861 char buf[128];
1863 buf[0] = 0;
1864 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
1865 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
1866 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
1867 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
1868 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
1871 /*****************************************************************************
1872 * Useful functions mapping GL <-> D3D values
1874 GLenum StencilOp(DWORD op) {
1875 switch(op) {
1876 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1877 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1878 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1879 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1880 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1881 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1882 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1883 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1884 default:
1885 FIXME("Unrecognized stencil op %d\n", op);
1886 return GL_KEEP;
1890 GLenum CompareFunc(DWORD func) {
1891 switch ((WINED3DCMPFUNC)func) {
1892 case WINED3DCMP_NEVER : return GL_NEVER;
1893 case WINED3DCMP_LESS : return GL_LESS;
1894 case WINED3DCMP_EQUAL : return GL_EQUAL;
1895 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1896 case WINED3DCMP_GREATER : return GL_GREATER;
1897 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1898 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1899 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1900 default:
1901 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1902 return 0;
1906 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1907 if (op == WINED3DTOP_DISABLE) return FALSE;
1908 if (This->stateBlock->textures[stage]) return FALSE;
1910 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1911 && op != WINED3DTOP_SELECTARG2) return TRUE;
1912 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1913 && op != WINED3DTOP_SELECTARG1) return TRUE;
1914 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1915 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1917 return FALSE;
1920 /* Setup this textures matrix according to the texture flags*/
1921 /* GL locking is done by the caller (state handler) */
1922 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
1923 WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
1925 float mat[16];
1927 glMatrixMode(GL_TEXTURE);
1928 checkGLcall("glMatrixMode(GL_TEXTURE)");
1930 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1931 glLoadIdentity();
1932 checkGLcall("glLoadIdentity()");
1933 return;
1936 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1937 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1938 return;
1941 memcpy(mat, smat, 16 * sizeof(float));
1943 if (flags & WINED3DTTFF_PROJECTED) {
1944 if(!ffp_proj_control) {
1945 switch (flags & ~WINED3DTTFF_PROJECTED) {
1946 case WINED3DTTFF_COUNT2:
1947 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1948 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1949 break;
1950 case WINED3DTTFF_COUNT3:
1951 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1952 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1953 break;
1956 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1957 if(!calculatedCoords) {
1958 switch(vtx_fmt)
1960 case WINED3DFMT_R32_FLOAT:
1961 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1962 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1963 * the input value to the transformation will be 0, so the matrix value is irrelevant
1965 mat[12] = mat[4];
1966 mat[13] = mat[5];
1967 mat[14] = mat[6];
1968 mat[15] = mat[7];
1969 break;
1970 case WINED3DFMT_R32G32_FLOAT:
1971 /* See above, just 3rd and 4th coord
1973 mat[12] = mat[8];
1974 mat[13] = mat[9];
1975 mat[14] = mat[10];
1976 mat[15] = mat[11];
1977 break;
1978 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
1979 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
1981 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1982 * into a bad place. The division elimination below will apply to make sure the
1983 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1985 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
1986 break;
1987 default:
1988 FIXME("Unexpected fixed function texture coord input\n");
1991 if(!ffp_proj_control) {
1992 switch (flags & ~WINED3DTTFF_PROJECTED) {
1993 /* case WINED3DTTFF_COUNT1: Won't ever get here */
1994 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
1995 /* OpenGL divides the first 3 vertex coord by the 4th by default,
1996 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
1997 * the 4th coord evaluates to 1.0 to eliminate that.
1999 * If the fixed function pipeline is used, the 4th value remains unused,
2000 * so there is no danger in doing this. With vertex shaders we have a
2001 * problem. Should an app hit that problem, the code here would have to
2002 * check for pixel shaders, and the shader has to undo the default gl divide.
2004 * A more serious problem occurs if the app passes 4 coordinates in, and the
2005 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2006 * or a replacement shader
2008 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2013 glLoadMatrixf(mat);
2014 checkGLcall("glLoadMatrixf(mat)");
2016 #undef GLINFO_LOCATION
2018 /* This small helper function is used to convert a bitmask into the number of masked bits */
2019 unsigned int count_bits(unsigned int mask)
2021 unsigned int count;
2022 for (count = 0; mask; ++count)
2024 mask &= mask - 1;
2026 return count;
2029 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2030 * The later function requires individual color components. */
2031 BOOL getColorBits(const struct GlPixelFormatDesc *format_desc,
2032 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2034 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2035 switch(format_desc->format)
2037 case WINED3DFMT_X8R8G8B8:
2038 case WINED3DFMT_R8G8B8:
2039 case WINED3DFMT_A8R8G8B8:
2040 case WINED3DFMT_R8G8B8A8_UNORM:
2041 case WINED3DFMT_A2R10G10B10:
2042 case WINED3DFMT_X1R5G5B5:
2043 case WINED3DFMT_A1R5G5B5:
2044 case WINED3DFMT_R5G6B5:
2045 case WINED3DFMT_X4R4G4B4:
2046 case WINED3DFMT_A4R4G4B4:
2047 case WINED3DFMT_R3G3B2:
2048 case WINED3DFMT_A8P8:
2049 case WINED3DFMT_P8:
2050 break;
2051 default:
2052 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
2053 return FALSE;
2056 *redSize = count_bits(format_desc->red_mask);
2057 *greenSize = count_bits(format_desc->green_mask);
2058 *blueSize = count_bits(format_desc->blue_mask);
2059 *alphaSize = count_bits(format_desc->alpha_mask);
2060 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2062 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
2063 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
2064 return TRUE;
2067 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2068 BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize)
2070 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2071 switch(format_desc->format)
2073 case WINED3DFMT_D16_LOCKABLE:
2074 case WINED3DFMT_D16_UNORM:
2075 case WINED3DFMT_D15S1:
2076 case WINED3DFMT_D24X8:
2077 case WINED3DFMT_D24X4S4:
2078 case WINED3DFMT_D24S8:
2079 case WINED3DFMT_D24FS8:
2080 case WINED3DFMT_D32:
2081 case WINED3DFMT_D32F_LOCKABLE:
2082 break;
2083 default:
2084 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
2085 return FALSE;
2088 *depthSize = format_desc->depth_size;
2089 *stencilSize = format_desc->stencil_size;
2091 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
2092 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
2093 return TRUE;
2096 /* DirectDraw stuff */
2097 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2098 switch(depth) {
2099 case 8: return WINED3DFMT_P8;
2100 case 15: return WINED3DFMT_X1R5G5B5;
2101 case 16: return WINED3DFMT_R5G6B5;
2102 case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
2103 case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
2104 default: return WINED3DFMT_UNKNOWN;
2108 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2109 WINED3DMATRIX temp;
2111 /* Now do the multiplication 'by hand'.
2112 I know that all this could be optimised, but this will be done later :-) */
2113 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);
2114 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);
2115 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);
2116 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);
2118 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);
2119 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);
2120 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);
2121 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);
2123 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);
2124 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);
2125 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);
2126 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);
2128 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);
2129 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);
2130 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);
2131 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);
2133 /* And copy the new matrix in the good storage.. */
2134 memcpy(dest, &temp, 16 * sizeof(float));
2137 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2138 DWORD size = 0;
2139 int i;
2140 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2142 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2143 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2144 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2145 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2146 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2147 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2148 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2149 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2150 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2151 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2152 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2153 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2154 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2155 default: ERR("Unexpected position mask\n");
2157 for (i = 0; i < numTextures; i++) {
2158 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2161 return size;
2164 /***********************************************************************
2165 * CalculateTexRect
2167 * Calculates the dimensions of the opengl texture used for blits.
2168 * Handled oversized opengl textures and updates the source rectangle
2169 * accordingly
2171 * Params:
2172 * This: Surface to operate on
2173 * Rect: Requested rectangle
2175 * Returns:
2176 * TRUE if the texture part can be loaded,
2177 * FALSE otherwise
2179 *********************************************************************/
2180 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
2182 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
2183 int x1 = Rect->left, x2 = Rect->right;
2184 int y1 = Rect->top, y2 = Rect->bottom;
2185 GLint maxSize = GL_LIMITS(texture_size);
2187 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2188 Rect->left, Rect->top, Rect->right, Rect->bottom);
2190 /* The sizes might be reversed */
2191 if(Rect->left > Rect->right) {
2192 x1 = Rect->right;
2193 x2 = Rect->left;
2195 if(Rect->top > Rect->bottom) {
2196 y1 = Rect->bottom;
2197 y2 = Rect->top;
2200 /* No oversized texture? This is easy */
2201 if(!(This->Flags & SFLAG_OVERSIZE)) {
2202 /* Which rect from the texture do I need? */
2203 if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
2205 glTexCoord[0] = (float) Rect->left;
2206 glTexCoord[2] = (float) Rect->top;
2207 glTexCoord[1] = (float) Rect->right;
2208 glTexCoord[3] = (float) Rect->bottom;
2209 } else {
2210 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2211 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2212 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2213 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2216 return TRUE;
2217 } else {
2218 /* Check if we can succeed at all */
2219 if( (x2 - x1) > maxSize ||
2220 (y2 - y1) > maxSize ) {
2221 TRACE("Requested rectangle is too large for gl\n");
2222 return FALSE;
2225 /* A part of the texture has to be picked. First, check if
2226 * some texture part is loaded already, if yes try to re-use it.
2227 * If the texture is dirty, or the part can't be used,
2228 * re-position the part to load
2230 if(This->Flags & SFLAG_INTEXTURE) {
2231 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2232 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2233 /* Ok, the rectangle is ok, re-use it */
2234 TRACE("Using existing gl Texture\n");
2235 } else {
2236 /* Rectangle is not ok, dirtify the texture to reload it */
2237 TRACE("Dirtifying texture to force reload\n");
2238 This->Flags &= ~SFLAG_INTEXTURE;
2242 /* Now if we are dirty(no else if!) */
2243 if(!(This->Flags & SFLAG_INTEXTURE)) {
2244 /* Set the new rectangle. Use the following strategy:
2245 * 1) Use as big textures as possible.
2246 * 2) Place the texture part in the way that the requested
2247 * part is in the middle of the texture(well, almost)
2248 * 3) If the texture is moved over the edges of the
2249 * surface, replace it nicely
2250 * 4) If the coord is not limiting the texture size,
2251 * use the whole size
2253 if((This->pow2Width) > maxSize) {
2254 This->glRect.left = x1 - maxSize / 2;
2255 if(This->glRect.left < 0) {
2256 This->glRect.left = 0;
2258 This->glRect.right = This->glRect.left + maxSize;
2259 if(This->glRect.right > This->currentDesc.Width) {
2260 This->glRect.right = This->currentDesc.Width;
2261 This->glRect.left = This->glRect.right - maxSize;
2263 } else {
2264 This->glRect.left = 0;
2265 This->glRect.right = This->pow2Width;
2268 if(This->pow2Height > maxSize) {
2269 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2270 if(This->glRect.top < 0) This->glRect.top = 0;
2271 This->glRect.bottom = This->glRect.left + maxSize;
2272 if(This->glRect.bottom > This->currentDesc.Height) {
2273 This->glRect.bottom = This->currentDesc.Height;
2274 This->glRect.top = This->glRect.bottom - maxSize;
2276 } else {
2277 This->glRect.top = 0;
2278 This->glRect.bottom = This->pow2Height;
2280 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2281 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2284 /* Re-calculate the rect to draw */
2285 Rect->left -= This->glRect.left;
2286 Rect->right -= This->glRect.left;
2287 Rect->top -= This->glRect.top;
2288 Rect->bottom -= This->glRect.top;
2290 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2291 * or the pow2Width / pow2Height of the surface.
2293 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
2294 * as regular GL_TEXTURE_2D.
2296 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2297 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2298 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2299 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2301 return TRUE;
2303 #undef GLINFO_LOCATION
2305 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2306 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2307 #define ARG1 0x01
2308 #define ARG2 0x02
2309 #define ARG0 0x04
2310 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2311 /* undefined */ 0,
2312 /* D3DTOP_DISABLE */ 0,
2313 /* D3DTOP_SELECTARG1 */ ARG1,
2314 /* D3DTOP_SELECTARG2 */ ARG2,
2315 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2316 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2317 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2318 /* D3DTOP_ADD */ ARG1 | ARG2,
2319 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2320 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2321 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2322 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2323 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2324 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2325 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2326 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2327 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2328 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2329 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2330 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2331 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2332 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2333 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2334 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2335 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2336 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2337 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2339 unsigned int i;
2340 DWORD ttff;
2341 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2342 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2344 for(i = 0; i < GL_LIMITS(texture_stages); i++) {
2345 IWineD3DBaseTextureImpl *texture;
2346 settings->op[i].padding = 0;
2347 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2348 settings->op[i].cop = WINED3DTOP_DISABLE;
2349 settings->op[i].aop = WINED3DTOP_DISABLE;
2350 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2351 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2352 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2353 settings->op[i].dst = resultreg;
2354 settings->op[i].tex_type = tex_1d;
2355 settings->op[i].projected = proj_none;
2356 i++;
2357 break;
2360 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2361 if(texture) {
2362 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2363 if(ignore_textype) {
2364 settings->op[i].tex_type = tex_1d;
2365 } else {
2366 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2367 case GL_TEXTURE_1D:
2368 settings->op[i].tex_type = tex_1d;
2369 break;
2370 case GL_TEXTURE_2D:
2371 settings->op[i].tex_type = tex_2d;
2372 break;
2373 case GL_TEXTURE_3D:
2374 settings->op[i].tex_type = tex_3d;
2375 break;
2376 case GL_TEXTURE_CUBE_MAP_ARB:
2377 settings->op[i].tex_type = tex_cube;
2378 break;
2379 case GL_TEXTURE_RECTANGLE_ARB:
2380 settings->op[i].tex_type = tex_rect;
2381 break;
2384 } else {
2385 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2386 settings->op[i].tex_type = tex_1d;
2389 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2390 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2392 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2393 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2394 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2396 if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2397 carg0 = ARG_UNUSED;
2398 carg2 = ARG_UNUSED;
2399 carg1 = WINED3DTA_CURRENT;
2400 cop = WINED3DTOP_SELECTARG1;
2403 if(cop == WINED3DTOP_DOTPRODUCT3) {
2404 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2405 * the color result to the alpha component of the destination
2407 aop = cop;
2408 aarg1 = carg1;
2409 aarg2 = carg2;
2410 aarg0 = carg0;
2411 } else {
2412 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2413 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2414 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2417 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2419 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2421 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2423 IWineD3DSurfaceImpl *surf;
2424 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2426 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2428 if (aop == WINED3DTOP_DISABLE)
2430 aarg1 = WINED3DTA_TEXTURE;
2431 aop = WINED3DTOP_SELECTARG1;
2433 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2435 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2437 aarg2 = WINED3DTA_TEXTURE;
2438 aop = WINED3DTOP_MODULATE;
2440 else aarg1 = WINED3DTA_TEXTURE;
2442 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2444 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2446 aarg1 = WINED3DTA_TEXTURE;
2447 aop = WINED3DTOP_MODULATE;
2449 else aarg2 = WINED3DTA_TEXTURE;
2455 if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2456 aarg0 = ARG_UNUSED;
2457 aarg2 = ARG_UNUSED;
2458 aarg1 = WINED3DTA_CURRENT;
2459 aop = WINED3DTOP_SELECTARG1;
2462 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2463 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2464 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2465 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2466 settings->op[i].projected = proj_count3;
2467 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2468 settings->op[i].projected = proj_count4;
2469 } else {
2470 settings->op[i].projected = proj_none;
2472 } else {
2473 settings->op[i].projected = proj_none;
2476 settings->op[i].cop = cop;
2477 settings->op[i].aop = aop;
2478 settings->op[i].carg0 = carg0;
2479 settings->op[i].carg1 = carg1;
2480 settings->op[i].carg2 = carg2;
2481 settings->op[i].aarg0 = aarg0;
2482 settings->op[i].aarg1 = aarg1;
2483 settings->op[i].aarg2 = aarg2;
2485 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2486 settings->op[i].dst = tempreg;
2487 } else {
2488 settings->op[i].dst = resultreg;
2492 /* Clear unsupported stages */
2493 for(; i < MAX_TEXTURES; i++) {
2494 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2497 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2498 settings->fog = FOG_OFF;
2499 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2500 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2501 settings->fog = FOG_LINEAR;
2502 } else {
2503 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2504 case WINED3DFOG_NONE:
2505 case WINED3DFOG_LINEAR:
2506 settings->fog = FOG_LINEAR;
2507 break;
2508 case WINED3DFOG_EXP:
2509 settings->fog = FOG_EXP;
2510 break;
2511 case WINED3DFOG_EXP2:
2512 settings->fog = FOG_EXP2;
2513 break;
2516 } else {
2517 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2518 case WINED3DFOG_LINEAR:
2519 settings->fog = FOG_LINEAR;
2520 break;
2521 case WINED3DFOG_EXP:
2522 settings->fog = FOG_EXP;
2523 break;
2524 case WINED3DFOG_EXP2:
2525 settings->fog = FOG_EXP2;
2526 break;
2529 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2530 settings->sRGB_write = 1;
2531 } else {
2532 settings->sRGB_write = 0;
2534 if(device->vs_clipping || !use_vs(stateblock)) {
2535 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2536 * the fixed function vertex pipeline is used(which always supports clipplanes)
2538 settings->emul_clipplanes = 0;
2539 } else {
2540 settings->emul_clipplanes = 1;
2543 #undef GLINFO_LOCATION
2545 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2546 const struct ffp_frag_settings *settings)
2548 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2549 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2552 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2554 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2555 * whereas desc points to an extended structure with implementation specific parts. */
2556 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2558 ERR("Failed to insert ffp frag shader.\n");
2562 /* Activates the texture dimension according to the bound D3D texture.
2563 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2564 * Requires the caller to activate the correct unit before
2566 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2567 /* GL locking is done by the caller (state handler) */
2568 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2570 if(stateblock->textures[stage]) {
2571 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2572 case GL_TEXTURE_2D:
2573 glDisable(GL_TEXTURE_3D);
2574 checkGLcall("glDisable(GL_TEXTURE_3D)");
2575 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2576 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2577 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2579 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2580 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2581 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2583 glEnable(GL_TEXTURE_2D);
2584 checkGLcall("glEnable(GL_TEXTURE_2D)");
2585 break;
2586 case GL_TEXTURE_RECTANGLE_ARB:
2587 glDisable(GL_TEXTURE_2D);
2588 checkGLcall("glDisable(GL_TEXTURE_2D)");
2589 glDisable(GL_TEXTURE_3D);
2590 checkGLcall("glDisable(GL_TEXTURE_3D)");
2591 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2592 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2593 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2595 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2596 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2597 break;
2598 case GL_TEXTURE_3D:
2599 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2600 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2601 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2603 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2604 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2605 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2607 glDisable(GL_TEXTURE_2D);
2608 checkGLcall("glDisable(GL_TEXTURE_2D)");
2609 glEnable(GL_TEXTURE_3D);
2610 checkGLcall("glEnable(GL_TEXTURE_3D)");
2611 break;
2612 case GL_TEXTURE_CUBE_MAP_ARB:
2613 glDisable(GL_TEXTURE_2D);
2614 checkGLcall("glDisable(GL_TEXTURE_2D)");
2615 glDisable(GL_TEXTURE_3D);
2616 checkGLcall("glDisable(GL_TEXTURE_3D)");
2617 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2618 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2619 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2621 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2622 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2623 break;
2625 } else {
2626 glEnable(GL_TEXTURE_2D);
2627 checkGLcall("glEnable(GL_TEXTURE_2D)");
2628 glDisable(GL_TEXTURE_3D);
2629 checkGLcall("glDisable(GL_TEXTURE_3D)");
2630 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2631 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2632 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2634 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2635 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2636 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2638 /* Binding textures is done by samplers. A dummy texture will be bound */
2642 /* GL locking is done by the caller (state handler) */
2643 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2645 DWORD sampler = state - STATE_SAMPLER(0);
2646 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2648 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2649 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2650 * will take care of this business
2652 if(mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= GL_LIMITS(textures)) return;
2653 if(sampler >= stateblock->lowest_disabled_stage) return;
2654 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2656 texture_activate_dimensions(sampler, stateblock, context);
2658 #undef GLINFO_LOCATION
2660 void *wined3d_rb_alloc(size_t size)
2662 return HeapAlloc(GetProcessHeap(), 0, size);
2665 void *wined3d_rb_realloc(void *ptr, size_t size)
2667 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
2670 void wined3d_rb_free(void *ptr)
2672 HeapFree(GetProcessHeap(), 0, ptr);
2675 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
2677 const struct ffp_frag_settings *ka = key;
2678 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
2680 return memcmp(ka, kb, sizeof(*ka));
2683 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
2685 wined3d_rb_alloc,
2686 wined3d_rb_realloc,
2687 wined3d_rb_free,
2688 ffp_frag_program_key_compare,
2691 UINT wined3d_log2i(UINT32 x)
2693 static const UINT l[] =
2695 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2696 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2697 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2698 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2699 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2700 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2701 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2702 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2703 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2704 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2705 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2706 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2707 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2708 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2709 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2710 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2712 UINT32 i;
2714 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];