push cc8bc80451cc24f4d7cf75168b569f0ebfe19547
[wine/hacks.git] / dlls / wined3d / utils.c
blob881736ee42db268f69fa0d5d6df107b1a05b2f65
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, 0,
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(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(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 static BOOL check_fbo_compat(const WineD3D_GL_Info *gl_info, GLint internal_format, GLenum format, GLenum type)
562 GLenum status;
563 GLuint tex;
565 ENTER_GL();
567 while(glGetError());
568 glGenTextures(1, &tex);
569 glBindTexture(GL_TEXTURE_2D, tex);
570 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, 16, 16, 0, format, type, NULL);
571 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
572 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
574 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
576 status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
577 glDeleteTextures(1, &tex);
579 checkGLcall("Framebuffer format check");
581 LEAVE_GL();
583 return status == GL_FRAMEBUFFER_COMPLETE_EXT;
586 static void init_format_fbo_compat_info(WineD3D_GL_Info *gl_info)
588 unsigned int i;
589 GLuint fbo;
591 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
593 GL_EXTCALL(glGenFramebuffersEXT(1, &fbo));
594 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
597 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
599 struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
601 if (!desc->glInternal) continue;
603 if (desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
605 TRACE("Skipping format %s because it's a depth/stencil format.\n",
606 debug_d3dformat(desc->format));
607 continue;
610 if (desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
612 TRACE("Skipping format %s because it's a compressed format.\n",
613 debug_d3dformat(desc->format));
614 continue;
617 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
619 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc->format));
621 /* Check if the default internal format is supported as a frame buffer target, otherwise
622 * fall back to the render target internal.
624 * Try to stick to the standard format if possible, this limits precision differences. */
625 if (check_fbo_compat(gl_info, desc->glInternal, desc->glFormat, desc->glType))
627 TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(desc->format));
628 desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
629 desc->rtInternal = desc->glInternal;
631 else
633 if (!desc->rtInternal)
635 if (desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)
637 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
638 " and no fallback specified.\n", debug_d3dformat(desc->format));
639 desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
641 else
643 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(desc->format));
645 desc->rtInternal = desc->glInternal;
647 else
649 TRACE("Format %s is not supported as FBO color attachment, using rtInternal format as fallback.\n",
650 debug_d3dformat(desc->format));
654 else
656 desc->rtInternal = desc->glInternal;
660 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
662 GL_EXTCALL(glDeleteFramebuffersEXT(1, &fbo));
666 static BOOL init_format_texture_info(WineD3D_GL_Info *gl_info)
668 unsigned int i;
670 for (i = 0; i < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); ++i)
672 int fmt_idx = getFmtIdx(gl_formats_template[i].fmt);
673 struct GlPixelFormatDesc *desc;
675 if (fmt_idx == -1)
677 ERR("Format %s (%#x) not found.\n",
678 debug_d3dformat(gl_formats_template[i].fmt), gl_formats_template[i].fmt);
679 return FALSE;
682 if (!GL_SUPPORT(gl_formats_template[i].extension)) continue;
684 desc = &gl_info->gl_formats[fmt_idx];
685 desc->glInternal = gl_formats_template[i].glInternal;
686 desc->glGammaInternal = gl_formats_template[i].glGammaInternal;
687 desc->rtInternal = gl_formats_template[i].rtInternal;
688 desc->glFormat = gl_formats_template[i].glFormat;
689 desc->glType = gl_formats_template[i].glType;
690 desc->color_fixup = COLOR_FIXUP_IDENTITY;
691 desc->Flags |= gl_formats_template[i].Flags;
692 desc->heightscale = 1.0;
695 return TRUE;
698 static void apply_format_fixups(WineD3D_GL_Info *gl_info)
700 int idx;
702 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
703 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
704 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
706 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
707 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
708 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
710 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
711 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
712 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
714 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
715 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
716 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
718 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
719 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
720 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
722 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
723 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
724 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
725 * the only driver that implements it(fglrx) has a buggy implementation.
727 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
728 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
729 * conversion for this format.
731 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
733 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
734 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
735 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
736 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
737 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
738 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
740 else
742 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
743 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
744 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
745 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
746 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
747 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
750 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
752 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
753 * with each other
755 idx = getFmtIdx(WINED3DFMT_L6V5U5);
756 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
757 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
758 idx = getFmtIdx(WINED3DFMT_X8L8V8U8);
759 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
760 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
761 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
762 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
763 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
765 else
767 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
768 * are converted at surface loading time, but they do not need any modification in
769 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
770 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
774 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC))
776 idx = getFmtIdx(WINED3DFMT_ATI2N);
777 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
778 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
780 else if (GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC))
782 idx = getFmtIdx(WINED3DFMT_ATI2N);
783 gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
784 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
787 if (!GL_SUPPORT(APPLE_YCBCR_422))
789 idx = getFmtIdx(WINED3DFMT_YUY2);
790 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
792 idx = getFmtIdx(WINED3DFMT_UYVY);
793 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
796 idx = getFmtIdx(WINED3DFMT_YV12);
797 gl_info->gl_formats[idx].heightscale = 1.5;
798 gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
800 if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
802 idx = getFmtIdx(WINED3DFMT_A8R8G8B8);
803 gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
806 if (GL_SUPPORT(ARB_HALF_FLOAT_VERTEX))
808 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
809 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
810 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
811 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
813 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
814 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
818 static BOOL init_format_vertex_info(WineD3D_GL_Info *gl_info)
820 unsigned int i;
822 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
824 struct GlPixelFormatDesc *format_desc;
825 int fmt_idx = getFmtIdx(format_vertex_info[i].format);
827 if (fmt_idx == -1)
829 ERR("Format %s (%#x) not found.\n",
830 debug_d3dformat(format_vertex_info[i].format), format_vertex_info[i].format);
831 return FALSE;
834 format_desc = &gl_info->gl_formats[fmt_idx];
835 format_desc->emit_idx = format_vertex_info[i].emit_idx;
836 format_desc->component_count = format_vertex_info[i].component_count;
837 format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
838 format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
839 format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
840 format_desc->component_size = format_vertex_info[i].component_size;
843 return TRUE;
846 BOOL initPixelFormatsNoGL(WineD3D_GL_Info *gl_info)
848 if (!init_format_base_info(gl_info)) return FALSE;
850 if (!init_format_compression_info(gl_info))
852 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
853 return FALSE;
856 return TRUE;
859 BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
861 if (!init_format_base_info(gl_info)) return FALSE;
863 if (!init_format_compression_info(gl_info)) goto fail;
864 if (!init_format_texture_info(gl_info)) goto fail;
865 if (!init_format_vertex_info(gl_info)) goto fail;
867 apply_format_fixups(gl_info);
868 init_format_fbo_compat_info(gl_info);
870 return TRUE;
872 fail:
873 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
874 return FALSE;
877 #undef GLINFO_LOCATION
879 #define GLINFO_LOCATION This->adapter->gl_info
881 const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const WineD3D_GL_Info *gl_info)
883 int idx = getFmtIdx(fmt);
885 if(idx == -1) {
886 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
887 /* Get the caller a valid pointer */
888 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
891 return &gl_info->gl_formats[idx];
894 /*****************************************************************************
895 * Trace formatting of useful values
897 const char* debug_d3dformat(WINED3DFORMAT fmt) {
898 switch (fmt) {
899 #define FMT_TO_STR(fmt) case fmt: return #fmt
900 FMT_TO_STR(WINED3DFMT_UNKNOWN);
901 FMT_TO_STR(WINED3DFMT_R8G8B8);
902 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
903 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
904 FMT_TO_STR(WINED3DFMT_R5G6B5);
905 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
906 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
907 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
908 FMT_TO_STR(WINED3DFMT_R3G3B2);
909 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
910 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
911 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
912 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
913 FMT_TO_STR(WINED3DFMT_A8P8);
914 FMT_TO_STR(WINED3DFMT_P8);
915 FMT_TO_STR(WINED3DFMT_L8);
916 FMT_TO_STR(WINED3DFMT_A8L8);
917 FMT_TO_STR(WINED3DFMT_A4L4);
918 FMT_TO_STR(WINED3DFMT_L6V5U5);
919 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
920 FMT_TO_STR(WINED3DFMT_W11V11U10);
921 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
922 FMT_TO_STR(WINED3DFMT_UYVY);
923 FMT_TO_STR(WINED3DFMT_YUY2);
924 FMT_TO_STR(WINED3DFMT_YV12);
925 FMT_TO_STR(WINED3DFMT_DXT1);
926 FMT_TO_STR(WINED3DFMT_DXT2);
927 FMT_TO_STR(WINED3DFMT_DXT3);
928 FMT_TO_STR(WINED3DFMT_DXT4);
929 FMT_TO_STR(WINED3DFMT_DXT5);
930 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
931 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
932 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
933 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
934 FMT_TO_STR(WINED3DFMT_D32);
935 FMT_TO_STR(WINED3DFMT_D15S1);
936 FMT_TO_STR(WINED3DFMT_D24S8);
937 FMT_TO_STR(WINED3DFMT_D24X8);
938 FMT_TO_STR(WINED3DFMT_D24X4S4);
939 FMT_TO_STR(WINED3DFMT_L16);
940 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
941 FMT_TO_STR(WINED3DFMT_D24FS8);
942 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
943 FMT_TO_STR(WINED3DFMT_CxV8U8);
944 FMT_TO_STR(WINED3DFMT_ATI2N);
945 FMT_TO_STR(WINED3DFMT_NVHU);
946 FMT_TO_STR(WINED3DFMT_NVHS);
947 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
948 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
949 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
950 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
951 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
952 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
953 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
954 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
955 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
956 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
957 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
958 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
959 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
960 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
961 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
962 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
963 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
964 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
965 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
966 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
967 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
968 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
969 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
970 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
971 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
972 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
973 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
974 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
975 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
976 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
977 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
978 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
979 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
980 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
981 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
982 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
983 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
984 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
985 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
986 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
987 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
988 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
989 FMT_TO_STR(WINED3DFMT_R32_UINT);
990 FMT_TO_STR(WINED3DFMT_R32_SINT);
991 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
992 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
993 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
994 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
995 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
996 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
997 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
998 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
999 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1000 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1001 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1002 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1003 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1004 FMT_TO_STR(WINED3DFMT_R16_UINT);
1005 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1006 FMT_TO_STR(WINED3DFMT_R16_SINT);
1007 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1008 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1009 FMT_TO_STR(WINED3DFMT_R8_UINT);
1010 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1011 FMT_TO_STR(WINED3DFMT_R8_SINT);
1012 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1013 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1014 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1015 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1016 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1017 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1018 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1019 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1020 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1021 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1022 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1023 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1024 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1025 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1026 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1027 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1028 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1029 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1030 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1031 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1032 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1033 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1034 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1035 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1036 #undef FMT_TO_STR
1037 default:
1039 char fourcc[5];
1040 fourcc[0] = (char)(fmt);
1041 fourcc[1] = (char)(fmt >> 8);
1042 fourcc[2] = (char)(fmt >> 16);
1043 fourcc[3] = (char)(fmt >> 24);
1044 fourcc[4] = 0;
1045 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
1046 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
1047 else
1048 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
1050 return "unrecognized";
1054 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
1055 switch (devtype) {
1056 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1057 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1058 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1059 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1060 #undef DEVTYPE_TO_STR
1061 default:
1062 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1063 return "unrecognized";
1067 const char *debug_d3dusage(DWORD usage)
1069 char buf[284];
1071 buf[0] = '\0';
1072 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1073 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1074 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1075 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1076 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1077 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1078 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1079 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1080 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1081 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1082 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1083 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1084 #undef WINED3DUSAGE_TO_STR
1085 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1087 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1090 const char *debug_d3dusagequery(DWORD usagequery)
1092 char buf[238];
1094 buf[0] = '\0';
1095 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1096 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1097 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1098 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1099 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1100 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1101 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1102 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1103 #undef WINED3DUSAGEQUERY_TO_STR
1104 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1106 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1109 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1110 switch (method) {
1111 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1112 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1113 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1114 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1115 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1116 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1117 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1118 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1119 #undef WINED3DDECLMETHOD_TO_STR
1120 default:
1121 FIXME("Unrecognized %u declaration method!\n", method);
1122 return "unrecognized";
1126 const char* debug_d3ddeclusage(BYTE usage) {
1127 switch (usage) {
1128 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1129 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1130 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1131 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1132 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1133 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1134 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1135 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1136 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1137 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1138 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1139 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1140 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1141 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1142 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1143 #undef WINED3DDECLUSAGE_TO_STR
1144 default:
1145 FIXME("Unrecognized %u declaration usage!\n", usage);
1146 return "unrecognized";
1150 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1151 switch (res) {
1152 #define RES_TO_STR(res) case res: return #res
1153 RES_TO_STR(WINED3DRTYPE_SURFACE);
1154 RES_TO_STR(WINED3DRTYPE_VOLUME);
1155 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1156 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1157 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1158 RES_TO_STR(WINED3DRTYPE_BUFFER);
1159 #undef RES_TO_STR
1160 default:
1161 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1162 return "unrecognized";
1166 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1167 switch (PrimitiveType) {
1168 #define PRIM_TO_STR(prim) case prim: return #prim
1169 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1170 PRIM_TO_STR(WINED3DPT_POINTLIST);
1171 PRIM_TO_STR(WINED3DPT_LINELIST);
1172 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1173 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1174 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1175 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1176 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1177 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1178 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1179 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1180 #undef PRIM_TO_STR
1181 default:
1182 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1183 return "unrecognized";
1187 const char* debug_d3drenderstate(DWORD state) {
1188 switch (state) {
1189 #define D3DSTATE_TO_STR(u) case u: return #u
1190 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
1191 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1192 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
1193 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1194 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1195 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1196 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1197 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1198 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1199 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1200 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1201 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1202 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1203 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1204 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1205 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1206 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
1207 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
1208 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1209 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1210 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
1211 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1212 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1213 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1214 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1215 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1216 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1217 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1218 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1219 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1220 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1221 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1222 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1223 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1224 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1225 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1226 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1227 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1228 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1229 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1230 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1231 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
1232 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
1233 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
1234 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1235 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1236 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1237 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1238 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1239 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1240 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1241 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1242 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1243 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1244 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1245 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1246 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1247 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1248 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1249 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
1250 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
1251 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
1252 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
1253 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
1254 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
1255 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
1256 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
1257 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
1258 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
1259 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
1260 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
1261 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
1262 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
1263 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
1264 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
1265 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
1266 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
1267 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
1268 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
1269 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
1270 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
1271 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
1272 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
1273 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
1274 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
1275 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
1276 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
1277 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
1278 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
1279 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
1280 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
1281 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1282 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1283 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1284 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1285 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1286 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1287 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1288 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1289 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1290 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1291 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1292 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1293 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1294 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1295 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1296 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1297 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1298 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1299 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1300 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1301 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1302 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1303 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1304 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1305 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1306 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1307 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1308 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1309 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1310 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1311 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1312 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1313 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1314 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1315 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1316 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1317 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1318 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1319 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1320 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1321 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1322 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1323 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1324 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1325 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1326 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1327 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1328 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1329 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1330 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1331 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1332 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1333 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1334 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1335 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1336 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1337 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1338 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1339 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1340 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1341 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1342 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1343 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1344 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1345 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1346 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1347 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1348 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1349 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1350 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1351 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1352 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1353 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1354 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1355 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1356 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1357 #undef D3DSTATE_TO_STR
1358 default:
1359 FIXME("Unrecognized %u render state!\n", state);
1360 return "unrecognized";
1364 const char* debug_d3dsamplerstate(DWORD state) {
1365 switch (state) {
1366 #define D3DSTATE_TO_STR(u) case u: return #u
1367 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1368 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1369 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1370 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1371 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1372 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1373 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1374 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1375 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1376 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1377 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1378 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1379 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1380 #undef D3DSTATE_TO_STR
1381 default:
1382 FIXME("Unrecognized %u sampler state!\n", state);
1383 return "unrecognized";
1387 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1388 switch (filter_type) {
1389 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1390 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1391 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1392 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1393 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1394 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1395 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1396 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1397 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1398 #undef D3DTEXTUREFILTERTYPE_TO_STR
1399 default:
1400 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1401 return "unrecognized";
1405 const char* debug_d3dtexturestate(DWORD state) {
1406 switch (state) {
1407 #define D3DSTATE_TO_STR(u) case u: return #u
1408 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1409 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1410 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1411 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1412 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1413 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1414 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1415 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1416 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1417 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1418 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1419 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1420 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1421 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1422 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1423 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1424 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1425 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1426 #undef D3DSTATE_TO_STR
1427 default:
1428 FIXME("Unrecognized %u texture state!\n", state);
1429 return "unrecognized";
1433 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1434 switch (d3dtop) {
1435 #define D3DTOP_TO_STR(u) case u: return #u
1436 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1437 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1438 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1439 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1440 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1441 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1442 D3DTOP_TO_STR(WINED3DTOP_ADD);
1443 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1444 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1445 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1446 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1447 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1448 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1449 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1450 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1451 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1452 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1453 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1454 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1455 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1456 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1457 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1458 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1459 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1460 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1461 D3DTOP_TO_STR(WINED3DTOP_LERP);
1462 #undef D3DTOP_TO_STR
1463 default:
1464 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1465 return "unrecognized";
1469 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1470 switch (tstype) {
1471 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1472 TSTYPE_TO_STR(WINED3DTS_VIEW);
1473 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1474 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1475 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1476 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1477 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1478 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1479 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1480 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1481 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1482 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1483 #undef TSTYPE_TO_STR
1484 default:
1485 if (tstype > 256 && tstype < 512) {
1486 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1487 return ("WINED3DTS_WORLDMATRIX > 0");
1489 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1490 return "unrecognized";
1494 const char* debug_d3dpool(WINED3DPOOL Pool) {
1495 switch (Pool) {
1496 #define POOL_TO_STR(p) case p: return #p
1497 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1498 POOL_TO_STR(WINED3DPOOL_MANAGED);
1499 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1500 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1501 #undef POOL_TO_STR
1502 default:
1503 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1504 return "unrecognized";
1508 const char *debug_fbostatus(GLenum status) {
1509 switch(status) {
1510 #define FBOSTATUS_TO_STR(u) case u: return #u
1511 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1512 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1513 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1514 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1515 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1516 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1517 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1518 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
1519 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1520 #undef FBOSTATUS_TO_STR
1521 default:
1522 FIXME("Unrecognied FBO status 0x%08x\n", status);
1523 return "unrecognized";
1527 const char *debug_glerror(GLenum error) {
1528 switch(error) {
1529 #define GLERROR_TO_STR(u) case u: return #u
1530 GLERROR_TO_STR(GL_NO_ERROR);
1531 GLERROR_TO_STR(GL_INVALID_ENUM);
1532 GLERROR_TO_STR(GL_INVALID_VALUE);
1533 GLERROR_TO_STR(GL_INVALID_OPERATION);
1534 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1535 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1536 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1537 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1538 #undef GLERROR_TO_STR
1539 default:
1540 FIXME("Unrecognied GL error 0x%08x\n", error);
1541 return "unrecognized";
1545 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1546 switch(basis) {
1547 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1548 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1549 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1550 default: return "unrecognized";
1554 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1555 switch(degree) {
1556 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1557 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1558 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1559 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1560 default: return "unrecognized";
1564 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
1566 switch(source)
1568 #define WINED3D_TO_STR(x) case x: return #x
1569 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1570 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1571 WINED3D_TO_STR(CHANNEL_SOURCE_X);
1572 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1573 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1574 WINED3D_TO_STR(CHANNEL_SOURCE_W);
1575 WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1576 WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1577 #undef WINED3D_TO_STR
1578 default:
1579 FIXME("Unrecognized fixup_channel_source %#x\n", source);
1580 return "unrecognized";
1584 static const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1586 switch(yuv_fixup)
1588 #define WINED3D_TO_STR(x) case x: return #x
1589 WINED3D_TO_STR(YUV_FIXUP_YUY2);
1590 WINED3D_TO_STR(YUV_FIXUP_UYVY);
1591 WINED3D_TO_STR(YUV_FIXUP_YV12);
1592 #undef WINED3D_TO_STR
1593 default:
1594 FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1595 return "unrecognized";
1599 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1601 if (is_yuv_fixup(fixup))
1603 TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1604 return;
1607 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1608 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1609 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1610 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1613 const char *debug_surflocation(DWORD flag) {
1614 char buf[128];
1616 buf[0] = 0;
1617 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
1618 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
1619 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
1620 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
1621 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
1624 /*****************************************************************************
1625 * Useful functions mapping GL <-> D3D values
1627 GLenum StencilOp(DWORD op) {
1628 switch(op) {
1629 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1630 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1631 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1632 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1633 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1634 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1635 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1636 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1637 default:
1638 FIXME("Unrecognized stencil op %d\n", op);
1639 return GL_KEEP;
1643 GLenum CompareFunc(DWORD func) {
1644 switch ((WINED3DCMPFUNC)func) {
1645 case WINED3DCMP_NEVER : return GL_NEVER;
1646 case WINED3DCMP_LESS : return GL_LESS;
1647 case WINED3DCMP_EQUAL : return GL_EQUAL;
1648 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1649 case WINED3DCMP_GREATER : return GL_GREATER;
1650 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1651 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1652 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1653 default:
1654 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1655 return 0;
1659 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1660 if (op == WINED3DTOP_DISABLE) return FALSE;
1661 if (This->stateBlock->textures[stage]) return FALSE;
1663 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1664 && op != WINED3DTOP_SELECTARG2) return TRUE;
1665 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1666 && op != WINED3DTOP_SELECTARG1) return TRUE;
1667 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1668 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1670 return FALSE;
1673 /* Setup this textures matrix according to the texture flags*/
1674 /* GL locking is done by the caller (state handler) */
1675 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
1676 WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
1678 float mat[16];
1680 glMatrixMode(GL_TEXTURE);
1681 checkGLcall("glMatrixMode(GL_TEXTURE)");
1683 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1684 glLoadIdentity();
1685 checkGLcall("glLoadIdentity()");
1686 return;
1689 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1690 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1691 return;
1694 memcpy(mat, smat, 16 * sizeof(float));
1696 if (flags & WINED3DTTFF_PROJECTED) {
1697 if(!ffp_proj_control) {
1698 switch (flags & ~WINED3DTTFF_PROJECTED) {
1699 case WINED3DTTFF_COUNT2:
1700 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1701 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1702 break;
1703 case WINED3DTTFF_COUNT3:
1704 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1705 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1706 break;
1709 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1710 if(!calculatedCoords) {
1711 switch(vtx_fmt)
1713 case WINED3DFMT_R32_FLOAT:
1714 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1715 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1716 * the input value to the transformation will be 0, so the matrix value is irrelevant
1718 mat[12] = mat[4];
1719 mat[13] = mat[5];
1720 mat[14] = mat[6];
1721 mat[15] = mat[7];
1722 break;
1723 case WINED3DFMT_R32G32_FLOAT:
1724 /* See above, just 3rd and 4th coord
1726 mat[12] = mat[8];
1727 mat[13] = mat[9];
1728 mat[14] = mat[10];
1729 mat[15] = mat[11];
1730 break;
1731 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
1732 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
1734 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1735 * into a bad place. The division elimination below will apply to make sure the
1736 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1738 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
1739 break;
1740 default:
1741 FIXME("Unexpected fixed function texture coord input\n");
1744 if(!ffp_proj_control) {
1745 switch (flags & ~WINED3DTTFF_PROJECTED) {
1746 /* case WINED3DTTFF_COUNT1: Won't ever get here */
1747 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
1748 /* OpenGL divides the first 3 vertex coord by the 4th by default,
1749 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
1750 * the 4th coord evaluates to 1.0 to eliminate that.
1752 * If the fixed function pipeline is used, the 4th value remains unused,
1753 * so there is no danger in doing this. With vertex shaders we have a
1754 * problem. Should an app hit that problem, the code here would have to
1755 * check for pixel shaders, and the shader has to undo the default gl divide.
1757 * A more serious problem occurs if the app passes 4 coordinates in, and the
1758 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
1759 * or a replacement shader
1761 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
1766 glLoadMatrixf(mat);
1767 checkGLcall("glLoadMatrixf(mat)");
1769 #undef GLINFO_LOCATION
1771 /* This small helper function is used to convert a bitmask into the number of masked bits */
1772 unsigned int count_bits(unsigned int mask)
1774 unsigned int count;
1775 for (count = 0; mask; ++count)
1777 mask &= mask - 1;
1779 return count;
1782 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
1783 * The later function requires individual color components. */
1784 BOOL getColorBits(const struct GlPixelFormatDesc *format_desc,
1785 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
1787 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
1788 switch(format_desc->format)
1790 case WINED3DFMT_X8R8G8B8:
1791 case WINED3DFMT_R8G8B8:
1792 case WINED3DFMT_A8R8G8B8:
1793 case WINED3DFMT_R8G8B8A8_UNORM:
1794 case WINED3DFMT_A2R10G10B10:
1795 case WINED3DFMT_X1R5G5B5:
1796 case WINED3DFMT_A1R5G5B5:
1797 case WINED3DFMT_R5G6B5:
1798 case WINED3DFMT_X4R4G4B4:
1799 case WINED3DFMT_A4R4G4B4:
1800 case WINED3DFMT_R3G3B2:
1801 case WINED3DFMT_A8P8:
1802 case WINED3DFMT_P8:
1803 break;
1804 default:
1805 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
1806 return FALSE;
1809 *redSize = count_bits(format_desc->red_mask);
1810 *greenSize = count_bits(format_desc->green_mask);
1811 *blueSize = count_bits(format_desc->blue_mask);
1812 *alphaSize = count_bits(format_desc->alpha_mask);
1813 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
1815 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
1816 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
1817 return TRUE;
1820 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
1821 BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize)
1823 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
1824 switch(format_desc->format)
1826 case WINED3DFMT_D16_LOCKABLE:
1827 case WINED3DFMT_D16_UNORM:
1828 case WINED3DFMT_D15S1:
1829 case WINED3DFMT_D24X8:
1830 case WINED3DFMT_D24X4S4:
1831 case WINED3DFMT_D24S8:
1832 case WINED3DFMT_D24FS8:
1833 case WINED3DFMT_D32:
1834 case WINED3DFMT_D32F_LOCKABLE:
1835 break;
1836 default:
1837 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
1838 return FALSE;
1841 *depthSize = format_desc->depth_size;
1842 *stencilSize = format_desc->stencil_size;
1844 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
1845 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
1846 return TRUE;
1849 /* DirectDraw stuff */
1850 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
1851 switch(depth) {
1852 case 8: return WINED3DFMT_P8;
1853 case 15: return WINED3DFMT_X1R5G5B5;
1854 case 16: return WINED3DFMT_R5G6B5;
1855 case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
1856 case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
1857 default: return WINED3DFMT_UNKNOWN;
1861 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
1862 WINED3DMATRIX temp;
1864 /* Now do the multiplication 'by hand'.
1865 I know that all this could be optimised, but this will be done later :-) */
1866 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);
1867 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);
1868 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);
1869 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);
1871 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);
1872 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);
1873 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);
1874 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);
1876 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);
1877 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);
1878 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);
1879 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);
1881 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);
1882 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);
1883 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);
1884 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);
1886 /* And copy the new matrix in the good storage.. */
1887 memcpy(dest, &temp, 16 * sizeof(float));
1890 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
1891 DWORD size = 0;
1892 int i;
1893 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
1895 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
1896 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
1897 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
1898 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
1899 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
1900 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
1901 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
1902 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
1903 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
1904 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
1905 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
1906 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
1907 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
1908 default: ERR("Unexpected position mask\n");
1910 for (i = 0; i < numTextures; i++) {
1911 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
1914 return size;
1917 /***********************************************************************
1918 * CalculateTexRect
1920 * Calculates the dimensions of the opengl texture used for blits.
1921 * Handled oversized opengl textures and updates the source rectangle
1922 * accordingly
1924 * Params:
1925 * This: Surface to operate on
1926 * Rect: Requested rectangle
1928 * Returns:
1929 * TRUE if the texture part can be loaded,
1930 * FALSE otherwise
1932 *********************************************************************/
1933 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
1935 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
1936 int x1 = Rect->left, x2 = Rect->right;
1937 int y1 = Rect->top, y2 = Rect->bottom;
1938 GLint maxSize = GL_LIMITS(texture_size);
1940 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
1941 Rect->left, Rect->top, Rect->right, Rect->bottom);
1943 /* The sizes might be reversed */
1944 if(Rect->left > Rect->right) {
1945 x1 = Rect->right;
1946 x2 = Rect->left;
1948 if(Rect->top > Rect->bottom) {
1949 y1 = Rect->bottom;
1950 y2 = Rect->top;
1953 /* No oversized texture? This is easy */
1954 if(!(This->Flags & SFLAG_OVERSIZE)) {
1955 /* Which rect from the texture do I need? */
1956 if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
1957 glTexCoord[0] = (float) Rect->left;
1958 glTexCoord[2] = (float) Rect->top;
1959 glTexCoord[1] = (float) Rect->right;
1960 glTexCoord[3] = (float) Rect->bottom;
1961 } else {
1962 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
1963 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
1964 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
1965 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
1968 return TRUE;
1969 } else {
1970 /* Check if we can succeed at all */
1971 if( (x2 - x1) > maxSize ||
1972 (y2 - y1) > maxSize ) {
1973 TRACE("Requested rectangle is too large for gl\n");
1974 return FALSE;
1977 /* A part of the texture has to be picked. First, check if
1978 * some texture part is loaded already, if yes try to re-use it.
1979 * If the texture is dirty, or the part can't be used,
1980 * re-position the part to load
1982 if(This->Flags & SFLAG_INTEXTURE) {
1983 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
1984 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
1985 /* Ok, the rectangle is ok, re-use it */
1986 TRACE("Using existing gl Texture\n");
1987 } else {
1988 /* Rectangle is not ok, dirtify the texture to reload it */
1989 TRACE("Dirtifying texture to force reload\n");
1990 This->Flags &= ~SFLAG_INTEXTURE;
1994 /* Now if we are dirty(no else if!) */
1995 if(!(This->Flags & SFLAG_INTEXTURE)) {
1996 /* Set the new rectangle. Use the following strategy:
1997 * 1) Use as big textures as possible.
1998 * 2) Place the texture part in the way that the requested
1999 * part is in the middle of the texture(well, almost)
2000 * 3) If the texture is moved over the edges of the
2001 * surface, replace it nicely
2002 * 4) If the coord is not limiting the texture size,
2003 * use the whole size
2005 if((This->pow2Width) > maxSize) {
2006 This->glRect.left = x1 - maxSize / 2;
2007 if(This->glRect.left < 0) {
2008 This->glRect.left = 0;
2010 This->glRect.right = This->glRect.left + maxSize;
2011 if(This->glRect.right > This->currentDesc.Width) {
2012 This->glRect.right = This->currentDesc.Width;
2013 This->glRect.left = This->glRect.right - maxSize;
2015 } else {
2016 This->glRect.left = 0;
2017 This->glRect.right = This->pow2Width;
2020 if(This->pow2Height > maxSize) {
2021 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2022 if(This->glRect.top < 0) This->glRect.top = 0;
2023 This->glRect.bottom = This->glRect.left + maxSize;
2024 if(This->glRect.bottom > This->currentDesc.Height) {
2025 This->glRect.bottom = This->currentDesc.Height;
2026 This->glRect.top = This->glRect.bottom - maxSize;
2028 } else {
2029 This->glRect.top = 0;
2030 This->glRect.bottom = This->pow2Height;
2032 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2033 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2036 /* Re-calculate the rect to draw */
2037 Rect->left -= This->glRect.left;
2038 Rect->right -= This->glRect.left;
2039 Rect->top -= This->glRect.top;
2040 Rect->bottom -= This->glRect.top;
2042 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2043 * or the pow2Width / pow2Height of the surface.
2045 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
2046 * as regular GL_TEXTURE_2D.
2048 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2049 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2050 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2051 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2053 return TRUE;
2055 #undef GLINFO_LOCATION
2057 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2058 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2059 #define ARG1 0x01
2060 #define ARG2 0x02
2061 #define ARG0 0x04
2062 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2063 /* undefined */ 0,
2064 /* D3DTOP_DISABLE */ 0,
2065 /* D3DTOP_SELECTARG1 */ ARG1,
2066 /* D3DTOP_SELECTARG2 */ ARG2,
2067 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2068 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2069 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2070 /* D3DTOP_ADD */ ARG1 | ARG2,
2071 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2072 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2073 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2074 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2075 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2076 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2077 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2078 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2079 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2080 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2081 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2082 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2083 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2084 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2085 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2086 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2087 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2088 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2089 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2091 unsigned int i;
2092 DWORD ttff;
2093 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2095 for(i = 0; i < GL_LIMITS(texture_stages); i++) {
2096 IWineD3DBaseTextureImpl *texture;
2097 settings->op[i].padding = 0;
2098 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2099 settings->op[i].cop = WINED3DTOP_DISABLE;
2100 settings->op[i].aop = WINED3DTOP_DISABLE;
2101 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2102 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2103 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2104 settings->op[i].dst = resultreg;
2105 settings->op[i].tex_type = tex_1d;
2106 settings->op[i].projected = proj_none;
2107 i++;
2108 break;
2111 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2112 if(texture) {
2113 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2114 if(ignore_textype) {
2115 settings->op[i].tex_type = tex_1d;
2116 } else {
2117 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2118 case GL_TEXTURE_1D:
2119 settings->op[i].tex_type = tex_1d;
2120 break;
2121 case GL_TEXTURE_2D:
2122 settings->op[i].tex_type = tex_2d;
2123 break;
2124 case GL_TEXTURE_3D:
2125 settings->op[i].tex_type = tex_3d;
2126 break;
2127 case GL_TEXTURE_CUBE_MAP_ARB:
2128 settings->op[i].tex_type = tex_cube;
2129 break;
2130 case GL_TEXTURE_RECTANGLE_ARB:
2131 settings->op[i].tex_type = tex_rect;
2132 break;
2135 } else {
2136 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2137 settings->op[i].tex_type = tex_1d;
2140 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2141 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2143 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2144 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2145 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2147 if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
2148 carg1, carg2, carg0)) {
2149 carg0 = ARG_UNUSED;
2150 carg2 = ARG_UNUSED;
2151 carg1 = WINED3DTA_CURRENT;
2152 cop = WINED3DTOP_SELECTARG1;
2155 if(cop == WINED3DTOP_DOTPRODUCT3) {
2156 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2157 * the color result to the alpha component of the destination
2159 aop = cop;
2160 aarg1 = carg1;
2161 aarg2 = carg2;
2162 aarg0 = carg0;
2163 } else {
2164 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2165 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2166 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2169 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2171 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2173 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2175 IWineD3DSurfaceImpl *surf;
2176 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2178 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2180 if (aop == WINED3DTOP_DISABLE)
2182 aarg1 = WINED3DTA_TEXTURE;
2183 aop = WINED3DTOP_SELECTARG1;
2185 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2187 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2189 aarg2 = WINED3DTA_TEXTURE;
2190 aop = WINED3DTOP_MODULATE;
2192 else aarg1 = WINED3DTA_TEXTURE;
2194 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2196 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2198 aarg1 = WINED3DTA_TEXTURE;
2199 aop = WINED3DTOP_MODULATE;
2201 else aarg2 = WINED3DTA_TEXTURE;
2207 if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
2208 aarg1, aarg2, aarg0)) {
2209 aarg0 = ARG_UNUSED;
2210 aarg2 = ARG_UNUSED;
2211 aarg1 = WINED3DTA_CURRENT;
2212 aop = WINED3DTOP_SELECTARG1;
2215 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2216 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2217 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2218 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2219 settings->op[i].projected = proj_count3;
2220 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2221 settings->op[i].projected = proj_count4;
2222 } else {
2223 settings->op[i].projected = proj_none;
2225 } else {
2226 settings->op[i].projected = proj_none;
2229 settings->op[i].cop = cop;
2230 settings->op[i].aop = aop;
2231 settings->op[i].carg0 = carg0;
2232 settings->op[i].carg1 = carg1;
2233 settings->op[i].carg2 = carg2;
2234 settings->op[i].aarg0 = aarg0;
2235 settings->op[i].aarg1 = aarg1;
2236 settings->op[i].aarg2 = aarg2;
2238 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2239 settings->op[i].dst = tempreg;
2240 } else {
2241 settings->op[i].dst = resultreg;
2245 /* Clear unsupported stages */
2246 for(; i < MAX_TEXTURES; i++) {
2247 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2250 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2251 settings->fog = FOG_OFF;
2252 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2253 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2254 settings->fog = FOG_LINEAR;
2255 } else {
2256 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2257 case WINED3DFOG_NONE:
2258 case WINED3DFOG_LINEAR:
2259 settings->fog = FOG_LINEAR;
2260 break;
2261 case WINED3DFOG_EXP:
2262 settings->fog = FOG_EXP;
2263 break;
2264 case WINED3DFOG_EXP2:
2265 settings->fog = FOG_EXP2;
2266 break;
2269 } else {
2270 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2271 case WINED3DFOG_LINEAR:
2272 settings->fog = FOG_LINEAR;
2273 break;
2274 case WINED3DFOG_EXP:
2275 settings->fog = FOG_EXP;
2276 break;
2277 case WINED3DFOG_EXP2:
2278 settings->fog = FOG_EXP2;
2279 break;
2282 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2283 settings->sRGB_write = 1;
2284 } else {
2285 settings->sRGB_write = 0;
2288 #undef GLINFO_LOCATION
2290 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2291 const struct ffp_frag_settings *settings)
2293 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2294 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2297 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2299 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2300 * whereas desc points to an extended structure with implementation specific parts. */
2301 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2303 ERR("Failed to insert ffp frag shader.\n");
2307 /* Activates the texture dimension according to the bound D3D texture.
2308 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2309 * Requires the caller to activate the correct unit before
2311 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2312 /* GL locking is done by the caller (state handler) */
2313 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2314 if(stateblock->textures[stage]) {
2315 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2316 case GL_TEXTURE_2D:
2317 glDisable(GL_TEXTURE_3D);
2318 checkGLcall("glDisable(GL_TEXTURE_3D)");
2319 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2320 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2321 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2323 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2324 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2325 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2327 glEnable(GL_TEXTURE_2D);
2328 checkGLcall("glEnable(GL_TEXTURE_2D)");
2329 break;
2330 case GL_TEXTURE_RECTANGLE_ARB:
2331 glDisable(GL_TEXTURE_2D);
2332 checkGLcall("glDisable(GL_TEXTURE_2D)");
2333 glDisable(GL_TEXTURE_3D);
2334 checkGLcall("glDisable(GL_TEXTURE_3D)");
2335 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2336 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2337 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2339 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2340 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2341 break;
2342 case GL_TEXTURE_3D:
2343 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2344 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2345 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2347 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2348 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2349 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2351 glDisable(GL_TEXTURE_2D);
2352 checkGLcall("glDisable(GL_TEXTURE_2D)");
2353 glEnable(GL_TEXTURE_3D);
2354 checkGLcall("glEnable(GL_TEXTURE_3D)");
2355 break;
2356 case GL_TEXTURE_CUBE_MAP_ARB:
2357 glDisable(GL_TEXTURE_2D);
2358 checkGLcall("glDisable(GL_TEXTURE_2D)");
2359 glDisable(GL_TEXTURE_3D);
2360 checkGLcall("glDisable(GL_TEXTURE_3D)");
2361 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2362 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2363 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2365 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2366 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2367 break;
2369 } else {
2370 glEnable(GL_TEXTURE_2D);
2371 checkGLcall("glEnable(GL_TEXTURE_2D)");
2372 glDisable(GL_TEXTURE_3D);
2373 checkGLcall("glDisable(GL_TEXTURE_3D)");
2374 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2375 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2376 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2378 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2379 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2380 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2382 /* Binding textures is done by samplers. A dummy texture will be bound */
2386 /* GL locking is done by the caller (state handler) */
2387 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2388 DWORD sampler = state - STATE_SAMPLER(0);
2389 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2391 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2392 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2393 * will take care of this business
2395 if(mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= GL_LIMITS(textures)) return;
2396 if(sampler >= stateblock->lowest_disabled_stage) return;
2397 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2399 texture_activate_dimensions(sampler, stateblock, context);
2401 #undef GLINFO_LOCATION
2403 void *wined3d_rb_alloc(size_t size)
2405 return HeapAlloc(GetProcessHeap(), 0, size);
2408 void *wined3d_rb_realloc(void *ptr, size_t size)
2410 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
2413 void wined3d_rb_free(void *ptr)
2415 HeapFree(GetProcessHeap(), 0, ptr);
2418 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
2420 const struct ffp_frag_settings *ka = key;
2421 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
2423 return memcmp(ka, kb, sizeof(*ka));
2426 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
2428 wined3d_rb_alloc,
2429 wined3d_rb_realloc,
2430 wined3d_rb_free,
2431 ffp_frag_program_key_compare,
2434 UINT wined3d_log2i(UINT32 x)
2436 static const BYTE l[] =
2438 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2439 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2440 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2441 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2442 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2443 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2444 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2445 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2446 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2447 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2448 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2449 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2450 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2451 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2452 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2453 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2455 UINT32 i;
2457 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];