VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/utils.c@ 22652

Last change on this file since 22652 was 22496, checked in by vboxsync, 15 years ago

crOpenGL: update wine to 1.1.27 and better fix for depthstencil surface refcounting

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette