2 * Utility functions for the WineD3D Library
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2008 Henri Verbeet
9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
10 * Copyright 2009 Henri Verbeet for CodeWeavers
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wined3d_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
32 struct StaticPixelFormatDesc
35 DWORD alphaMask, redMask, greenMask, blueMask;
37 short depthSize, stencilSize;
40 /*****************************************************************************
43 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
44 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
45 * high masks do not fit into the 32 bit values needed for ddraw. It is only
46 * used for ddraw mostly, and to figure out if the format has alpha at all, so
47 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
48 * formats are not usable in 2D rendering because ddraw doesn't support them.
50 static const struct StaticPixelFormatDesc formats[] =
52 /* WINED3DFORMAT alphamask redmask greenmask bluemask bpp depth stencil */
53 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
55 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
56 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
57 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
58 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
59 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
60 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
61 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
62 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
63 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
64 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
65 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
67 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
68 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
69 {WINED3DFMT_R32G32B32_FLOAT, 0x0, 0x0, 0x0, 0x0, 12, 0, 0},
70 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0},
72 {WINED3DFMT_R8G8_SNORM_Cx, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
74 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
75 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
76 {WINED3DFMT_R16G16_SINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
77 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
78 {WINED3DFMT_R16G16B16A16_SINT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
79 /* Palettized formats */
80 {WINED3DFMT_P8_UINT_A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
81 {WINED3DFMT_P8_UINT, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
82 /* Standard ARGB formats. */
83 {WINED3DFMT_B8G8R8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0},
84 {WINED3DFMT_B8G8R8A8_UNORM, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
85 {WINED3DFMT_B8G8R8X8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
86 {WINED3DFMT_B5G6R5_UNORM, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0},
87 {WINED3DFMT_B5G5R5X1_UNORM, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
88 {WINED3DFMT_B5G5R5A1_UNORM, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
89 {WINED3DFMT_B4G4R4A4_UNORM, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
90 {WINED3DFMT_B2G3R3_UNORM, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0},
91 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0},
92 {WINED3DFMT_B2G3R3A8_UNORM, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0},
93 {WINED3DFMT_B4G4R4X4_UNORM, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
94 {WINED3DFMT_R10G10B10A2_UNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
95 {WINED3DFMT_R10G10B10A2_UINT, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
96 {WINED3DFMT_R10G10B10A2_SNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
97 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
98 {WINED3DFMT_R8G8B8A8_UINT, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
99 {WINED3DFMT_R8G8B8X8_UNORM, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
100 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0},
101 {WINED3DFMT_B10G10R10A2_UNORM, 0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0},
102 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0},
104 {WINED3DFMT_L8_UNORM, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
105 {WINED3DFMT_L8A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
106 {WINED3DFMT_L4A4_UNORM, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0},
107 {WINED3DFMT_L16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
108 /* Bump mapping stuff */
109 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
110 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
111 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
112 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
113 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
114 {WINED3DFMT_R10G11B11_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
115 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0},
116 /* Depth stencil formats */
117 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
118 {WINED3DFMT_D32_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
119 {WINED3DFMT_S1_UINT_D15_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 15, 1},
120 {WINED3DFMT_D24_UNORM_S8_UINT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
121 {WINED3DFMT_X8D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 0},
122 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 4},
123 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
124 {WINED3DFMT_D32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
125 {WINED3DFMT_S8_UINT_D24_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
126 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
127 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
128 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
129 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
130 /* Vendor-specific formats */
131 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
132 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
133 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
136 struct wined3d_format_base_flags
138 WINED3DFORMAT format;
142 static const struct wined3d_format_base_flags format_base_flags[] =
144 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
145 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
146 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
147 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
148 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
149 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
150 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
151 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
152 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
153 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
156 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
157 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
158 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
159 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
160 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
161 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
162 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
163 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
164 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
165 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
166 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC},
167 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
168 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
169 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
170 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
171 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
172 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
173 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
174 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
175 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
176 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
177 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 struct wined3d_format_compression_info
182 WINED3DFORMAT format;
185 UINT block_byte_count;
188 static const struct wined3d_format_compression_info format_compression_info[] =
190 {WINED3DFMT_DXT1, 4, 4, 8},
191 {WINED3DFMT_DXT2, 4, 4, 16},
192 {WINED3DFMT_DXT3, 4, 4, 16},
193 {WINED3DFMT_DXT4, 4, 4, 16},
194 {WINED3DFMT_DXT5, 4, 4, 16},
195 {WINED3DFMT_ATI2N, 1, 1, 1},
198 struct wined3d_format_vertex_info
200 WINED3DFORMAT format;
201 enum wined3d_ffp_emit_idx emit_idx;
202 GLint component_count;
205 GLboolean gl_normalized;
206 unsigned int component_size;
209 static const struct wined3d_format_vertex_info format_vertex_info[] =
211 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
212 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
213 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
214 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
215 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
216 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
217 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
218 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
219 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
220 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
221 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
222 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
223 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
224 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
225 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
226 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
227 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
230 struct wined3d_format_texture_info
232 WINED3DFORMAT format;
234 GLint gl_srgb_internal;
235 GLint gl_rt_internal;
238 unsigned int conv_byte_count;
240 GL_SupportedExt extension;
241 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
244 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
249 for(y = 0; y < height; y++)
251 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
252 Source = (const WORD *)(src + y * pitch);
253 for (x = 0; x < width; x++ )
255 short color = (*Source++);
256 unsigned char l = ((color >> 10) & 0xfc);
257 short v = ((color >> 5) & 0x3e);
258 short u = ((color ) & 0x1f);
259 short v_conv = v + 16;
260 short u_conv = u + 16;
262 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
268 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
273 UINT outpitch = (pitch * 3)/2;
275 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
276 * fixed function and shaders without further conversion once the surface is
279 for(y = 0; y < height; y++) {
280 Source = (const WORD *)(src + y * pitch);
281 Dest = dst + y * outpitch;
282 for (x = 0; x < width; x++ ) {
283 short color = (*Source++);
284 unsigned char l = ((color >> 10) & 0xfc);
285 char v = ((color >> 5) & 0x3e);
286 char u = ((color ) & 0x1f);
288 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
289 * and doubles the positive range. Thus shift left only once, gl does the 2nd
290 * shift. GL reads a signed value and converts it into an unsigned value.
292 /* M */ Dest[2] = l << 1;
294 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
295 * from 5 bit values to 8 bit values.
297 /* V */ Dest[1] = v << 3;
298 /* U */ Dest[0] = u << 3;
304 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
309 UINT outpitch = (pitch * 3)/2;
311 for(y = 0; y < height; y++)
313 Source = (const short *)(src + y * pitch);
314 Dest = dst + y * outpitch;
315 for (x = 0; x < width; x++ )
317 long color = (*Source++);
318 /* B */ Dest[0] = 0xff;
319 /* G */ Dest[1] = (color >> 8) + 128; /* V */
320 /* R */ Dest[2] = (color) + 128; /* U */
326 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
332 /* Doesn't work correctly with the fixed function pipeline, but can work in
333 * shaders if the shader is adjusted. (There's no use for this format in gl's
334 * standard fixed function pipeline anyway).
336 for(y = 0; y < height; y++)
338 Source = (const DWORD *)(src + y * pitch);
339 Dest = dst + y * pitch;
340 for (x = 0; x < width; x++ )
342 long color = (*Source++);
343 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
344 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
345 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
351 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
357 /* This implementation works with the fixed function pipeline and shaders
358 * without further modification after converting the surface.
360 for(y = 0; y < height; y++)
362 Source = (const DWORD *)(src + y * pitch);
363 Dest = dst + y * pitch;
364 for (x = 0; x < width; x++ )
366 long color = (*Source++);
367 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
368 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
369 /* U */ Dest[0] = (color & 0xff); /* U */
370 /* I */ Dest[3] = 255; /* X */
376 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
382 for(y = 0; y < height; y++)
384 Source = (const DWORD *)(src + y * pitch);
385 Dest = dst + y * pitch;
386 for (x = 0; x < width; x++ )
388 long color = (*Source++);
389 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
390 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
391 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
392 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
398 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
402 unsigned short *Dest;
403 UINT outpitch = (pitch * 3)/2;
405 for(y = 0; y < height; y++)
407 Source = (const DWORD *)(src + y * pitch);
408 Dest = (unsigned short *) (dst + y * outpitch);
409 for (x = 0; x < width; x++ )
411 DWORD color = (*Source++);
412 /* B */ Dest[0] = 0xffff;
413 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
414 /* R */ Dest[2] = (color ) + 32768; /* U */
420 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
423 UINT outpitch = pitch * 2;
425 for (y = 0; y < height; ++y)
427 const WORD *source = (const WORD *)(src + y * pitch);
428 DWORD *dest = (DWORD *)(dst + y * outpitch);
430 for (x = 0; x < width; ++x)
432 /* The depth data is normalized, so needs to be scaled,
433 * the stencil data isn't. Scale depth data by
434 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
435 WORD d15 = source[x] >> 1;
436 DWORD d24 = (d15 << 9) + (d15 >> 6);
437 dest[x] = (d24 << 8) | (source[x] & 0x1);
442 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
446 for (y = 0; y < height; ++y)
448 const DWORD *source = (const DWORD *)(src + y * pitch);
449 DWORD *dest = (DWORD *)(dst + y * pitch);
451 for (x = 0; x < width; ++x)
453 /* Just need to clear out the X4 part. */
454 dest[x] = source[x] & ~0xf0;
459 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
462 UINT outpitch = pitch * 2;
464 for (y = 0; y < height; ++y)
466 const DWORD *source = (const DWORD *)(src + y * pitch);
467 float *dest_f = (float *)(dst + y * outpitch);
468 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
470 for (x = 0; x < width; ++x)
472 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
473 dest_s[x * 2 + 1] = source[x] & 0xff;
478 static const struct wined3d_format_texture_info format_texture_info[] =
480 /* WINED3DFORMAT internal srgbInternal rtInternal
485 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
486 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
487 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
488 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
491 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
492 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
493 WINED3DFMT_FLAG_FILTERING,
494 WINED3D_GL_EXT_NONE, NULL},
495 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
496 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
497 WINED3DFMT_FLAG_FILTERING,
498 APPLE_YCBCR_422, NULL},
499 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
500 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
501 WINED3DFMT_FLAG_FILTERING,
502 WINED3D_GL_EXT_NONE, NULL},
503 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
504 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
505 WINED3DFMT_FLAG_FILTERING,
506 APPLE_YCBCR_422, NULL},
507 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
508 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
509 WINED3DFMT_FLAG_FILTERING,
510 WINED3D_GL_EXT_NONE, NULL},
511 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
512 GL_RGBA, GL_UNSIGNED_BYTE, 0,
513 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
514 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
515 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
516 GL_RGBA, GL_UNSIGNED_BYTE, 0,
517 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
518 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
519 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
520 GL_RGBA, GL_UNSIGNED_BYTE, 0,
521 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
522 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
523 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
524 GL_RGBA, GL_UNSIGNED_BYTE, 0,
525 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
526 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
527 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
528 GL_RGBA, GL_UNSIGNED_BYTE, 0,
529 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
530 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
532 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
534 WINED3DFMT_FLAG_RENDERTARGET,
535 ARB_TEXTURE_FLOAT, NULL},
536 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
538 WINED3DFMT_FLAG_RENDERTARGET,
539 ARB_TEXTURE_RG, NULL},
540 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
542 WINED3DFMT_FLAG_RENDERTARGET,
543 ARB_TEXTURE_FLOAT, NULL},
544 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
546 WINED3DFMT_FLAG_RENDERTARGET,
547 ARB_TEXTURE_RG, NULL},
548 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
549 GL_RGBA, GL_FLOAT, 0,
550 WINED3DFMT_FLAG_RENDERTARGET,
551 ARB_TEXTURE_FLOAT, NULL},
553 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
554 GL_RED, GL_HALF_FLOAT_ARB, 0,
555 WINED3DFMT_FLAG_RENDERTARGET,
556 ARB_TEXTURE_FLOAT, NULL},
557 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
558 GL_RED, GL_HALF_FLOAT_ARB, 0,
559 WINED3DFMT_FLAG_RENDERTARGET,
560 ARB_TEXTURE_RG, NULL},
561 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
562 GL_RGB, GL_HALF_FLOAT_ARB, 0,
563 WINED3DFMT_FLAG_RENDERTARGET,
564 ARB_TEXTURE_FLOAT, NULL},
565 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
566 GL_RG, GL_HALF_FLOAT_ARB, 0,
567 WINED3DFMT_FLAG_RENDERTARGET,
568 ARB_TEXTURE_RG, NULL},
569 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
570 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
571 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
572 ARB_TEXTURE_FLOAT, NULL},
573 /* Palettized formats */
574 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
575 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
577 ARB_FRAGMENT_PROGRAM, NULL},
578 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
579 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
581 EXT_PALETTED_TEXTURE, NULL},
582 /* Standard ARGB formats */
583 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
584 GL_BGR, GL_UNSIGNED_BYTE, 0,
585 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
586 WINED3D_GL_EXT_NONE, NULL},
587 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
588 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
589 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
590 WINED3D_GL_EXT_NONE, NULL},
591 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
592 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
593 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
594 WINED3D_GL_EXT_NONE, NULL},
595 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
596 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
597 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
598 WINED3D_GL_EXT_NONE, NULL},
599 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
600 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
601 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
602 WINED3D_GL_EXT_NONE, NULL},
603 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
604 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
605 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
606 WINED3D_GL_EXT_NONE, NULL},
607 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
608 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
609 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
610 WINED3D_GL_EXT_NONE, NULL},
611 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
612 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
613 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
614 WINED3D_GL_EXT_NONE, NULL},
615 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
616 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
617 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
618 WINED3D_GL_EXT_NONE, NULL},
619 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
620 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
621 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
622 WINED3D_GL_EXT_NONE, NULL},
623 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
624 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
625 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
626 WINED3D_GL_EXT_NONE, NULL},
627 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
628 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
629 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
630 WINED3D_GL_EXT_NONE, NULL},
631 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
632 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
633 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
634 WINED3D_GL_EXT_NONE, NULL},
635 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
636 GL_RGB, GL_UNSIGNED_SHORT, 0,
637 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
638 WINED3D_GL_EXT_NONE, NULL},
639 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
640 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
641 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
642 WINED3D_GL_EXT_NONE, NULL},
643 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
644 GL_RGBA, GL_UNSIGNED_SHORT, 0,
645 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
646 WINED3D_GL_EXT_NONE, NULL},
648 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
649 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
650 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
651 WINED3D_GL_EXT_NONE, NULL},
652 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
653 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
654 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
655 WINED3D_GL_EXT_NONE, NULL},
656 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
657 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
659 WINED3D_GL_EXT_NONE, NULL},
660 /* Bump mapping stuff */
661 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
662 GL_BGR, GL_UNSIGNED_BYTE, 3,
663 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
664 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm},
665 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
666 GL_DSDT_NV, GL_BYTE, 0,
667 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
668 NV_TEXTURE_SHADER, NULL},
669 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
670 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
671 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
672 WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm},
673 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
674 GL_DSDT_MAG_NV, GL_BYTE, 3,
675 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
676 NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv},
677 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
678 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
679 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
680 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm},
681 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
682 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
683 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
684 NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv},
685 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
686 GL_BGRA, GL_UNSIGNED_BYTE, 4,
687 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
688 WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm},
689 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
691 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
692 NV_TEXTURE_SHADER, NULL},
693 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
694 GL_BGR, GL_UNSIGNED_SHORT, 6,
695 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
696 WINED3D_GL_EXT_NONE, &convert_r16g16_snorm},
697 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
698 GL_HILO_NV, GL_SHORT, 0,
699 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
700 NV_TEXTURE_SHADER, NULL},
701 /* Depth stencil formats */
702 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
703 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
704 WINED3DFMT_FLAG_DEPTH,
705 ARB_DEPTH_TEXTURE, NULL},
706 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
707 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
708 WINED3DFMT_FLAG_DEPTH,
709 ARB_DEPTH_TEXTURE, NULL},
710 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
711 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
712 WINED3DFMT_FLAG_DEPTH,
713 ARB_DEPTH_TEXTURE, NULL},
714 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
715 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
716 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
717 EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm},
718 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
719 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
720 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
721 ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm},
722 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
723 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
724 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
725 ARB_DEPTH_TEXTURE, NULL},
726 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
727 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
728 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
729 EXT_PACKED_DEPTH_STENCIL, NULL},
730 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
731 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
732 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
733 ARB_FRAMEBUFFER_OBJECT, NULL},
734 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
735 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
736 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
737 ARB_DEPTH_TEXTURE, NULL},
738 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
739 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
740 WINED3DFMT_FLAG_DEPTH,
741 ARB_DEPTH_TEXTURE, NULL},
742 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
743 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
744 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
745 EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm},
746 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
747 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
748 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
749 ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm},
750 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
751 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
752 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
753 ARB_DEPTH_TEXTURE, NULL},
754 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
755 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
756 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
757 WINED3D_GL_EXT_NONE, NULL},
758 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
759 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
760 WINED3DFMT_FLAG_DEPTH,
761 ARB_DEPTH_BUFFER_FLOAT, NULL},
762 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
763 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
764 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
765 ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float},
766 /* Vendor-specific formats */
767 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
768 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
770 ATI_TEXTURE_COMPRESSION_3DC, NULL},
771 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, 0,
772 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
774 EXT_TEXTURE_COMPRESSION_RGTC, NULL},
777 static inline int getFmtIdx(WINED3DFORMAT fmt) {
778 /* First check if the format is at the position of its value.
779 * This will catch the argb formats before the loop is entered
781 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
785 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
786 if(formats[i].format == fmt) {
794 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
796 UINT format_count = sizeof(formats) / sizeof(*formats);
799 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->gl_formats));
800 if (!gl_info->gl_formats)
802 ERR("Failed to allocate memory.\n");
806 for (i = 0; i < format_count; ++i)
808 struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
809 desc->format = formats[i].format;
810 desc->red_mask = formats[i].redMask;
811 desc->green_mask = formats[i].greenMask;
812 desc->blue_mask = formats[i].blueMask;
813 desc->alpha_mask = formats[i].alphaMask;
814 desc->byte_count = formats[i].bpp;
815 desc->depth_size = formats[i].depthSize;
816 desc->stencil_size = formats[i].stencilSize;
819 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
821 int fmt_idx = getFmtIdx(format_base_flags[i].format);
825 ERR("Format %s (%#x) not found.\n",
826 debug_d3dformat(format_base_flags[i].format), format_base_flags[i].format);
827 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
831 gl_info->gl_formats[fmt_idx].Flags |= format_base_flags[i].flags;
837 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
841 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
843 struct wined3d_format_desc *format_desc;
844 int fmt_idx = getFmtIdx(format_compression_info[i].format);
848 ERR("Format %s (%#x) not found.\n",
849 debug_d3dformat(format_compression_info[i].format), format_compression_info[i].format);
853 format_desc = &gl_info->gl_formats[fmt_idx];
854 format_desc->block_width = format_compression_info[i].block_width;
855 format_desc->block_height = format_compression_info[i].block_height;
856 format_desc->block_byte_count = format_compression_info[i].block_byte_count;
857 format_desc->Flags |= WINED3DFMT_FLAG_COMPRESSED;
863 /* Context activation is done by the caller. */
864 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format_desc *format_desc)
866 /* Check if the default internal format is supported as a frame buffer
867 * target, otherwise fall back to the render target internal.
869 * Try to stick to the standard format if possible, this limits precision differences. */
878 glGenTextures(1, &tex);
879 glBindTexture(GL_TEXTURE_2D, tex);
881 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glInternal, 16, 16, 0,
882 format_desc->glFormat, format_desc->glType, NULL);
883 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
884 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
886 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
888 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
889 checkGLcall("Framebuffer format check");
891 if (status == GL_FRAMEBUFFER_COMPLETE)
893 TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(format_desc->format));
894 format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
895 format_desc->rtInternal = format_desc->glInternal;
899 if (!format_desc->rtInternal)
901 if (format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)
903 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
904 " and no fallback specified.\n", debug_d3dformat(format_desc->format));
905 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
909 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format_desc->format));
911 format_desc->rtInternal = format_desc->glInternal;
915 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
916 debug_d3dformat(format_desc->format));
920 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
922 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->rtInternal, 16, 16, 0,
923 format_desc->glFormat, format_desc->glType, NULL);
924 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
925 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
927 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
929 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
930 checkGLcall("Framebuffer format check");
932 if (status == GL_FRAMEBUFFER_COMPLETE)
934 TRACE("Format %s rtInternal format is supported as FBO color attachment\n",
935 debug_d3dformat(format_desc->format));
939 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
940 debug_d3dformat(format_desc->format));
941 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
946 if (status == GL_FRAMEBUFFER_COMPLETE && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
950 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
951 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
953 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
954 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
955 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
956 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
957 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
958 checkGLcall("RB attachment");
962 glClear(GL_COLOR_BUFFER_BIT);
963 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
966 TRACE("Format doesn't support post-pixelshader blending.\n");
967 format_desc->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
970 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
971 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
973 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
974 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
975 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
976 checkGLcall("RB cleanup");
980 glDeleteTextures(1, &tex);
985 /* Context activation is done by the caller. */
986 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
991 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
995 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
996 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1001 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1003 struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
1005 if (!desc->glInternal) continue;
1007 if (desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1009 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1010 debug_d3dformat(desc->format));
1014 if (desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
1016 TRACE("Skipping format %s because it's a compressed format.\n",
1017 debug_d3dformat(desc->format));
1021 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1023 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc->format));
1024 check_fbo_compat(gl_info, desc);
1028 desc->rtInternal = desc->glInternal;
1032 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1036 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1042 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1046 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1048 int fmt_idx = getFmtIdx(format_texture_info[i].format);
1049 struct wined3d_format_desc *desc;
1053 ERR("Format %s (%#x) not found.\n",
1054 debug_d3dformat(format_texture_info[i].format), format_texture_info[i].format);
1058 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1060 desc = &gl_info->gl_formats[fmt_idx];
1061 desc->glInternal = format_texture_info[i].gl_internal;
1062 desc->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1063 desc->rtInternal = format_texture_info[i].gl_rt_internal;
1064 desc->glFormat = format_texture_info[i].gl_format;
1065 desc->glType = format_texture_info[i].gl_type;
1066 desc->color_fixup = COLOR_FIXUP_IDENTITY;
1067 desc->Flags |= format_texture_info[i].flags;
1068 desc->heightscale = 1.0f;
1070 /* Texture conversion stuff */
1071 desc->convert = format_texture_info[i].convert;
1072 desc->conv_byte_count = format_texture_info[i].conv_byte_count;
1078 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1080 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1082 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1084 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1086 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1090 /* A context is provided by the caller */
1091 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1093 GLuint tex, fbo, buffer;
1094 const DWORD data[] = {0x00000000, 0xffffffff};
1095 DWORD readback[16 * 1];
1098 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1099 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1100 * falling back to software. If this changes in the future this code will get fooled and
1101 * apps might hit the software path due to incorrectly advertised caps.
1103 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1104 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1105 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1109 while(glGetError());
1111 glGenTextures(1, &buffer);
1112 glBindTexture(GL_TEXTURE_2D, buffer);
1113 memset(readback, 0x7e, sizeof(readback));
1114 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1116 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1117 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1118 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1119 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1121 glGenTextures(1, &tex);
1122 glBindTexture(GL_TEXTURE_2D, tex);
1123 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1126 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1127 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1129 glEnable(GL_TEXTURE_2D);
1131 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1132 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1133 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1134 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1136 glViewport(0, 0, 16, 1);
1137 glDisable(GL_LIGHTING);
1138 glMatrixMode(GL_MODELVIEW);
1140 glMatrixMode(GL_PROJECTION);
1143 glClearColor(0, 1, 0, 0);
1144 glClear(GL_COLOR_BUFFER_BIT);
1146 glBegin(GL_TRIANGLE_STRIP);
1147 glTexCoord2f(0.0, 0.0);
1148 glVertex2f(-1.0f, -1.0f);
1149 glTexCoord2f(1.0, 0.0);
1150 glVertex2f(1.0f, -1.0f);
1151 glTexCoord2f(0.0, 1.0);
1152 glVertex2f(-1.0f, 1.0f);
1153 glTexCoord2f(1.0, 1.0);
1154 glVertex2f(1.0f, 1.0f);
1157 glBindTexture(GL_TEXTURE_2D, buffer);
1158 memset(readback, 0x7f, sizeof(readback));
1159 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1160 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1161 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1163 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1164 readback[6], readback[9]);
1169 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1170 readback[6], readback[9]);
1174 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1175 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1176 glDeleteTextures(1, &tex);
1177 glDeleteTextures(1, &buffer);
1181 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1188 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1190 struct wined3d_format_desc *desc;
1191 unsigned int fmt_idx, i;
1192 WINED3DFORMAT fmts16[] = {
1193 WINED3DFMT_R16_FLOAT,
1194 WINED3DFMT_R16G16_FLOAT,
1195 WINED3DFMT_R16G16B16A16_FLOAT,
1199 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1201 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1202 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1204 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1207 else if (gl_info->limits.glsl_varyings > 44)
1209 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1214 TRACE("Assuming no float16 blending\n");
1220 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1222 fmt_idx = getFmtIdx(fmts16[i]);
1223 gl_info->gl_formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
1229 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1231 fmt_idx = getFmtIdx(fmts16[i]);
1232 desc = &gl_info->gl_formats[fmt_idx];
1233 if(!desc->glInternal) continue; /* Not supported by GL */
1235 filtered = check_filter(gl_info, gl_info->gl_formats[fmt_idx].glInternal);
1238 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1239 desc->Flags |= WINED3DFMT_FLAG_FILTERING;
1243 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1248 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1252 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1253 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1254 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1256 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1257 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1258 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1260 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1261 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1262 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1264 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1265 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1266 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1268 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1269 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1270 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1272 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1273 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1274 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1275 * the only driver that implements it(fglrx) has a buggy implementation.
1277 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1278 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1279 * conversion for this format.
1281 if (!gl_info->supported[NV_TEXTURE_SHADER])
1283 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1284 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1285 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1286 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1287 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1288 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1292 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1293 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1294 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1296 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1297 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1298 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1301 if (!gl_info->supported[NV_TEXTURE_SHADER])
1303 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1306 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1307 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1308 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1309 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1310 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1311 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1312 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1313 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1314 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1318 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1319 * are converted at surface loading time, but they do not need any modification in
1320 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1321 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1325 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1327 idx = getFmtIdx(WINED3DFMT_ATI2N);
1328 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1329 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1331 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1333 idx = getFmtIdx(WINED3DFMT_ATI2N);
1334 gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
1335 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1338 if (!gl_info->supported[APPLE_YCBCR_422])
1340 idx = getFmtIdx(WINED3DFMT_YUY2);
1341 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1343 idx = getFmtIdx(WINED3DFMT_UYVY);
1344 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1347 idx = getFmtIdx(WINED3DFMT_YV12);
1348 gl_info->gl_formats[idx].heightscale = 1.5f;
1349 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1351 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1353 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1354 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1357 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1359 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1360 gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
1363 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1365 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1366 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1367 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1368 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1370 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1371 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1375 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1379 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1381 struct wined3d_format_desc *format_desc;
1382 int fmt_idx = getFmtIdx(format_vertex_info[i].format);
1386 ERR("Format %s (%#x) not found.\n",
1387 debug_d3dformat(format_vertex_info[i].format), format_vertex_info[i].format);
1391 format_desc = &gl_info->gl_formats[fmt_idx];
1392 format_desc->emit_idx = format_vertex_info[i].emit_idx;
1393 format_desc->component_count = format_vertex_info[i].component_count;
1394 format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1395 format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1396 format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
1397 format_desc->component_size = format_vertex_info[i].component_size;
1403 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1405 if (!init_format_base_info(gl_info)) return FALSE;
1407 if (!init_format_compression_info(gl_info))
1409 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1410 gl_info->gl_formats = NULL;
1417 /* Context activation is done by the caller. */
1418 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1420 if (!init_format_base_info(gl_info)) return FALSE;
1422 if (!init_format_compression_info(gl_info)) goto fail;
1423 if (!init_format_texture_info(gl_info)) goto fail;
1424 if (!init_format_vertex_info(gl_info)) goto fail;
1426 apply_format_fixups(gl_info);
1427 init_format_fbo_compat_info(gl_info);
1428 init_format_filter_info(gl_info, vendor);
1433 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1434 gl_info->gl_formats = NULL;
1438 const struct wined3d_format_desc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info)
1440 int idx = getFmtIdx(fmt);
1443 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
1444 /* Get the caller a valid pointer */
1445 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1448 return &gl_info->gl_formats[idx];
1451 /*****************************************************************************
1452 * Trace formatting of useful values
1454 const char* debug_d3dformat(WINED3DFORMAT fmt) {
1456 #define FMT_TO_STR(fmt) case fmt: return #fmt
1457 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1458 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1459 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1460 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1461 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1462 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1463 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1464 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1465 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1466 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1467 FMT_TO_STR(WINED3DFMT_P8_UINT);
1468 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1469 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1470 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1471 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1472 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1473 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1474 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1475 FMT_TO_STR(WINED3DFMT_UYVY);
1476 FMT_TO_STR(WINED3DFMT_YUY2);
1477 FMT_TO_STR(WINED3DFMT_YV12);
1478 FMT_TO_STR(WINED3DFMT_DXT1);
1479 FMT_TO_STR(WINED3DFMT_DXT2);
1480 FMT_TO_STR(WINED3DFMT_DXT3);
1481 FMT_TO_STR(WINED3DFMT_DXT4);
1482 FMT_TO_STR(WINED3DFMT_DXT5);
1483 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1484 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1485 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1486 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1487 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1488 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1489 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1490 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1491 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1492 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1493 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1494 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1495 FMT_TO_STR(WINED3DFMT_ATI2N);
1496 FMT_TO_STR(WINED3DFMT_NVHU);
1497 FMT_TO_STR(WINED3DFMT_NVHS);
1498 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1499 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1500 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1501 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1502 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1503 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1504 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1505 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1506 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1507 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1508 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1509 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1510 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1511 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1512 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1513 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1514 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1515 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1516 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1517 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1518 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1519 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1520 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1521 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1522 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1523 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1524 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1525 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1526 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1527 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1528 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1529 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1530 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1531 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1532 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1533 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1534 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1535 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1536 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1537 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1538 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1539 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1540 FMT_TO_STR(WINED3DFMT_R32_UINT);
1541 FMT_TO_STR(WINED3DFMT_R32_SINT);
1542 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1543 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1544 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1545 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1546 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1547 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1548 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1549 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1550 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1551 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1552 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1553 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1554 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1555 FMT_TO_STR(WINED3DFMT_R16_UINT);
1556 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1557 FMT_TO_STR(WINED3DFMT_R16_SINT);
1558 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1559 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1560 FMT_TO_STR(WINED3DFMT_R8_UINT);
1561 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1562 FMT_TO_STR(WINED3DFMT_R8_SINT);
1563 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1564 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1565 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1566 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1567 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1568 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1569 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1570 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1571 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1572 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1573 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1574 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1575 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1576 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1577 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1578 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1579 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1580 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1581 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1582 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1583 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1584 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1585 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1586 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1591 fourcc[0] = (char)(fmt);
1592 fourcc[1] = (char)(fmt >> 8);
1593 fourcc[2] = (char)(fmt >> 16);
1594 fourcc[3] = (char)(fmt >> 24);
1596 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
1597 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
1599 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
1601 return "unrecognized";
1605 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
1607 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1608 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1609 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1610 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1611 #undef DEVTYPE_TO_STR
1613 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1614 return "unrecognized";
1618 const char *debug_d3dusage(DWORD usage)
1623 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1624 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1625 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1626 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1627 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1628 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1629 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1630 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1631 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1632 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1633 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1634 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1635 #undef WINED3DUSAGE_TO_STR
1636 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1638 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1641 const char *debug_d3dusagequery(DWORD usagequery)
1646 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1647 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1648 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1649 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1650 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1651 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1652 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1653 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1654 #undef WINED3DUSAGEQUERY_TO_STR
1655 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1657 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1660 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1662 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1663 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1664 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1665 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1666 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1667 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1668 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1669 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1670 #undef WINED3DDECLMETHOD_TO_STR
1672 FIXME("Unrecognized %u declaration method!\n", method);
1673 return "unrecognized";
1677 const char* debug_d3ddeclusage(BYTE usage) {
1679 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1680 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1681 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1682 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1683 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1684 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1685 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1686 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1687 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1688 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1689 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1690 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1691 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1692 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1693 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1694 #undef WINED3DDECLUSAGE_TO_STR
1696 FIXME("Unrecognized %u declaration usage!\n", usage);
1697 return "unrecognized";
1701 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1703 #define RES_TO_STR(res) case res: return #res
1704 RES_TO_STR(WINED3DRTYPE_SURFACE);
1705 RES_TO_STR(WINED3DRTYPE_VOLUME);
1706 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1707 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1708 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1709 RES_TO_STR(WINED3DRTYPE_BUFFER);
1712 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1713 return "unrecognized";
1717 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1718 switch (PrimitiveType) {
1719 #define PRIM_TO_STR(prim) case prim: return #prim
1720 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1721 PRIM_TO_STR(WINED3DPT_POINTLIST);
1722 PRIM_TO_STR(WINED3DPT_LINELIST);
1723 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1724 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1725 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1726 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1727 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1728 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1729 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1730 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1733 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1734 return "unrecognized";
1738 const char* debug_d3drenderstate(DWORD state) {
1740 #define D3DSTATE_TO_STR(u) case u: return #u
1741 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1742 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1743 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1744 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1745 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1746 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1747 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1748 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1749 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1750 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1751 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1752 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1753 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1754 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1755 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1756 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1757 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1758 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1759 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1760 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1761 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1762 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1763 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1764 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1765 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1766 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1767 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1768 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1769 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1770 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1771 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1772 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1773 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1774 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1775 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1776 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1777 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1778 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1779 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1780 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1781 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1782 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1783 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1784 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1785 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1786 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1787 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1788 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1789 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1790 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1791 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1792 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1793 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1794 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1795 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1796 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1797 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1798 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1799 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1800 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1801 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1802 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1803 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1804 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1805 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1806 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1807 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1808 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1809 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1810 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1811 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1812 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1813 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1814 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1815 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1816 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1817 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1818 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1819 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1820 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1821 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1822 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1823 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1824 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1825 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1826 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1827 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1828 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1829 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1830 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1831 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1832 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1833 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1834 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1835 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1836 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1837 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1838 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1839 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1840 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1841 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1842 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1843 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1844 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1845 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1846 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1847 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1848 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1849 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1850 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1851 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1852 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1853 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1854 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1855 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1856 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1857 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1858 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1859 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1860 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1861 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1862 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1863 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1864 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1865 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1866 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1867 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1868 #undef D3DSTATE_TO_STR
1870 FIXME("Unrecognized %u render state!\n", state);
1871 return "unrecognized";
1875 const char* debug_d3dsamplerstate(DWORD state) {
1877 #define D3DSTATE_TO_STR(u) case u: return #u
1878 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1879 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1880 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1881 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1882 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1883 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1884 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1885 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1886 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1887 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1888 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1889 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1890 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1891 #undef D3DSTATE_TO_STR
1893 FIXME("Unrecognized %u sampler state!\n", state);
1894 return "unrecognized";
1898 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1899 switch (filter_type) {
1900 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1901 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1902 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1903 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1904 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1905 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1906 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1907 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1908 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1909 #undef D3DTEXTUREFILTERTYPE_TO_STR
1911 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1912 return "unrecognized";
1916 const char* debug_d3dtexturestate(DWORD state) {
1918 #define D3DSTATE_TO_STR(u) case u: return #u
1919 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1920 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1921 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1922 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1923 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1924 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1925 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1926 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1927 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1928 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1929 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1930 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1931 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1932 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1933 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1934 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1935 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1936 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1937 #undef D3DSTATE_TO_STR
1939 FIXME("Unrecognized %u texture state!\n", state);
1940 return "unrecognized";
1944 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1946 #define D3DTOP_TO_STR(u) case u: return #u
1947 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1948 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1949 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1950 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1951 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1952 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1953 D3DTOP_TO_STR(WINED3DTOP_ADD);
1954 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1955 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1956 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1957 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1958 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1959 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1960 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1961 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1962 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1963 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1964 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1965 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1966 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1967 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1968 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1969 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1970 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1971 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1972 D3DTOP_TO_STR(WINED3DTOP_LERP);
1973 #undef D3DTOP_TO_STR
1975 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1976 return "unrecognized";
1980 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1982 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1983 TSTYPE_TO_STR(WINED3DTS_VIEW);
1984 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1985 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1986 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1987 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1988 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1989 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1990 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1991 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1992 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1993 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1994 #undef TSTYPE_TO_STR
1996 if (tstype > 256 && tstype < 512) {
1997 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1998 return ("WINED3DTS_WORLDMATRIX > 0");
2000 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2001 return "unrecognized";
2005 const char *debug_d3dstate(DWORD state)
2007 if (STATE_IS_RENDER(state))
2008 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2009 if (STATE_IS_TEXTURESTAGE(state))
2011 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2012 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2013 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2014 texture_stage, debug_d3dtexturestate(texture_state));
2016 if (STATE_IS_SAMPLER(state))
2017 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2018 if (STATE_IS_PIXELSHADER(state))
2019 return "STATE_PIXELSHADER";
2020 if (STATE_IS_TRANSFORM(state))
2021 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2022 if (STATE_IS_STREAMSRC(state))
2023 return "STATE_STREAMSRC";
2024 if (STATE_IS_INDEXBUFFER(state))
2025 return "STATE_INDEXBUFFER";
2026 if (STATE_IS_VDECL(state))
2027 return "STATE_VDECL";
2028 if (STATE_IS_VSHADER(state))
2029 return "STATE_VSHADER";
2030 if (STATE_IS_VIEWPORT(state))
2031 return "STATE_VIEWPORT";
2032 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2033 return "STATE_VERTEXSHADERCONSTANT";
2034 if (STATE_IS_PIXELSHADERCONSTANT(state))
2035 return "STATE_PIXELSHADERCONSTANT";
2036 if (STATE_IS_ACTIVELIGHT(state))
2037 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2038 if (STATE_IS_SCISSORRECT(state))
2039 return "STATE_SCISSORRECT";
2040 if (STATE_IS_CLIPPLANE(state))
2041 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2042 if (STATE_IS_MATERIAL(state))
2043 return "STATE_MATERIAL";
2044 if (STATE_IS_FRONTFACE(state))
2045 return "STATE_FRONTFACE";
2047 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2050 const char* debug_d3dpool(WINED3DPOOL Pool) {
2052 #define POOL_TO_STR(p) case p: return #p
2053 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2054 POOL_TO_STR(WINED3DPOOL_MANAGED);
2055 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2056 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2059 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
2060 return "unrecognized";
2064 const char *debug_fbostatus(GLenum status) {
2066 #define FBOSTATUS_TO_STR(u) case u: return #u
2067 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2068 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2069 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2070 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2071 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2072 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2073 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2074 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2075 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2076 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2077 #undef FBOSTATUS_TO_STR
2079 FIXME("Unrecognied FBO status 0x%08x\n", status);
2080 return "unrecognized";
2084 const char *debug_glerror(GLenum error) {
2086 #define GLERROR_TO_STR(u) case u: return #u
2087 GLERROR_TO_STR(GL_NO_ERROR);
2088 GLERROR_TO_STR(GL_INVALID_ENUM);
2089 GLERROR_TO_STR(GL_INVALID_VALUE);
2090 GLERROR_TO_STR(GL_INVALID_OPERATION);
2091 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2092 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2093 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2094 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2095 #undef GLERROR_TO_STR
2097 FIXME("Unrecognied GL error 0x%08x\n", error);
2098 return "unrecognized";
2102 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2104 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2105 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2106 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2107 default: return "unrecognized";
2111 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2113 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2114 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2115 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2116 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2117 default: return "unrecognized";
2121 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2125 #define WINED3D_TO_STR(x) case x: return #x
2126 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2127 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2128 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2129 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2130 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2131 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2132 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2133 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2134 #undef WINED3D_TO_STR
2136 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2137 return "unrecognized";
2141 static const char *debug_complex_fixup(enum complex_fixup fixup)
2145 #define WINED3D_TO_STR(x) case x: return #x
2146 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2147 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2148 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2149 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2150 #undef WINED3D_TO_STR
2152 FIXME("Unrecognized complex fixup %#x\n", fixup);
2153 return "unrecognized";
2157 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2159 if (is_complex_fixup(fixup))
2161 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2165 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2166 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2167 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2168 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2171 const char *debug_surflocation(DWORD flag) {
2175 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2176 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2177 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2178 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2179 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2182 /*****************************************************************************
2183 * Useful functions mapping GL <-> D3D values
2185 GLenum StencilOp(DWORD op) {
2187 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2188 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2189 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2190 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2191 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2192 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2193 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2194 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2196 FIXME("Unrecognized stencil op %d\n", op);
2201 GLenum CompareFunc(DWORD func) {
2202 switch ((WINED3DCMPFUNC)func) {
2203 case WINED3DCMP_NEVER : return GL_NEVER;
2204 case WINED3DCMP_LESS : return GL_LESS;
2205 case WINED3DCMP_EQUAL : return GL_EQUAL;
2206 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2207 case WINED3DCMP_GREATER : return GL_GREATER;
2208 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2209 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2210 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2212 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2217 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
2218 if (op == WINED3DTOP_DISABLE) return FALSE;
2219 if (This->stateBlock->textures[stage]) return FALSE;
2221 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2222 && op != WINED3DTOP_SELECTARG2) return TRUE;
2223 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2224 && op != WINED3DTOP_SELECTARG1) return TRUE;
2225 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2226 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2231 /* Setup this textures matrix according to the texture flags*/
2232 /* GL locking is done by the caller (state handler) */
2233 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2234 WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
2238 glMatrixMode(GL_TEXTURE);
2239 checkGLcall("glMatrixMode(GL_TEXTURE)");
2241 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2243 checkGLcall("glLoadIdentity()");
2247 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2248 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2252 memcpy(mat, smat, 16 * sizeof(float));
2254 if (flags & WINED3DTTFF_PROJECTED) {
2255 if(!ffp_proj_control) {
2256 switch (flags & ~WINED3DTTFF_PROJECTED) {
2257 case WINED3DTTFF_COUNT2:
2258 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2259 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2261 case WINED3DTTFF_COUNT3:
2262 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2263 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2267 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2268 if(!calculatedCoords) {
2271 case WINED3DFMT_R32_FLOAT:
2272 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2273 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2274 * the input value to the transformation will be 0, so the matrix value is irrelevant
2281 case WINED3DFMT_R32G32_FLOAT:
2282 /* See above, just 3rd and 4th coord
2289 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2290 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2292 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2293 * into a bad place. The division elimination below will apply to make sure the
2294 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2296 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2299 FIXME("Unexpected fixed function texture coord input\n");
2302 if(!ffp_proj_control) {
2303 switch (flags & ~WINED3DTTFF_PROJECTED) {
2304 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2305 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2306 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2307 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2308 * the 4th coord evaluates to 1.0 to eliminate that.
2310 * If the fixed function pipeline is used, the 4th value remains unused,
2311 * so there is no danger in doing this. With vertex shaders we have a
2312 * problem. Should an app hit that problem, the code here would have to
2313 * check for pixel shaders, and the shader has to undo the default gl divide.
2315 * A more serious problem occurs if the app passes 4 coordinates in, and the
2316 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2317 * or a replacement shader
2319 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2325 checkGLcall("glLoadMatrixf(mat)");
2328 /* This small helper function is used to convert a bitmask into the number of masked bits */
2329 unsigned int count_bits(unsigned int mask)
2332 for (count = 0; mask; ++count)
2339 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2340 * The later function requires individual color components. */
2341 BOOL getColorBits(const struct wined3d_format_desc *format_desc,
2342 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2344 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2345 switch(format_desc->format)
2347 case WINED3DFMT_B8G8R8X8_UNORM:
2348 case WINED3DFMT_B8G8R8_UNORM:
2349 case WINED3DFMT_B8G8R8A8_UNORM:
2350 case WINED3DFMT_R8G8B8A8_UNORM:
2351 case WINED3DFMT_B10G10R10A2_UNORM:
2352 case WINED3DFMT_B5G5R5X1_UNORM:
2353 case WINED3DFMT_B5G5R5A1_UNORM:
2354 case WINED3DFMT_B5G6R5_UNORM:
2355 case WINED3DFMT_B4G4R4X4_UNORM:
2356 case WINED3DFMT_B4G4R4A4_UNORM:
2357 case WINED3DFMT_B2G3R3_UNORM:
2358 case WINED3DFMT_P8_UINT_A8_UNORM:
2359 case WINED3DFMT_P8_UINT:
2362 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
2366 *redSize = count_bits(format_desc->red_mask);
2367 *greenSize = count_bits(format_desc->green_mask);
2368 *blueSize = count_bits(format_desc->blue_mask);
2369 *alphaSize = count_bits(format_desc->alpha_mask);
2370 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2372 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
2373 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
2377 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2378 BOOL getDepthStencilBits(const struct wined3d_format_desc *format_desc, short *depthSize, short *stencilSize)
2380 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2381 switch(format_desc->format)
2383 case WINED3DFMT_D16_LOCKABLE:
2384 case WINED3DFMT_D16_UNORM:
2385 case WINED3DFMT_S1_UINT_D15_UNORM:
2386 case WINED3DFMT_X8D24_UNORM:
2387 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2388 case WINED3DFMT_D24_UNORM_S8_UINT:
2389 case WINED3DFMT_S8_UINT_D24_FLOAT:
2390 case WINED3DFMT_D32_UNORM:
2391 case WINED3DFMT_D32_FLOAT:
2394 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
2398 *depthSize = format_desc->depth_size;
2399 *stencilSize = format_desc->stencil_size;
2401 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
2402 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
2406 DWORD color_convert_argb_to_fmt(DWORD color, WINED3DFORMAT destfmt)
2408 unsigned int r, g, b, a;
2411 if (destfmt == WINED3DFMT_B8G8R8A8_UNORM
2412 || destfmt == WINED3DFMT_B8G8R8X8_UNORM
2413 || destfmt == WINED3DFMT_B8G8R8_UNORM)
2416 TRACE("Converting color %08x to format %s\n", color, debug_d3dformat(destfmt));
2418 a = (color & 0xff000000) >> 24;
2419 r = (color & 0x00ff0000) >> 16;
2420 g = (color & 0x0000ff00) >> 8;
2421 b = (color & 0x000000ff) >> 0;
2425 case WINED3DFMT_B5G6R5_UNORM:
2426 if(r == 0xff && g == 0xff && b == 0xff) return 0xffff;
2433 TRACE("Returning %08x\n", ret);
2436 case WINED3DFMT_B5G5R5X1_UNORM:
2437 case WINED3DFMT_B5G5R5A1_UNORM:
2446 TRACE("Returning %08x\n", ret);
2449 case WINED3DFMT_A8_UNORM:
2450 TRACE("Returning %08x\n", a);
2453 case WINED3DFMT_B4G4R4X4_UNORM:
2454 case WINED3DFMT_B4G4R4A4_UNORM:
2463 TRACE("Returning %08x\n", ret);
2466 case WINED3DFMT_B2G3R3_UNORM:
2473 TRACE("Returning %08x\n", ret);
2476 case WINED3DFMT_R8G8B8X8_UNORM:
2477 case WINED3DFMT_R8G8B8A8_UNORM:
2482 TRACE("Returning %08x\n", ret);
2485 case WINED3DFMT_B10G10R10A2_UNORM:
2487 r = (r * 1024) / 256;
2488 g = (g * 1024) / 256;
2489 b = (b * 1024) / 256;
2494 TRACE("Returning %08x\n", ret);
2497 case WINED3DFMT_R10G10B10A2_UNORM:
2499 r = (r * 1024) / 256;
2500 g = (g * 1024) / 256;
2501 b = (b * 1024) / 256;
2506 TRACE("Returning %08x\n", ret);
2510 FIXME("Add a COLORFILL conversion for format %s\n", debug_d3dformat(destfmt));
2515 /* DirectDraw stuff */
2516 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2518 case 8: return WINED3DFMT_P8_UINT;
2519 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2520 case 16: return WINED3DFMT_B5G6R5_UNORM;
2521 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2522 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2523 default: return WINED3DFMT_UNKNOWN;
2527 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2530 /* Now do the multiplication 'by hand'.
2531 I know that all this could be optimised, but this will be done later :-) */
2532 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);
2533 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);
2534 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);
2535 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);
2537 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);
2538 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);
2539 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);
2540 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);
2542 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);
2543 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);
2544 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);
2545 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);
2547 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);
2548 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);
2549 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);
2550 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);
2552 /* And copy the new matrix in the good storage.. */
2553 memcpy(dest, &temp, 16 * sizeof(float));
2556 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2559 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2561 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2562 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2563 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2564 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2565 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2566 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2567 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2568 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2569 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2570 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2571 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2572 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2573 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2574 default: ERR("Unexpected position mask\n");
2576 for (i = 0; i < numTextures; i++) {
2577 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2583 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2587 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2589 /* D3DTOP_DISABLE */ 0,
2590 /* D3DTOP_SELECTARG1 */ ARG1,
2591 /* D3DTOP_SELECTARG2 */ ARG2,
2592 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2593 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2594 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2595 /* D3DTOP_ADD */ ARG1 | ARG2,
2596 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2597 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2598 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2599 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2600 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2601 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2602 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2603 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2604 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2605 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2606 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2607 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2608 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2609 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2610 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2611 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2612 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2613 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2614 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2618 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2619 IWineD3DDeviceImpl *device = stateblock->device;
2620 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2622 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2624 IWineD3DBaseTextureImpl *texture;
2625 settings->op[i].padding = 0;
2626 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2627 settings->op[i].cop = WINED3DTOP_DISABLE;
2628 settings->op[i].aop = WINED3DTOP_DISABLE;
2629 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2630 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2631 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2632 settings->op[i].dst = resultreg;
2633 settings->op[i].tex_type = tex_1d;
2634 settings->op[i].projected = proj_none;
2639 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2641 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2642 if(ignore_textype) {
2643 settings->op[i].tex_type = tex_1d;
2645 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2647 settings->op[i].tex_type = tex_1d;
2650 settings->op[i].tex_type = tex_2d;
2653 settings->op[i].tex_type = tex_3d;
2655 case GL_TEXTURE_CUBE_MAP_ARB:
2656 settings->op[i].tex_type = tex_cube;
2658 case GL_TEXTURE_RECTANGLE_ARB:
2659 settings->op[i].tex_type = tex_rect;
2664 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2665 settings->op[i].tex_type = tex_1d;
2668 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2669 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2671 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2672 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2673 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2675 if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2678 carg1 = WINED3DTA_CURRENT;
2679 cop = WINED3DTOP_SELECTARG1;
2682 if(cop == WINED3DTOP_DOTPRODUCT3) {
2683 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2684 * the color result to the alpha component of the destination
2691 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2692 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2693 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2696 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2698 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2700 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2702 IWineD3DSurfaceImpl *surf;
2703 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2705 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2707 if (aop == WINED3DTOP_DISABLE)
2709 aarg1 = WINED3DTA_TEXTURE;
2710 aop = WINED3DTOP_SELECTARG1;
2712 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2714 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2716 aarg2 = WINED3DTA_TEXTURE;
2717 aop = WINED3DTOP_MODULATE;
2719 else aarg1 = WINED3DTA_TEXTURE;
2721 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2723 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2725 aarg1 = WINED3DTA_TEXTURE;
2726 aop = WINED3DTOP_MODULATE;
2728 else aarg2 = WINED3DTA_TEXTURE;
2734 if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2737 aarg1 = WINED3DTA_CURRENT;
2738 aop = WINED3DTOP_SELECTARG1;
2741 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2742 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2743 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2744 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2745 settings->op[i].projected = proj_count3;
2746 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2747 settings->op[i].projected = proj_count4;
2749 settings->op[i].projected = proj_none;
2752 settings->op[i].projected = proj_none;
2755 settings->op[i].cop = cop;
2756 settings->op[i].aop = aop;
2757 settings->op[i].carg0 = carg0;
2758 settings->op[i].carg1 = carg1;
2759 settings->op[i].carg2 = carg2;
2760 settings->op[i].aarg0 = aarg0;
2761 settings->op[i].aarg1 = aarg1;
2762 settings->op[i].aarg2 = aarg2;
2764 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2765 settings->op[i].dst = tempreg;
2767 settings->op[i].dst = resultreg;
2771 /* Clear unsupported stages */
2772 for(; i < MAX_TEXTURES; i++) {
2773 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2776 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2777 settings->fog = FOG_OFF;
2778 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2779 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2780 settings->fog = FOG_LINEAR;
2782 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2783 case WINED3DFOG_NONE:
2784 case WINED3DFOG_LINEAR:
2785 settings->fog = FOG_LINEAR;
2787 case WINED3DFOG_EXP:
2788 settings->fog = FOG_EXP;
2790 case WINED3DFOG_EXP2:
2791 settings->fog = FOG_EXP2;
2796 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2797 case WINED3DFOG_LINEAR:
2798 settings->fog = FOG_LINEAR;
2800 case WINED3DFOG_EXP:
2801 settings->fog = FOG_EXP;
2803 case WINED3DFOG_EXP2:
2804 settings->fog = FOG_EXP2;
2808 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2809 settings->sRGB_write = 1;
2811 settings->sRGB_write = 0;
2813 if(device->vs_clipping || !use_vs(stateblock) || !stateblock->renderState[WINED3DRS_CLIPPING] ||
2814 !stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
2815 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2816 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2817 * if no clipplane is enabled
2819 settings->emul_clipplanes = 0;
2821 settings->emul_clipplanes = 1;
2825 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2826 const struct ffp_frag_settings *settings)
2828 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2829 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2832 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2834 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2835 * whereas desc points to an extended structure with implementation specific parts. */
2836 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2838 ERR("Failed to insert ffp frag shader.\n");
2842 /* Activates the texture dimension according to the bound D3D texture.
2843 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2844 * Requires the caller to activate the correct unit before
2846 /* GL locking is done by the caller (state handler) */
2847 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2849 const struct wined3d_gl_info *gl_info = context->gl_info;
2851 if (stateblock->textures[stage])
2853 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2855 glDisable(GL_TEXTURE_3D);
2856 checkGLcall("glDisable(GL_TEXTURE_3D)");
2857 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2859 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2860 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2862 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2864 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2865 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2867 glEnable(GL_TEXTURE_2D);
2868 checkGLcall("glEnable(GL_TEXTURE_2D)");
2870 case GL_TEXTURE_RECTANGLE_ARB:
2871 glDisable(GL_TEXTURE_2D);
2872 checkGLcall("glDisable(GL_TEXTURE_2D)");
2873 glDisable(GL_TEXTURE_3D);
2874 checkGLcall("glDisable(GL_TEXTURE_3D)");
2875 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2877 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2878 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2880 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2881 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2884 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2886 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2887 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2889 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2891 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2892 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2894 glDisable(GL_TEXTURE_2D);
2895 checkGLcall("glDisable(GL_TEXTURE_2D)");
2896 glEnable(GL_TEXTURE_3D);
2897 checkGLcall("glEnable(GL_TEXTURE_3D)");
2899 case GL_TEXTURE_CUBE_MAP_ARB:
2900 glDisable(GL_TEXTURE_2D);
2901 checkGLcall("glDisable(GL_TEXTURE_2D)");
2902 glDisable(GL_TEXTURE_3D);
2903 checkGLcall("glDisable(GL_TEXTURE_3D)");
2904 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2906 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2907 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2909 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2910 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2914 glEnable(GL_TEXTURE_2D);
2915 checkGLcall("glEnable(GL_TEXTURE_2D)");
2916 glDisable(GL_TEXTURE_3D);
2917 checkGLcall("glDisable(GL_TEXTURE_3D)");
2918 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2920 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2921 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2923 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2925 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2926 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2928 /* Binding textures is done by samplers. A dummy texture will be bound */
2932 /* GL locking is done by the caller (state handler) */
2933 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2935 DWORD sampler = state - STATE_SAMPLER(0);
2936 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
2938 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2939 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2940 * will take care of this business
2942 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
2943 if(sampler >= stateblock->lowest_disabled_stage) return;
2944 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2946 texture_activate_dimensions(sampler, stateblock, context);
2949 void *wined3d_rb_alloc(size_t size)
2951 return HeapAlloc(GetProcessHeap(), 0, size);
2954 void *wined3d_rb_realloc(void *ptr, size_t size)
2956 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
2959 void wined3d_rb_free(void *ptr)
2961 HeapFree(GetProcessHeap(), 0, ptr);
2964 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
2966 const struct ffp_frag_settings *ka = key;
2967 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
2969 return memcmp(ka, kb, sizeof(*ka));
2972 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
2977 ffp_frag_program_key_compare,
2980 UINT wined3d_log2i(UINT32 x)
2982 static const UINT l[] =
2984 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2985 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2986 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2987 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2988 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2989 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2990 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2991 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2992 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2993 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2994 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2995 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2996 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2997 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2998 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2999 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3003 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3006 /* Set the shader type for this device, depending on the given capabilities
3007 * and the user preferences in wined3d_settings. */
3008 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3010 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3012 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3013 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3015 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3016 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3017 * shaders only on this card. */
3018 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3019 else *vs_selected = SHADER_GLSL;
3021 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3022 else *vs_selected = SHADER_NONE;
3024 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3025 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3026 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3027 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3028 else *ps_selected = SHADER_NONE;