push 862965e7f7bbbfb960006fcded9111ae18c06ef6
[wine/hacks.git] / dlls / wined3d / utils.c
blobd2631ea0135bc8401e56dea63e4d1ec22af998b7
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_FILTERING | 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_FILTERING | 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_FILTERING | 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_FILTERING | 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_FILTERING | 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 void apply_format_fixups(struct wined3d_gl_info *gl_info)
775 int idx;
777 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
778 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
779 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
781 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
782 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
783 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
785 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
786 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
787 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
789 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
790 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
791 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
793 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
794 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
795 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
797 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
798 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
799 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
800 * the only driver that implements it(fglrx) has a buggy implementation.
802 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
803 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
804 * conversion for this format.
806 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
808 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
809 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
810 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
811 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
812 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
813 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
815 else
817 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
818 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
819 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
820 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
821 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
822 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
825 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
827 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
828 * with each other
830 idx = getFmtIdx(WINED3DFMT_L6V5U5);
831 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
832 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
833 idx = getFmtIdx(WINED3DFMT_X8L8V8U8);
834 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
835 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
836 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
837 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
838 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
840 else
842 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
843 * are converted at surface loading time, but they do not need any modification in
844 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
845 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
849 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC))
851 idx = getFmtIdx(WINED3DFMT_ATI2N);
852 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
853 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
855 else if (GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC))
857 idx = getFmtIdx(WINED3DFMT_ATI2N);
858 gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
859 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
862 if (!GL_SUPPORT(APPLE_YCBCR_422))
864 idx = getFmtIdx(WINED3DFMT_YUY2);
865 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
867 idx = getFmtIdx(WINED3DFMT_UYVY);
868 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
871 idx = getFmtIdx(WINED3DFMT_YV12);
872 gl_info->gl_formats[idx].heightscale = 1.5f;
873 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
875 if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
877 idx = getFmtIdx(WINED3DFMT_A8R8G8B8);
878 gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
881 if (GL_SUPPORT(ARB_HALF_FLOAT_VERTEX))
883 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
884 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
885 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
886 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
888 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
889 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
893 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
895 unsigned int i;
897 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
899 struct GlPixelFormatDesc *format_desc;
900 int fmt_idx = getFmtIdx(format_vertex_info[i].format);
902 if (fmt_idx == -1)
904 ERR("Format %s (%#x) not found.\n",
905 debug_d3dformat(format_vertex_info[i].format), format_vertex_info[i].format);
906 return FALSE;
909 format_desc = &gl_info->gl_formats[fmt_idx];
910 format_desc->emit_idx = format_vertex_info[i].emit_idx;
911 format_desc->component_count = format_vertex_info[i].component_count;
912 format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
913 format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
914 format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
915 format_desc->component_size = format_vertex_info[i].component_size;
918 return TRUE;
921 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
923 if (!init_format_base_info(gl_info)) return FALSE;
925 if (!init_format_compression_info(gl_info))
927 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
928 return FALSE;
931 return TRUE;
934 /* Context activation is done by the caller. */
935 BOOL initPixelFormats(struct wined3d_gl_info *gl_info)
937 if (!init_format_base_info(gl_info)) return FALSE;
939 if (!init_format_compression_info(gl_info)) goto fail;
940 if (!init_format_texture_info(gl_info)) goto fail;
941 if (!init_format_vertex_info(gl_info)) goto fail;
943 apply_format_fixups(gl_info);
944 init_format_fbo_compat_info(gl_info);
946 return TRUE;
948 fail:
949 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
950 return FALSE;
953 #undef GLINFO_LOCATION
955 #define GLINFO_LOCATION This->adapter->gl_info
957 const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info)
959 int idx = getFmtIdx(fmt);
961 if(idx == -1) {
962 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
963 /* Get the caller a valid pointer */
964 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
967 return &gl_info->gl_formats[idx];
970 /*****************************************************************************
971 * Trace formatting of useful values
973 const char* debug_d3dformat(WINED3DFORMAT fmt) {
974 switch (fmt) {
975 #define FMT_TO_STR(fmt) case fmt: return #fmt
976 FMT_TO_STR(WINED3DFMT_UNKNOWN);
977 FMT_TO_STR(WINED3DFMT_R8G8B8);
978 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
979 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
980 FMT_TO_STR(WINED3DFMT_R5G6B5);
981 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
982 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
983 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
984 FMT_TO_STR(WINED3DFMT_R3G3B2);
985 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
986 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
987 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
988 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
989 FMT_TO_STR(WINED3DFMT_A8P8);
990 FMT_TO_STR(WINED3DFMT_P8);
991 FMT_TO_STR(WINED3DFMT_L8);
992 FMT_TO_STR(WINED3DFMT_A8L8);
993 FMT_TO_STR(WINED3DFMT_A4L4);
994 FMT_TO_STR(WINED3DFMT_L6V5U5);
995 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
996 FMT_TO_STR(WINED3DFMT_W11V11U10);
997 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
998 FMT_TO_STR(WINED3DFMT_UYVY);
999 FMT_TO_STR(WINED3DFMT_YUY2);
1000 FMT_TO_STR(WINED3DFMT_YV12);
1001 FMT_TO_STR(WINED3DFMT_DXT1);
1002 FMT_TO_STR(WINED3DFMT_DXT2);
1003 FMT_TO_STR(WINED3DFMT_DXT3);
1004 FMT_TO_STR(WINED3DFMT_DXT4);
1005 FMT_TO_STR(WINED3DFMT_DXT5);
1006 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1007 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1008 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1009 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1010 FMT_TO_STR(WINED3DFMT_D32);
1011 FMT_TO_STR(WINED3DFMT_D15S1);
1012 FMT_TO_STR(WINED3DFMT_D24S8);
1013 FMT_TO_STR(WINED3DFMT_D24X8);
1014 FMT_TO_STR(WINED3DFMT_D24X4S4);
1015 FMT_TO_STR(WINED3DFMT_L16);
1016 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
1017 FMT_TO_STR(WINED3DFMT_D24FS8);
1018 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1019 FMT_TO_STR(WINED3DFMT_CxV8U8);
1020 FMT_TO_STR(WINED3DFMT_ATI2N);
1021 FMT_TO_STR(WINED3DFMT_NVHU);
1022 FMT_TO_STR(WINED3DFMT_NVHS);
1023 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1024 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1025 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1026 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1027 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1028 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1029 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1030 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1031 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1032 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1033 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1034 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1035 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1036 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1037 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1038 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1039 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1040 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1041 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1042 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1043 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1044 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1045 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1046 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1047 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1048 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1049 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1050 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1051 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1052 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1053 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1054 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1055 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1056 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1057 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1058 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1059 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1060 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1061 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1062 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1063 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1064 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1065 FMT_TO_STR(WINED3DFMT_R32_UINT);
1066 FMT_TO_STR(WINED3DFMT_R32_SINT);
1067 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1068 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1069 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1070 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1071 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1072 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1073 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1074 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1075 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1076 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1077 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1078 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1079 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1080 FMT_TO_STR(WINED3DFMT_R16_UINT);
1081 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1082 FMT_TO_STR(WINED3DFMT_R16_SINT);
1083 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1084 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1085 FMT_TO_STR(WINED3DFMT_R8_UINT);
1086 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1087 FMT_TO_STR(WINED3DFMT_R8_SINT);
1088 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1089 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1090 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1091 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1092 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1093 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1094 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1095 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1096 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1097 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1098 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1099 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1100 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1101 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1102 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1103 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1104 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1105 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1106 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1107 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1108 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1109 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1110 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1111 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1112 #undef FMT_TO_STR
1113 default:
1115 char fourcc[5];
1116 fourcc[0] = (char)(fmt);
1117 fourcc[1] = (char)(fmt >> 8);
1118 fourcc[2] = (char)(fmt >> 16);
1119 fourcc[3] = (char)(fmt >> 24);
1120 fourcc[4] = 0;
1121 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
1122 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
1123 else
1124 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
1126 return "unrecognized";
1130 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
1131 switch (devtype) {
1132 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1133 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1134 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1135 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1136 #undef DEVTYPE_TO_STR
1137 default:
1138 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1139 return "unrecognized";
1143 const char *debug_d3dusage(DWORD usage)
1145 char buf[284];
1147 buf[0] = '\0';
1148 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1149 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1150 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1151 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1152 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1153 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1154 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1155 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1156 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1157 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1158 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1159 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1160 #undef WINED3DUSAGE_TO_STR
1161 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1163 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1166 const char *debug_d3dusagequery(DWORD usagequery)
1168 char buf[238];
1170 buf[0] = '\0';
1171 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1172 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1173 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1174 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1175 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1176 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1177 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1178 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1179 #undef WINED3DUSAGEQUERY_TO_STR
1180 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1182 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1185 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1186 switch (method) {
1187 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1188 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1189 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1190 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1191 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1192 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1193 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1194 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1195 #undef WINED3DDECLMETHOD_TO_STR
1196 default:
1197 FIXME("Unrecognized %u declaration method!\n", method);
1198 return "unrecognized";
1202 const char* debug_d3ddeclusage(BYTE usage) {
1203 switch (usage) {
1204 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1205 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1206 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1207 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1208 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1209 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1210 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1211 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1212 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1213 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1214 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1215 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1216 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1217 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1218 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1219 #undef WINED3DDECLUSAGE_TO_STR
1220 default:
1221 FIXME("Unrecognized %u declaration usage!\n", usage);
1222 return "unrecognized";
1226 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1227 switch (res) {
1228 #define RES_TO_STR(res) case res: return #res
1229 RES_TO_STR(WINED3DRTYPE_SURFACE);
1230 RES_TO_STR(WINED3DRTYPE_VOLUME);
1231 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1232 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1233 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1234 RES_TO_STR(WINED3DRTYPE_BUFFER);
1235 #undef RES_TO_STR
1236 default:
1237 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1238 return "unrecognized";
1242 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1243 switch (PrimitiveType) {
1244 #define PRIM_TO_STR(prim) case prim: return #prim
1245 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1246 PRIM_TO_STR(WINED3DPT_POINTLIST);
1247 PRIM_TO_STR(WINED3DPT_LINELIST);
1248 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1249 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1250 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1251 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1252 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1253 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1254 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1255 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1256 #undef PRIM_TO_STR
1257 default:
1258 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1259 return "unrecognized";
1263 const char* debug_d3drenderstate(DWORD state) {
1264 switch (state) {
1265 #define D3DSTATE_TO_STR(u) case u: return #u
1266 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
1267 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1268 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
1269 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1270 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1271 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1272 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1273 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1274 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1275 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1276 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1277 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1278 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1279 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1280 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1281 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1282 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
1283 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
1284 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1285 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1286 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
1287 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1288 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1289 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1290 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1291 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1292 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1293 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1294 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1295 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1296 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1297 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1298 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1299 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1300 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1301 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1302 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1303 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1304 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1305 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1306 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1307 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
1308 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
1309 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
1310 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1311 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1312 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1313 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1314 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1315 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1316 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1317 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1318 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1319 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1320 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1321 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1322 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1323 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1324 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1325 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
1326 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
1327 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
1328 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
1329 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
1330 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
1331 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
1332 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
1333 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
1334 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
1335 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
1336 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
1337 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
1338 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
1339 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
1340 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
1341 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
1342 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
1343 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
1344 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
1345 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
1346 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
1347 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
1348 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
1349 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
1350 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
1351 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
1352 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
1353 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
1354 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
1355 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
1356 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
1357 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1358 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1359 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1360 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1361 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1362 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1363 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1364 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1365 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1366 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1367 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1368 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1369 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1370 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1371 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1372 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1373 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1374 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1375 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1376 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1377 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1378 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1379 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1380 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1381 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1382 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1383 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1384 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1385 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1386 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1387 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1388 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1389 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1390 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1391 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1392 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1393 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1394 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1395 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1396 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1397 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1398 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1399 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1400 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1401 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1402 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1403 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1404 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1405 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1406 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1407 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1408 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1409 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1410 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1411 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1412 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1413 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1414 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1415 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1416 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1417 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1418 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1419 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1420 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1421 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1422 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1423 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1424 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1425 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1426 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1427 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1428 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1429 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1430 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1431 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1432 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1433 #undef D3DSTATE_TO_STR
1434 default:
1435 FIXME("Unrecognized %u render state!\n", state);
1436 return "unrecognized";
1440 const char* debug_d3dsamplerstate(DWORD state) {
1441 switch (state) {
1442 #define D3DSTATE_TO_STR(u) case u: return #u
1443 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1444 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1445 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1446 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1447 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1448 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1449 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1450 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1451 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1452 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1453 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1454 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1455 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1456 #undef D3DSTATE_TO_STR
1457 default:
1458 FIXME("Unrecognized %u sampler state!\n", state);
1459 return "unrecognized";
1463 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1464 switch (filter_type) {
1465 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1466 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1467 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1468 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1469 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1470 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1471 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1472 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1473 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1474 #undef D3DTEXTUREFILTERTYPE_TO_STR
1475 default:
1476 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1477 return "unrecognized";
1481 const char* debug_d3dtexturestate(DWORD state) {
1482 switch (state) {
1483 #define D3DSTATE_TO_STR(u) case u: return #u
1484 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1485 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1486 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1487 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1488 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1489 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1490 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1491 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1492 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1493 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1494 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1495 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1496 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1497 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1498 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1499 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1500 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1501 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1502 #undef D3DSTATE_TO_STR
1503 default:
1504 FIXME("Unrecognized %u texture state!\n", state);
1505 return "unrecognized";
1509 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1510 switch (d3dtop) {
1511 #define D3DTOP_TO_STR(u) case u: return #u
1512 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1513 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1514 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1515 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1516 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1517 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1518 D3DTOP_TO_STR(WINED3DTOP_ADD);
1519 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1520 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1521 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1522 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1523 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1524 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1525 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1526 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1527 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1528 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1529 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1530 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1531 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1532 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1533 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1534 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1535 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1536 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1537 D3DTOP_TO_STR(WINED3DTOP_LERP);
1538 #undef D3DTOP_TO_STR
1539 default:
1540 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1541 return "unrecognized";
1545 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1546 switch (tstype) {
1547 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1548 TSTYPE_TO_STR(WINED3DTS_VIEW);
1549 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1550 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1551 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1552 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1553 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1554 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1555 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1556 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1557 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1558 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1559 #undef TSTYPE_TO_STR
1560 default:
1561 if (tstype > 256 && tstype < 512) {
1562 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1563 return ("WINED3DTS_WORLDMATRIX > 0");
1565 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1566 return "unrecognized";
1570 const char* debug_d3dpool(WINED3DPOOL Pool) {
1571 switch (Pool) {
1572 #define POOL_TO_STR(p) case p: return #p
1573 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1574 POOL_TO_STR(WINED3DPOOL_MANAGED);
1575 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1576 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1577 #undef POOL_TO_STR
1578 default:
1579 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1580 return "unrecognized";
1584 const char *debug_fbostatus(GLenum status) {
1585 switch(status) {
1586 #define FBOSTATUS_TO_STR(u) case u: return #u
1587 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1588 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1589 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1590 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1591 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1592 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1593 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1594 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
1595 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1596 #undef FBOSTATUS_TO_STR
1597 default:
1598 FIXME("Unrecognied FBO status 0x%08x\n", status);
1599 return "unrecognized";
1603 const char *debug_glerror(GLenum error) {
1604 switch(error) {
1605 #define GLERROR_TO_STR(u) case u: return #u
1606 GLERROR_TO_STR(GL_NO_ERROR);
1607 GLERROR_TO_STR(GL_INVALID_ENUM);
1608 GLERROR_TO_STR(GL_INVALID_VALUE);
1609 GLERROR_TO_STR(GL_INVALID_OPERATION);
1610 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1611 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1612 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1613 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1614 #undef GLERROR_TO_STR
1615 default:
1616 FIXME("Unrecognied GL error 0x%08x\n", error);
1617 return "unrecognized";
1621 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1622 switch(basis) {
1623 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1624 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1625 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1626 default: return "unrecognized";
1630 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1631 switch(degree) {
1632 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1633 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1634 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1635 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1636 default: return "unrecognized";
1640 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
1642 switch(source)
1644 #define WINED3D_TO_STR(x) case x: return #x
1645 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1646 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1647 WINED3D_TO_STR(CHANNEL_SOURCE_X);
1648 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1649 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1650 WINED3D_TO_STR(CHANNEL_SOURCE_W);
1651 WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1652 WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1653 #undef WINED3D_TO_STR
1654 default:
1655 FIXME("Unrecognized fixup_channel_source %#x\n", source);
1656 return "unrecognized";
1660 static const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1662 switch(yuv_fixup)
1664 #define WINED3D_TO_STR(x) case x: return #x
1665 WINED3D_TO_STR(YUV_FIXUP_YUY2);
1666 WINED3D_TO_STR(YUV_FIXUP_UYVY);
1667 WINED3D_TO_STR(YUV_FIXUP_YV12);
1668 #undef WINED3D_TO_STR
1669 default:
1670 FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1671 return "unrecognized";
1675 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1677 if (is_yuv_fixup(fixup))
1679 TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1680 return;
1683 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1684 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1685 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1686 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1689 const char *debug_surflocation(DWORD flag) {
1690 char buf[128];
1692 buf[0] = 0;
1693 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
1694 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
1695 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
1696 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
1697 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
1700 /*****************************************************************************
1701 * Useful functions mapping GL <-> D3D values
1703 GLenum StencilOp(DWORD op) {
1704 switch(op) {
1705 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1706 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1707 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1708 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1709 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1710 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1711 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1712 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1713 default:
1714 FIXME("Unrecognized stencil op %d\n", op);
1715 return GL_KEEP;
1719 GLenum CompareFunc(DWORD func) {
1720 switch ((WINED3DCMPFUNC)func) {
1721 case WINED3DCMP_NEVER : return GL_NEVER;
1722 case WINED3DCMP_LESS : return GL_LESS;
1723 case WINED3DCMP_EQUAL : return GL_EQUAL;
1724 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1725 case WINED3DCMP_GREATER : return GL_GREATER;
1726 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1727 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1728 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1729 default:
1730 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1731 return 0;
1735 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1736 if (op == WINED3DTOP_DISABLE) return FALSE;
1737 if (This->stateBlock->textures[stage]) return FALSE;
1739 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1740 && op != WINED3DTOP_SELECTARG2) return TRUE;
1741 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1742 && op != WINED3DTOP_SELECTARG1) return TRUE;
1743 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1744 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1746 return FALSE;
1749 /* Setup this textures matrix according to the texture flags*/
1750 /* GL locking is done by the caller (state handler) */
1751 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
1752 WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
1754 float mat[16];
1756 glMatrixMode(GL_TEXTURE);
1757 checkGLcall("glMatrixMode(GL_TEXTURE)");
1759 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1760 glLoadIdentity();
1761 checkGLcall("glLoadIdentity()");
1762 return;
1765 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1766 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1767 return;
1770 memcpy(mat, smat, 16 * sizeof(float));
1772 if (flags & WINED3DTTFF_PROJECTED) {
1773 if(!ffp_proj_control) {
1774 switch (flags & ~WINED3DTTFF_PROJECTED) {
1775 case WINED3DTTFF_COUNT2:
1776 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1777 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1778 break;
1779 case WINED3DTTFF_COUNT3:
1780 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1781 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1782 break;
1785 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1786 if(!calculatedCoords) {
1787 switch(vtx_fmt)
1789 case WINED3DFMT_R32_FLOAT:
1790 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1791 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1792 * the input value to the transformation will be 0, so the matrix value is irrelevant
1794 mat[12] = mat[4];
1795 mat[13] = mat[5];
1796 mat[14] = mat[6];
1797 mat[15] = mat[7];
1798 break;
1799 case WINED3DFMT_R32G32_FLOAT:
1800 /* See above, just 3rd and 4th coord
1802 mat[12] = mat[8];
1803 mat[13] = mat[9];
1804 mat[14] = mat[10];
1805 mat[15] = mat[11];
1806 break;
1807 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
1808 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
1810 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1811 * into a bad place. The division elimination below will apply to make sure the
1812 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1814 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
1815 break;
1816 default:
1817 FIXME("Unexpected fixed function texture coord input\n");
1820 if(!ffp_proj_control) {
1821 switch (flags & ~WINED3DTTFF_PROJECTED) {
1822 /* case WINED3DTTFF_COUNT1: Won't ever get here */
1823 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
1824 /* OpenGL divides the first 3 vertex coord by the 4th by default,
1825 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
1826 * the 4th coord evaluates to 1.0 to eliminate that.
1828 * If the fixed function pipeline is used, the 4th value remains unused,
1829 * so there is no danger in doing this. With vertex shaders we have a
1830 * problem. Should an app hit that problem, the code here would have to
1831 * check for pixel shaders, and the shader has to undo the default gl divide.
1833 * A more serious problem occurs if the app passes 4 coordinates in, and the
1834 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
1835 * or a replacement shader
1837 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
1842 glLoadMatrixf(mat);
1843 checkGLcall("glLoadMatrixf(mat)");
1845 #undef GLINFO_LOCATION
1847 /* This small helper function is used to convert a bitmask into the number of masked bits */
1848 unsigned int count_bits(unsigned int mask)
1850 unsigned int count;
1851 for (count = 0; mask; ++count)
1853 mask &= mask - 1;
1855 return count;
1858 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
1859 * The later function requires individual color components. */
1860 BOOL getColorBits(const struct GlPixelFormatDesc *format_desc,
1861 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
1863 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
1864 switch(format_desc->format)
1866 case WINED3DFMT_X8R8G8B8:
1867 case WINED3DFMT_R8G8B8:
1868 case WINED3DFMT_A8R8G8B8:
1869 case WINED3DFMT_R8G8B8A8_UNORM:
1870 case WINED3DFMT_A2R10G10B10:
1871 case WINED3DFMT_X1R5G5B5:
1872 case WINED3DFMT_A1R5G5B5:
1873 case WINED3DFMT_R5G6B5:
1874 case WINED3DFMT_X4R4G4B4:
1875 case WINED3DFMT_A4R4G4B4:
1876 case WINED3DFMT_R3G3B2:
1877 case WINED3DFMT_A8P8:
1878 case WINED3DFMT_P8:
1879 break;
1880 default:
1881 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
1882 return FALSE;
1885 *redSize = count_bits(format_desc->red_mask);
1886 *greenSize = count_bits(format_desc->green_mask);
1887 *blueSize = count_bits(format_desc->blue_mask);
1888 *alphaSize = count_bits(format_desc->alpha_mask);
1889 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
1891 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
1892 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
1893 return TRUE;
1896 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
1897 BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize)
1899 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
1900 switch(format_desc->format)
1902 case WINED3DFMT_D16_LOCKABLE:
1903 case WINED3DFMT_D16_UNORM:
1904 case WINED3DFMT_D15S1:
1905 case WINED3DFMT_D24X8:
1906 case WINED3DFMT_D24X4S4:
1907 case WINED3DFMT_D24S8:
1908 case WINED3DFMT_D24FS8:
1909 case WINED3DFMT_D32:
1910 case WINED3DFMT_D32F_LOCKABLE:
1911 break;
1912 default:
1913 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
1914 return FALSE;
1917 *depthSize = format_desc->depth_size;
1918 *stencilSize = format_desc->stencil_size;
1920 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
1921 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
1922 return TRUE;
1925 /* DirectDraw stuff */
1926 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
1927 switch(depth) {
1928 case 8: return WINED3DFMT_P8;
1929 case 15: return WINED3DFMT_X1R5G5B5;
1930 case 16: return WINED3DFMT_R5G6B5;
1931 case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
1932 case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
1933 default: return WINED3DFMT_UNKNOWN;
1937 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
1938 WINED3DMATRIX temp;
1940 /* Now do the multiplication 'by hand'.
1941 I know that all this could be optimised, but this will be done later :-) */
1942 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);
1943 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);
1944 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);
1945 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);
1947 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);
1948 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);
1949 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);
1950 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);
1952 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);
1953 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);
1954 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);
1955 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);
1957 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);
1958 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);
1959 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);
1960 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);
1962 /* And copy the new matrix in the good storage.. */
1963 memcpy(dest, &temp, 16 * sizeof(float));
1966 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
1967 DWORD size = 0;
1968 int i;
1969 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
1971 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
1972 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
1973 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
1974 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
1975 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
1976 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
1977 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
1978 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
1979 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
1980 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
1981 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
1982 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
1983 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
1984 default: ERR("Unexpected position mask\n");
1986 for (i = 0; i < numTextures; i++) {
1987 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
1990 return size;
1993 /***********************************************************************
1994 * CalculateTexRect
1996 * Calculates the dimensions of the opengl texture used for blits.
1997 * Handled oversized opengl textures and updates the source rectangle
1998 * accordingly
2000 * Params:
2001 * This: Surface to operate on
2002 * Rect: Requested rectangle
2004 * Returns:
2005 * TRUE if the texture part can be loaded,
2006 * FALSE otherwise
2008 *********************************************************************/
2009 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
2011 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
2012 int x1 = Rect->left, x2 = Rect->right;
2013 int y1 = Rect->top, y2 = Rect->bottom;
2014 GLint maxSize = GL_LIMITS(texture_size);
2016 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2017 Rect->left, Rect->top, Rect->right, Rect->bottom);
2019 /* The sizes might be reversed */
2020 if(Rect->left > Rect->right) {
2021 x1 = Rect->right;
2022 x2 = Rect->left;
2024 if(Rect->top > Rect->bottom) {
2025 y1 = Rect->bottom;
2026 y2 = Rect->top;
2029 /* No oversized texture? This is easy */
2030 if(!(This->Flags & SFLAG_OVERSIZE)) {
2031 /* Which rect from the texture do I need? */
2032 if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
2034 glTexCoord[0] = (float) Rect->left;
2035 glTexCoord[2] = (float) Rect->top;
2036 glTexCoord[1] = (float) Rect->right;
2037 glTexCoord[3] = (float) Rect->bottom;
2038 } else {
2039 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2040 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2041 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2042 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2045 return TRUE;
2046 } else {
2047 /* Check if we can succeed at all */
2048 if( (x2 - x1) > maxSize ||
2049 (y2 - y1) > maxSize ) {
2050 TRACE("Requested rectangle is too large for gl\n");
2051 return FALSE;
2054 /* A part of the texture has to be picked. First, check if
2055 * some texture part is loaded already, if yes try to re-use it.
2056 * If the texture is dirty, or the part can't be used,
2057 * re-position the part to load
2059 if(This->Flags & SFLAG_INTEXTURE) {
2060 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2061 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2062 /* Ok, the rectangle is ok, re-use it */
2063 TRACE("Using existing gl Texture\n");
2064 } else {
2065 /* Rectangle is not ok, dirtify the texture to reload it */
2066 TRACE("Dirtifying texture to force reload\n");
2067 This->Flags &= ~SFLAG_INTEXTURE;
2071 /* Now if we are dirty(no else if!) */
2072 if(!(This->Flags & SFLAG_INTEXTURE)) {
2073 /* Set the new rectangle. Use the following strategy:
2074 * 1) Use as big textures as possible.
2075 * 2) Place the texture part in the way that the requested
2076 * part is in the middle of the texture(well, almost)
2077 * 3) If the texture is moved over the edges of the
2078 * surface, replace it nicely
2079 * 4) If the coord is not limiting the texture size,
2080 * use the whole size
2082 if((This->pow2Width) > maxSize) {
2083 This->glRect.left = x1 - maxSize / 2;
2084 if(This->glRect.left < 0) {
2085 This->glRect.left = 0;
2087 This->glRect.right = This->glRect.left + maxSize;
2088 if(This->glRect.right > This->currentDesc.Width) {
2089 This->glRect.right = This->currentDesc.Width;
2090 This->glRect.left = This->glRect.right - maxSize;
2092 } else {
2093 This->glRect.left = 0;
2094 This->glRect.right = This->pow2Width;
2097 if(This->pow2Height > maxSize) {
2098 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2099 if(This->glRect.top < 0) This->glRect.top = 0;
2100 This->glRect.bottom = This->glRect.left + maxSize;
2101 if(This->glRect.bottom > This->currentDesc.Height) {
2102 This->glRect.bottom = This->currentDesc.Height;
2103 This->glRect.top = This->glRect.bottom - maxSize;
2105 } else {
2106 This->glRect.top = 0;
2107 This->glRect.bottom = This->pow2Height;
2109 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2110 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2113 /* Re-calculate the rect to draw */
2114 Rect->left -= This->glRect.left;
2115 Rect->right -= This->glRect.left;
2116 Rect->top -= This->glRect.top;
2117 Rect->bottom -= This->glRect.top;
2119 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2120 * or the pow2Width / pow2Height of the surface.
2122 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
2123 * as regular GL_TEXTURE_2D.
2125 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2126 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2127 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2128 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2130 return TRUE;
2132 #undef GLINFO_LOCATION
2134 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2135 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2136 #define ARG1 0x01
2137 #define ARG2 0x02
2138 #define ARG0 0x04
2139 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2140 /* undefined */ 0,
2141 /* D3DTOP_DISABLE */ 0,
2142 /* D3DTOP_SELECTARG1 */ ARG1,
2143 /* D3DTOP_SELECTARG2 */ ARG2,
2144 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2145 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2146 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2147 /* D3DTOP_ADD */ ARG1 | ARG2,
2148 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2149 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2150 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2151 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2152 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2153 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2154 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2155 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2156 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2157 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2158 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2159 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2160 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2161 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2162 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2163 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2164 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2165 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2166 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2168 unsigned int i;
2169 DWORD ttff;
2170 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2171 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2173 for(i = 0; i < GL_LIMITS(texture_stages); i++) {
2174 IWineD3DBaseTextureImpl *texture;
2175 settings->op[i].padding = 0;
2176 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2177 settings->op[i].cop = WINED3DTOP_DISABLE;
2178 settings->op[i].aop = WINED3DTOP_DISABLE;
2179 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2180 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2181 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2182 settings->op[i].dst = resultreg;
2183 settings->op[i].tex_type = tex_1d;
2184 settings->op[i].projected = proj_none;
2185 i++;
2186 break;
2189 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2190 if(texture) {
2191 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2192 if(ignore_textype) {
2193 settings->op[i].tex_type = tex_1d;
2194 } else {
2195 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2196 case GL_TEXTURE_1D:
2197 settings->op[i].tex_type = tex_1d;
2198 break;
2199 case GL_TEXTURE_2D:
2200 settings->op[i].tex_type = tex_2d;
2201 break;
2202 case GL_TEXTURE_3D:
2203 settings->op[i].tex_type = tex_3d;
2204 break;
2205 case GL_TEXTURE_CUBE_MAP_ARB:
2206 settings->op[i].tex_type = tex_cube;
2207 break;
2208 case GL_TEXTURE_RECTANGLE_ARB:
2209 settings->op[i].tex_type = tex_rect;
2210 break;
2213 } else {
2214 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2215 settings->op[i].tex_type = tex_1d;
2218 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2219 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2221 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2222 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2223 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2225 if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2226 carg0 = ARG_UNUSED;
2227 carg2 = ARG_UNUSED;
2228 carg1 = WINED3DTA_CURRENT;
2229 cop = WINED3DTOP_SELECTARG1;
2232 if(cop == WINED3DTOP_DOTPRODUCT3) {
2233 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2234 * the color result to the alpha component of the destination
2236 aop = cop;
2237 aarg1 = carg1;
2238 aarg2 = carg2;
2239 aarg0 = carg0;
2240 } else {
2241 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2242 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2243 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2246 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2248 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2250 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2252 IWineD3DSurfaceImpl *surf;
2253 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2255 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2257 if (aop == WINED3DTOP_DISABLE)
2259 aarg1 = WINED3DTA_TEXTURE;
2260 aop = WINED3DTOP_SELECTARG1;
2262 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2264 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2266 aarg2 = WINED3DTA_TEXTURE;
2267 aop = WINED3DTOP_MODULATE;
2269 else aarg1 = WINED3DTA_TEXTURE;
2271 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2273 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2275 aarg1 = WINED3DTA_TEXTURE;
2276 aop = WINED3DTOP_MODULATE;
2278 else aarg2 = WINED3DTA_TEXTURE;
2284 if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2285 aarg0 = ARG_UNUSED;
2286 aarg2 = ARG_UNUSED;
2287 aarg1 = WINED3DTA_CURRENT;
2288 aop = WINED3DTOP_SELECTARG1;
2291 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2292 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2293 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2294 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2295 settings->op[i].projected = proj_count3;
2296 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2297 settings->op[i].projected = proj_count4;
2298 } else {
2299 settings->op[i].projected = proj_none;
2301 } else {
2302 settings->op[i].projected = proj_none;
2305 settings->op[i].cop = cop;
2306 settings->op[i].aop = aop;
2307 settings->op[i].carg0 = carg0;
2308 settings->op[i].carg1 = carg1;
2309 settings->op[i].carg2 = carg2;
2310 settings->op[i].aarg0 = aarg0;
2311 settings->op[i].aarg1 = aarg1;
2312 settings->op[i].aarg2 = aarg2;
2314 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2315 settings->op[i].dst = tempreg;
2316 } else {
2317 settings->op[i].dst = resultreg;
2321 /* Clear unsupported stages */
2322 for(; i < MAX_TEXTURES; i++) {
2323 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2326 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2327 settings->fog = FOG_OFF;
2328 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2329 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2330 settings->fog = FOG_LINEAR;
2331 } else {
2332 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2333 case WINED3DFOG_NONE:
2334 case WINED3DFOG_LINEAR:
2335 settings->fog = FOG_LINEAR;
2336 break;
2337 case WINED3DFOG_EXP:
2338 settings->fog = FOG_EXP;
2339 break;
2340 case WINED3DFOG_EXP2:
2341 settings->fog = FOG_EXP2;
2342 break;
2345 } else {
2346 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2347 case WINED3DFOG_LINEAR:
2348 settings->fog = FOG_LINEAR;
2349 break;
2350 case WINED3DFOG_EXP:
2351 settings->fog = FOG_EXP;
2352 break;
2353 case WINED3DFOG_EXP2:
2354 settings->fog = FOG_EXP2;
2355 break;
2358 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2359 settings->sRGB_write = 1;
2360 } else {
2361 settings->sRGB_write = 0;
2363 if(device->vs_clipping || !use_vs(stateblock)) {
2364 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2365 * the fixed function vertex pipeline is used(which always supports clipplanes)
2367 settings->emul_clipplanes = 0;
2368 } else {
2369 settings->emul_clipplanes = 1;
2372 #undef GLINFO_LOCATION
2374 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2375 const struct ffp_frag_settings *settings)
2377 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2378 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2381 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2383 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2384 * whereas desc points to an extended structure with implementation specific parts. */
2385 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2387 ERR("Failed to insert ffp frag shader.\n");
2391 /* Activates the texture dimension according to the bound D3D texture.
2392 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2393 * Requires the caller to activate the correct unit before
2395 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2396 /* GL locking is done by the caller (state handler) */
2397 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2398 if(stateblock->textures[stage]) {
2399 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2400 case GL_TEXTURE_2D:
2401 glDisable(GL_TEXTURE_3D);
2402 checkGLcall("glDisable(GL_TEXTURE_3D)");
2403 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2404 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2405 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2407 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2408 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2409 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2411 glEnable(GL_TEXTURE_2D);
2412 checkGLcall("glEnable(GL_TEXTURE_2D)");
2413 break;
2414 case GL_TEXTURE_RECTANGLE_ARB:
2415 glDisable(GL_TEXTURE_2D);
2416 checkGLcall("glDisable(GL_TEXTURE_2D)");
2417 glDisable(GL_TEXTURE_3D);
2418 checkGLcall("glDisable(GL_TEXTURE_3D)");
2419 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2420 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2421 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2423 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2424 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2425 break;
2426 case GL_TEXTURE_3D:
2427 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2428 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2429 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2431 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2432 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2433 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2435 glDisable(GL_TEXTURE_2D);
2436 checkGLcall("glDisable(GL_TEXTURE_2D)");
2437 glEnable(GL_TEXTURE_3D);
2438 checkGLcall("glEnable(GL_TEXTURE_3D)");
2439 break;
2440 case GL_TEXTURE_CUBE_MAP_ARB:
2441 glDisable(GL_TEXTURE_2D);
2442 checkGLcall("glDisable(GL_TEXTURE_2D)");
2443 glDisable(GL_TEXTURE_3D);
2444 checkGLcall("glDisable(GL_TEXTURE_3D)");
2445 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2446 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2447 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2449 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2450 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2451 break;
2453 } else {
2454 glEnable(GL_TEXTURE_2D);
2455 checkGLcall("glEnable(GL_TEXTURE_2D)");
2456 glDisable(GL_TEXTURE_3D);
2457 checkGLcall("glDisable(GL_TEXTURE_3D)");
2458 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2459 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2460 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2462 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2463 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2464 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2466 /* Binding textures is done by samplers. A dummy texture will be bound */
2470 /* GL locking is done by the caller (state handler) */
2471 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2472 DWORD sampler = state - STATE_SAMPLER(0);
2473 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2475 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2476 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2477 * will take care of this business
2479 if(mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= GL_LIMITS(textures)) return;
2480 if(sampler >= stateblock->lowest_disabled_stage) return;
2481 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2483 texture_activate_dimensions(sampler, stateblock, context);
2485 #undef GLINFO_LOCATION
2487 void *wined3d_rb_alloc(size_t size)
2489 return HeapAlloc(GetProcessHeap(), 0, size);
2492 void *wined3d_rb_realloc(void *ptr, size_t size)
2494 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
2497 void wined3d_rb_free(void *ptr)
2499 HeapFree(GetProcessHeap(), 0, ptr);
2502 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
2504 const struct ffp_frag_settings *ka = key;
2505 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
2507 return memcmp(ka, kb, sizeof(*ka));
2510 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
2512 wined3d_rb_alloc,
2513 wined3d_rb_realloc,
2514 wined3d_rb_free,
2515 ffp_frag_program_key_compare,
2518 UINT wined3d_log2i(UINT32 x)
2520 static const BYTE l[] =
2522 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2523 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2524 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2525 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2526 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2527 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2528 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2529 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2530 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2531 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2532 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2533 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2534 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2535 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2536 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2537 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2539 UINT32 i;
2541 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];