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