shell32: Replaced ramdisk.ico with a Tango compliant icon.
[wine/multimedia.git] / dlls / wined3d / utils.c
blobb2a35c6033d10c13a9a9c6fa72362a8ad2171ba9
1 /*
2 * Utility functions for the WineD3D Library
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2008 Henri Verbeet
9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
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
27 #include "config.h"
28 #include "wined3d_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
32 struct StaticPixelFormatDesc
34 WINED3DFORMAT format;
35 DWORD alphaMask, redMask, greenMask, blueMask;
36 UINT bpp;
37 short depthSize, stencilSize;
40 /*****************************************************************************
41 * Pixel format array
43 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
44 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
45 * high masks do not fit into the 32 bit values needed for ddraw. It is only
46 * used for ddraw mostly, and to figure out if the format has alpha at all, so
47 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
48 * formats are not usable in 2D rendering because ddraw doesn't support them.
50 static const struct StaticPixelFormatDesc formats[] =
52 /* WINED3DFORMAT alphamask redmask greenmask bluemask bpp depth stencil */
53 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
54 /* FourCC formats */
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},
66 /* IEEE formats */
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},
71 /* Hmm? */
72 {WINED3DFMT_R8G8_SNORM_Cx, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
73 /* Float */
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},
103 /* Luminance */
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;
139 DWORD flags;
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;
183 UINT block_width;
184 UINT block_height;
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;
203 GLenum gl_vtx_type;
204 GLint gl_vtx_format;
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;
233 GLint gl_internal;
234 GLint gl_srgb_internal;
235 GLint gl_rt_internal;
236 GLint gl_format;
237 GLint gl_type;
238 unsigned int conv_byte_count;
239 unsigned int flags;
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)
246 unsigned int x, y;
247 const WORD *Source;
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);
263 Dest_s += 1;
268 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
270 unsigned int x, y;
271 const WORD *Source;
272 unsigned char *Dest;
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
277 * loaded
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;
299 Dest += 3;
304 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
306 unsigned int x, y;
307 const short *Source;
308 unsigned char *Dest;
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 */
321 Dest += 3;
326 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
328 unsigned int x, y;
329 const DWORD *Source;
330 unsigned char *Dest;
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 */
346 Dest += 4;
351 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
353 unsigned int x, y;
354 const DWORD *Source;
355 unsigned char *Dest;
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 */
371 Dest += 4;
376 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
378 unsigned int x, y;
379 const DWORD *Source;
380 unsigned char *Dest;
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 */
393 Dest += 4;
398 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
400 unsigned int x, y;
401 const DWORD *Source;
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 */
415 Dest += 3;
420 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
422 unsigned int x, y;
423 const float *Source;
424 float *Dest;
425 UINT outpitch = (pitch * 3)/2;
427 for(y = 0; y < height; y++)
429 Source = (const float *)(src + y * pitch);
430 Dest = (float *) (dst + y * outpitch);
431 for (x = 0; x < width; x++ )
433 float green = (*Source++);
434 float red = (*Source++);
435 Dest[0] = green;
436 Dest[1] = red;
437 Dest[2] = 1.0f;
438 Dest += 3;
443 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
445 unsigned int x, y;
446 UINT outpitch = pitch * 2;
448 for (y = 0; y < height; ++y)
450 const WORD *source = (const WORD *)(src + y * pitch);
451 DWORD *dest = (DWORD *)(dst + y * outpitch);
453 for (x = 0; x < width; ++x)
455 /* The depth data is normalized, so needs to be scaled,
456 * the stencil data isn't. Scale depth data by
457 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
458 WORD d15 = source[x] >> 1;
459 DWORD d24 = (d15 << 9) + (d15 >> 6);
460 dest[x] = (d24 << 8) | (source[x] & 0x1);
465 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
467 unsigned int x, y;
469 for (y = 0; y < height; ++y)
471 const DWORD *source = (const DWORD *)(src + y * pitch);
472 DWORD *dest = (DWORD *)(dst + y * pitch);
474 for (x = 0; x < width; ++x)
476 /* Just need to clear out the X4 part. */
477 dest[x] = source[x] & ~0xf0;
482 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
484 unsigned int x, y;
485 UINT outpitch = pitch * 2;
487 for (y = 0; y < height; ++y)
489 const DWORD *source = (const DWORD *)(src + y * pitch);
490 float *dest_f = (float *)(dst + y * outpitch);
491 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
493 for (x = 0; x < width; ++x)
495 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
496 dest_s[x * 2 + 1] = source[x] & 0xff;
501 static const struct wined3d_format_texture_info format_texture_info[] =
503 /* WINED3DFORMAT internal srgbInternal rtInternal
504 format type
505 flags
506 extension */
507 /* FourCC formats */
508 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
509 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
510 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
511 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
512 * endian machine
514 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
515 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
516 WINED3DFMT_FLAG_FILTERING,
517 WINED3D_GL_EXT_NONE, NULL},
518 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
519 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
520 WINED3DFMT_FLAG_FILTERING,
521 APPLE_YCBCR_422, NULL},
522 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
523 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
524 WINED3DFMT_FLAG_FILTERING,
525 WINED3D_GL_EXT_NONE, NULL},
526 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
527 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
528 WINED3DFMT_FLAG_FILTERING,
529 APPLE_YCBCR_422, NULL},
530 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
531 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
532 WINED3DFMT_FLAG_FILTERING,
533 WINED3D_GL_EXT_NONE, NULL},
534 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
535 GL_RGBA, GL_UNSIGNED_BYTE, 0,
536 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
537 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
538 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
539 GL_RGBA, GL_UNSIGNED_BYTE, 0,
540 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
541 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
542 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
543 GL_RGBA, GL_UNSIGNED_BYTE, 0,
544 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
545 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
546 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
547 GL_RGBA, GL_UNSIGNED_BYTE, 0,
548 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
549 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
550 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
551 GL_RGBA, GL_UNSIGNED_BYTE, 0,
552 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
553 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
554 /* IEEE formats */
555 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
556 GL_RED, GL_FLOAT, 0,
557 WINED3DFMT_FLAG_RENDERTARGET,
558 ARB_TEXTURE_FLOAT, NULL},
559 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
560 GL_RED, GL_FLOAT, 0,
561 WINED3DFMT_FLAG_RENDERTARGET,
562 ARB_TEXTURE_RG, NULL},
563 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
564 GL_RGB, GL_FLOAT, 12,
565 WINED3DFMT_FLAG_RENDERTARGET,
566 ARB_TEXTURE_FLOAT, &convert_r32g32_float},
567 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
568 GL_RG, GL_FLOAT, 0,
569 WINED3DFMT_FLAG_RENDERTARGET,
570 ARB_TEXTURE_RG, NULL},
571 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
572 GL_RGBA, GL_FLOAT, 0,
573 WINED3DFMT_FLAG_RENDERTARGET,
574 ARB_TEXTURE_FLOAT, NULL},
575 /* Float */
576 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
577 GL_RED, GL_HALF_FLOAT_ARB, 0,
578 WINED3DFMT_FLAG_RENDERTARGET,
579 ARB_TEXTURE_FLOAT, NULL},
580 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
581 GL_RED, GL_HALF_FLOAT_ARB, 0,
582 WINED3DFMT_FLAG_RENDERTARGET,
583 ARB_TEXTURE_RG, NULL},
584 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
585 GL_RGB, GL_HALF_FLOAT_ARB, 0,
586 WINED3DFMT_FLAG_RENDERTARGET,
587 ARB_TEXTURE_FLOAT, NULL},
588 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
589 GL_RG, GL_HALF_FLOAT_ARB, 0,
590 WINED3DFMT_FLAG_RENDERTARGET,
591 ARB_TEXTURE_RG, NULL},
592 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
593 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
594 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
595 ARB_TEXTURE_FLOAT, NULL},
596 /* Palettized formats */
597 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
598 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
600 ARB_FRAGMENT_PROGRAM, NULL},
601 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
602 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
604 EXT_PALETTED_TEXTURE, NULL},
605 /* Standard ARGB formats */
606 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
607 GL_BGR, GL_UNSIGNED_BYTE, 0,
608 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
609 WINED3D_GL_EXT_NONE, NULL},
610 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
611 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
612 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
613 WINED3D_GL_EXT_NONE, NULL},
614 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
615 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
616 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
617 WINED3D_GL_EXT_NONE, NULL},
618 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
619 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
620 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
621 WINED3D_GL_EXT_NONE, NULL},
622 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
623 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
624 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
625 WINED3D_GL_EXT_NONE, NULL},
626 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
627 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
628 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
629 WINED3D_GL_EXT_NONE, NULL},
630 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
631 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
632 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
633 WINED3D_GL_EXT_NONE, NULL},
634 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
635 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
636 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
637 WINED3D_GL_EXT_NONE, NULL},
638 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
639 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
640 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
641 WINED3D_GL_EXT_NONE, NULL},
642 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
643 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
644 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
645 WINED3D_GL_EXT_NONE, NULL},
646 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
647 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
648 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
649 WINED3D_GL_EXT_NONE, NULL},
650 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
651 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
652 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
653 WINED3D_GL_EXT_NONE, NULL},
654 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
655 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
656 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
657 WINED3D_GL_EXT_NONE, NULL},
658 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
659 GL_RGB, GL_UNSIGNED_SHORT, 0,
660 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
661 WINED3D_GL_EXT_NONE, NULL},
662 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
663 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
664 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
665 WINED3D_GL_EXT_NONE, NULL},
666 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
667 GL_RGBA, GL_UNSIGNED_SHORT, 0,
668 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
669 WINED3D_GL_EXT_NONE, NULL},
670 /* Luminance */
671 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
672 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
673 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
674 WINED3D_GL_EXT_NONE, NULL},
675 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
676 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
677 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
678 WINED3D_GL_EXT_NONE, NULL},
679 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
680 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
682 WINED3D_GL_EXT_NONE, NULL},
683 /* Bump mapping stuff */
684 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
685 GL_BGR, GL_UNSIGNED_BYTE, 3,
686 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
687 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm},
688 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
689 GL_DSDT_NV, GL_BYTE, 0,
690 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
691 NV_TEXTURE_SHADER, NULL},
692 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
693 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
694 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
695 WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm},
696 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
697 GL_DSDT_MAG_NV, GL_BYTE, 3,
698 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
699 NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv},
700 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
701 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
702 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
703 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm},
704 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
705 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
706 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
707 NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv},
708 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
709 GL_BGRA, GL_UNSIGNED_BYTE, 4,
710 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
711 WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm},
712 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
713 GL_RGBA, GL_BYTE, 0,
714 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
715 NV_TEXTURE_SHADER, NULL},
716 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
717 GL_BGR, GL_UNSIGNED_SHORT, 6,
718 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
719 WINED3D_GL_EXT_NONE, &convert_r16g16_snorm},
720 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
721 GL_HILO_NV, GL_SHORT, 0,
722 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
723 NV_TEXTURE_SHADER, NULL},
724 /* Depth stencil formats */
725 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
726 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
727 WINED3DFMT_FLAG_DEPTH,
728 ARB_DEPTH_TEXTURE, NULL},
729 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
730 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
731 WINED3DFMT_FLAG_DEPTH,
732 ARB_DEPTH_TEXTURE, NULL},
733 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
734 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
735 WINED3DFMT_FLAG_DEPTH,
736 ARB_DEPTH_TEXTURE, NULL},
737 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
738 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
739 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
740 EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm},
741 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
742 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
743 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
744 ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm},
745 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
746 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
747 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
748 ARB_DEPTH_TEXTURE, NULL},
749 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
750 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
751 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
752 EXT_PACKED_DEPTH_STENCIL, NULL},
753 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
754 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
755 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
756 ARB_FRAMEBUFFER_OBJECT, NULL},
757 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
758 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
759 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
760 ARB_DEPTH_TEXTURE, NULL},
761 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
762 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
763 WINED3DFMT_FLAG_DEPTH,
764 ARB_DEPTH_TEXTURE, NULL},
765 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
766 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
767 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
768 EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm},
769 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
770 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
771 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
772 ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm},
773 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
774 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
775 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
776 ARB_DEPTH_TEXTURE, NULL},
777 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
778 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
779 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
780 WINED3D_GL_EXT_NONE, NULL},
781 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
782 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
783 WINED3DFMT_FLAG_DEPTH,
784 ARB_DEPTH_BUFFER_FLOAT, NULL},
785 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
786 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
787 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
788 ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float},
789 /* Vendor-specific formats */
790 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
791 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
793 ATI_TEXTURE_COMPRESSION_3DC, NULL},
794 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, 0,
795 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
797 EXT_TEXTURE_COMPRESSION_RGTC, NULL},
800 static inline int getFmtIdx(WINED3DFORMAT fmt) {
801 /* First check if the format is at the position of its value.
802 * This will catch the argb formats before the loop is entered
804 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
805 return fmt;
806 } else {
807 unsigned int i;
808 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
809 if(formats[i].format == fmt) {
810 return i;
814 return -1;
817 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
819 UINT format_count = sizeof(formats) / sizeof(*formats);
820 UINT i;
822 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->gl_formats));
823 if (!gl_info->gl_formats)
825 ERR("Failed to allocate memory.\n");
826 return FALSE;
829 for (i = 0; i < format_count; ++i)
831 struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
832 desc->format = formats[i].format;
833 desc->red_mask = formats[i].redMask;
834 desc->green_mask = formats[i].greenMask;
835 desc->blue_mask = formats[i].blueMask;
836 desc->alpha_mask = formats[i].alphaMask;
837 desc->byte_count = formats[i].bpp;
838 desc->depth_size = formats[i].depthSize;
839 desc->stencil_size = formats[i].stencilSize;
842 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
844 int fmt_idx = getFmtIdx(format_base_flags[i].format);
846 if (fmt_idx == -1)
848 ERR("Format %s (%#x) not found.\n",
849 debug_d3dformat(format_base_flags[i].format), format_base_flags[i].format);
850 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
851 return FALSE;
854 gl_info->gl_formats[fmt_idx].Flags |= format_base_flags[i].flags;
857 return TRUE;
860 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
862 unsigned int i;
864 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
866 struct wined3d_format_desc *format_desc;
867 int fmt_idx = getFmtIdx(format_compression_info[i].format);
869 if (fmt_idx == -1)
871 ERR("Format %s (%#x) not found.\n",
872 debug_d3dformat(format_compression_info[i].format), format_compression_info[i].format);
873 return FALSE;
876 format_desc = &gl_info->gl_formats[fmt_idx];
877 format_desc->block_width = format_compression_info[i].block_width;
878 format_desc->block_height = format_compression_info[i].block_height;
879 format_desc->block_byte_count = format_compression_info[i].block_byte_count;
880 format_desc->Flags |= WINED3DFMT_FLAG_COMPRESSED;
883 return TRUE;
886 /* Context activation is done by the caller. */
887 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format_desc *format_desc)
889 /* Check if the default internal format is supported as a frame buffer
890 * target, otherwise fall back to the render target internal.
892 * Try to stick to the standard format if possible, this limits precision differences. */
893 GLenum status;
894 GLuint tex;
896 ENTER_GL();
898 while(glGetError());
899 glDisable(GL_BLEND);
901 glGenTextures(1, &tex);
902 glBindTexture(GL_TEXTURE_2D, tex);
904 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glInternal, 16, 16, 0,
905 format_desc->glFormat, format_desc->glType, NULL);
906 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
907 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
909 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
911 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
912 checkGLcall("Framebuffer format check");
914 if (status == GL_FRAMEBUFFER_COMPLETE)
916 TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(format_desc->format));
917 format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
918 format_desc->rtInternal = format_desc->glInternal;
920 else
922 if (!format_desc->rtInternal)
924 if (format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)
926 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
927 " and no fallback specified.\n", debug_d3dformat(format_desc->format));
928 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
930 else
932 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format_desc->format));
934 format_desc->rtInternal = format_desc->glInternal;
936 else
938 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
939 debug_d3dformat(format_desc->format));
941 while(glGetError());
943 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
945 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->rtInternal, 16, 16, 0,
946 format_desc->glFormat, format_desc->glType, NULL);
947 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
948 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
950 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
952 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
953 checkGLcall("Framebuffer format check");
955 if (status == GL_FRAMEBUFFER_COMPLETE)
957 TRACE("Format %s rtInternal format is supported as FBO color attachment\n",
958 debug_d3dformat(format_desc->format));
960 else
962 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
963 debug_d3dformat(format_desc->format));
964 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
969 if (status == GL_FRAMEBUFFER_COMPLETE && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
971 GLuint rb;
973 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
974 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
976 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
977 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
978 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
979 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
980 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
981 checkGLcall("RB attachment");
984 glEnable(GL_BLEND);
985 glClear(GL_COLOR_BUFFER_BIT);
986 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
988 while(glGetError());
989 TRACE("Format doesn't support post-pixelshader blending.\n");
990 format_desc->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
993 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
994 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
996 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
997 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
998 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
999 checkGLcall("RB cleanup");
1003 glDeleteTextures(1, &tex);
1005 LEAVE_GL();
1008 /* Context activation is done by the caller. */
1009 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1011 unsigned int i;
1012 GLuint fbo;
1014 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1016 ENTER_GL();
1018 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1019 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1021 LEAVE_GL();
1024 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1026 struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
1028 if (!desc->glInternal) continue;
1030 if (desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1032 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1033 debug_d3dformat(desc->format));
1034 continue;
1037 if (desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
1039 TRACE("Skipping format %s because it's a compressed format.\n",
1040 debug_d3dformat(desc->format));
1041 continue;
1044 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1046 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc->format));
1047 check_fbo_compat(gl_info, desc);
1049 else
1051 desc->rtInternal = desc->glInternal;
1055 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1057 ENTER_GL();
1059 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1061 LEAVE_GL();
1065 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1067 unsigned int i;
1069 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1071 int fmt_idx = getFmtIdx(format_texture_info[i].format);
1072 struct wined3d_format_desc *desc;
1074 if (fmt_idx == -1)
1076 ERR("Format %s (%#x) not found.\n",
1077 debug_d3dformat(format_texture_info[i].format), format_texture_info[i].format);
1078 return FALSE;
1081 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1083 desc = &gl_info->gl_formats[fmt_idx];
1084 desc->glInternal = format_texture_info[i].gl_internal;
1085 desc->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1086 desc->rtInternal = format_texture_info[i].gl_rt_internal;
1087 desc->glFormat = format_texture_info[i].gl_format;
1088 desc->glType = format_texture_info[i].gl_type;
1089 desc->color_fixup = COLOR_FIXUP_IDENTITY;
1090 desc->Flags |= format_texture_info[i].flags;
1091 desc->heightscale = 1.0f;
1093 /* Texture conversion stuff */
1094 desc->convert = format_texture_info[i].convert;
1095 desc->conv_byte_count = format_texture_info[i].conv_byte_count;
1098 return TRUE;
1101 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1103 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1104 c1 >>= 8; c2 >>= 8;
1105 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1106 c1 >>= 8; c2 >>= 8;
1107 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1108 c1 >>= 8; c2 >>= 8;
1109 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1110 return TRUE;
1113 /* A context is provided by the caller */
1114 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1116 GLuint tex, fbo, buffer;
1117 const DWORD data[] = {0x00000000, 0xffffffff};
1118 DWORD readback[16 * 1];
1119 BOOL ret = FALSE;
1121 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1122 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1123 * falling back to software. If this changes in the future this code will get fooled and
1124 * apps might hit the software path due to incorrectly advertised caps.
1126 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1127 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1128 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1131 ENTER_GL();
1132 while(glGetError());
1134 glGenTextures(1, &buffer);
1135 glBindTexture(GL_TEXTURE_2D, buffer);
1136 memset(readback, 0x7e, sizeof(readback));
1137 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1138 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1139 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1140 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1141 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1142 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1144 glGenTextures(1, &tex);
1145 glBindTexture(GL_TEXTURE_2D, tex);
1146 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1147 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1149 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1150 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1151 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1152 glEnable(GL_TEXTURE_2D);
1154 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1155 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1156 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1157 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1159 glViewport(0, 0, 16, 1);
1160 glDisable(GL_LIGHTING);
1161 glMatrixMode(GL_MODELVIEW);
1162 glLoadIdentity();
1163 glMatrixMode(GL_PROJECTION);
1164 glLoadIdentity();
1166 glClearColor(0, 1, 0, 0);
1167 glClear(GL_COLOR_BUFFER_BIT);
1169 glBegin(GL_TRIANGLE_STRIP);
1170 glTexCoord2f(0.0, 0.0);
1171 glVertex2f(-1.0f, -1.0f);
1172 glTexCoord2f(1.0, 0.0);
1173 glVertex2f(1.0f, -1.0f);
1174 glTexCoord2f(0.0, 1.0);
1175 glVertex2f(-1.0f, 1.0f);
1176 glTexCoord2f(1.0, 1.0);
1177 glVertex2f(1.0f, 1.0f);
1178 glEnd();
1180 glBindTexture(GL_TEXTURE_2D, buffer);
1181 memset(readback, 0x7f, sizeof(readback));
1182 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1183 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1184 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1186 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1187 readback[6], readback[9]);
1188 ret = FALSE;
1190 else
1192 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1193 readback[6], readback[9]);
1194 ret = TRUE;
1197 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1198 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1199 glDeleteTextures(1, &tex);
1200 glDeleteTextures(1, &buffer);
1202 if(glGetError())
1204 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1205 ret = FALSE;
1207 LEAVE_GL();
1208 return ret;
1211 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1213 struct wined3d_format_desc *desc;
1214 unsigned int fmt_idx, i;
1215 WINED3DFORMAT fmts16[] = {
1216 WINED3DFMT_R16_FLOAT,
1217 WINED3DFMT_R16G16_FLOAT,
1218 WINED3DFMT_R16G16B16A16_FLOAT,
1220 BOOL filtered;
1222 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1224 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1225 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1227 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1228 filtered = TRUE;
1230 else if (gl_info->limits.glsl_varyings > 44)
1232 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1233 filtered = TRUE;
1235 else
1237 TRACE("Assuming no float16 blending\n");
1238 filtered = FALSE;
1241 if(filtered)
1243 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1245 fmt_idx = getFmtIdx(fmts16[i]);
1246 gl_info->gl_formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
1249 return;
1252 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1254 fmt_idx = getFmtIdx(fmts16[i]);
1255 desc = &gl_info->gl_formats[fmt_idx];
1256 if(!desc->glInternal) continue; /* Not supported by GL */
1258 filtered = check_filter(gl_info, gl_info->gl_formats[fmt_idx].glInternal);
1259 if(filtered)
1261 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1262 desc->Flags |= WINED3DFMT_FLAG_FILTERING;
1264 else
1266 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1271 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1273 int idx;
1275 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1276 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1277 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1279 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1280 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1281 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1283 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1284 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1285 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1287 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1288 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1289 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1291 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1292 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1293 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1295 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1296 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1297 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1298 * the only driver that implements it(fglrx) has a buggy implementation.
1300 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1301 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1302 * conversion for this format.
1304 if (!gl_info->supported[NV_TEXTURE_SHADER])
1306 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1307 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1308 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1309 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1310 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1311 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1313 else
1315 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1316 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1317 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1319 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1320 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1321 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1324 if (!gl_info->supported[NV_TEXTURE_SHADER])
1326 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1327 * with each other
1329 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1330 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1331 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1332 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1333 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1334 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1335 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1336 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1337 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1339 else
1341 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1342 * are converted at surface loading time, but they do not need any modification in
1343 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1344 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1348 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1350 idx = getFmtIdx(WINED3DFMT_ATI2N);
1351 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1352 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1354 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1356 idx = getFmtIdx(WINED3DFMT_ATI2N);
1357 gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
1358 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1361 if (!gl_info->supported[APPLE_YCBCR_422])
1363 idx = getFmtIdx(WINED3DFMT_YUY2);
1364 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1366 idx = getFmtIdx(WINED3DFMT_UYVY);
1367 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1370 idx = getFmtIdx(WINED3DFMT_YV12);
1371 gl_info->gl_formats[idx].heightscale = 1.5f;
1372 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1374 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1376 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1377 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1380 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1382 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1383 gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
1386 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1388 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1389 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1390 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1391 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1393 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1394 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1398 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1400 unsigned int i;
1402 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1404 struct wined3d_format_desc *format_desc;
1405 int fmt_idx = getFmtIdx(format_vertex_info[i].format);
1407 if (fmt_idx == -1)
1409 ERR("Format %s (%#x) not found.\n",
1410 debug_d3dformat(format_vertex_info[i].format), format_vertex_info[i].format);
1411 return FALSE;
1414 format_desc = &gl_info->gl_formats[fmt_idx];
1415 format_desc->emit_idx = format_vertex_info[i].emit_idx;
1416 format_desc->component_count = format_vertex_info[i].component_count;
1417 format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1418 format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1419 format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
1420 format_desc->component_size = format_vertex_info[i].component_size;
1423 return TRUE;
1426 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1428 if (!init_format_base_info(gl_info)) return FALSE;
1430 if (!init_format_compression_info(gl_info))
1432 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1433 gl_info->gl_formats = NULL;
1434 return FALSE;
1437 return TRUE;
1440 /* Context activation is done by the caller. */
1441 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1443 if (!init_format_base_info(gl_info)) return FALSE;
1445 if (!init_format_compression_info(gl_info)) goto fail;
1446 if (!init_format_texture_info(gl_info)) goto fail;
1447 if (!init_format_vertex_info(gl_info)) goto fail;
1449 apply_format_fixups(gl_info);
1450 init_format_fbo_compat_info(gl_info);
1451 init_format_filter_info(gl_info, vendor);
1453 return TRUE;
1455 fail:
1456 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1457 gl_info->gl_formats = NULL;
1458 return FALSE;
1461 const struct wined3d_format_desc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info)
1463 int idx = getFmtIdx(fmt);
1465 if(idx == -1) {
1466 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
1467 /* Get the caller a valid pointer */
1468 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1471 return &gl_info->gl_formats[idx];
1474 /*****************************************************************************
1475 * Trace formatting of useful values
1477 const char* debug_d3dformat(WINED3DFORMAT fmt) {
1478 switch (fmt) {
1479 #define FMT_TO_STR(fmt) case fmt: return #fmt
1480 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1481 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1482 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1483 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1484 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1485 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1486 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1487 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1488 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1489 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1490 FMT_TO_STR(WINED3DFMT_P8_UINT);
1491 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1492 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1493 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1494 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1495 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1496 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1497 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1498 FMT_TO_STR(WINED3DFMT_UYVY);
1499 FMT_TO_STR(WINED3DFMT_YUY2);
1500 FMT_TO_STR(WINED3DFMT_YV12);
1501 FMT_TO_STR(WINED3DFMT_DXT1);
1502 FMT_TO_STR(WINED3DFMT_DXT2);
1503 FMT_TO_STR(WINED3DFMT_DXT3);
1504 FMT_TO_STR(WINED3DFMT_DXT4);
1505 FMT_TO_STR(WINED3DFMT_DXT5);
1506 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1507 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1508 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1509 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1510 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1511 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1512 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1513 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1514 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1515 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1516 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1517 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1518 FMT_TO_STR(WINED3DFMT_ATI2N);
1519 FMT_TO_STR(WINED3DFMT_NVHU);
1520 FMT_TO_STR(WINED3DFMT_NVHS);
1521 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1522 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1523 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1524 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1525 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1526 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1527 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1528 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1529 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1530 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1531 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1532 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1533 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1534 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1535 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1536 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1537 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1538 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1539 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1540 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1541 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1542 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1543 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1544 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1545 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1546 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1547 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1548 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1549 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1550 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1551 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1552 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1553 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1554 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1555 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1556 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1557 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1558 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1559 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1560 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1561 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1562 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1563 FMT_TO_STR(WINED3DFMT_R32_UINT);
1564 FMT_TO_STR(WINED3DFMT_R32_SINT);
1565 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1566 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1567 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1568 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1569 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1570 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1571 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1572 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1573 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1574 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1575 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1576 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1577 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1578 FMT_TO_STR(WINED3DFMT_R16_UINT);
1579 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1580 FMT_TO_STR(WINED3DFMT_R16_SINT);
1581 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1582 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1583 FMT_TO_STR(WINED3DFMT_R8_UINT);
1584 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1585 FMT_TO_STR(WINED3DFMT_R8_SINT);
1586 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1587 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1588 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1589 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1590 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1591 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1592 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1593 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1594 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1595 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1596 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1597 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1598 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1599 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1600 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1601 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1602 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1603 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1604 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1605 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1606 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1607 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1608 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1609 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1610 #undef FMT_TO_STR
1611 default:
1613 char fourcc[5];
1614 fourcc[0] = (char)(fmt);
1615 fourcc[1] = (char)(fmt >> 8);
1616 fourcc[2] = (char)(fmt >> 16);
1617 fourcc[3] = (char)(fmt >> 24);
1618 fourcc[4] = 0;
1619 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
1620 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
1621 else
1622 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
1624 return "unrecognized";
1628 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
1629 switch (devtype) {
1630 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1631 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1632 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1633 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1634 #undef DEVTYPE_TO_STR
1635 default:
1636 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1637 return "unrecognized";
1641 const char *debug_d3dusage(DWORD usage)
1643 char buf[284];
1645 buf[0] = '\0';
1646 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1647 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1648 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1649 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1650 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1651 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1652 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1653 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1654 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1655 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1656 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1657 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1658 #undef WINED3DUSAGE_TO_STR
1659 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1661 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1664 const char *debug_d3dusagequery(DWORD usagequery)
1666 char buf[238];
1668 buf[0] = '\0';
1669 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1670 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1671 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1672 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1673 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1674 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1675 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1676 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1677 #undef WINED3DUSAGEQUERY_TO_STR
1678 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1680 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1683 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1684 switch (method) {
1685 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1686 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1687 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1688 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1689 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1690 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1691 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1692 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1693 #undef WINED3DDECLMETHOD_TO_STR
1694 default:
1695 FIXME("Unrecognized %u declaration method!\n", method);
1696 return "unrecognized";
1700 const char* debug_d3ddeclusage(BYTE usage) {
1701 switch (usage) {
1702 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1703 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1704 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1705 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1706 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1707 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1708 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1709 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1710 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1711 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1712 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1713 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1714 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1715 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1716 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1717 #undef WINED3DDECLUSAGE_TO_STR
1718 default:
1719 FIXME("Unrecognized %u declaration usage!\n", usage);
1720 return "unrecognized";
1724 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1725 switch (res) {
1726 #define RES_TO_STR(res) case res: return #res
1727 RES_TO_STR(WINED3DRTYPE_SURFACE);
1728 RES_TO_STR(WINED3DRTYPE_VOLUME);
1729 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1730 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1731 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1732 RES_TO_STR(WINED3DRTYPE_BUFFER);
1733 #undef RES_TO_STR
1734 default:
1735 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1736 return "unrecognized";
1740 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1741 switch (PrimitiveType) {
1742 #define PRIM_TO_STR(prim) case prim: return #prim
1743 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1744 PRIM_TO_STR(WINED3DPT_POINTLIST);
1745 PRIM_TO_STR(WINED3DPT_LINELIST);
1746 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1747 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1748 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1749 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1750 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1751 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1752 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1753 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1754 #undef PRIM_TO_STR
1755 default:
1756 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1757 return "unrecognized";
1761 const char* debug_d3drenderstate(DWORD state) {
1762 switch (state) {
1763 #define D3DSTATE_TO_STR(u) case u: return #u
1764 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1765 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1766 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1767 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1768 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1769 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1770 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1771 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1772 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1773 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1774 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1775 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1776 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1777 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1778 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1779 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1780 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1781 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1782 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1783 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1784 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1785 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1786 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1787 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1788 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1789 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1790 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1791 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1792 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1793 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1794 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1795 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1796 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1797 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1798 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1799 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1800 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1801 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1802 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1803 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1804 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1805 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1806 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1807 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1808 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1809 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1810 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1811 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1812 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1813 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1814 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1815 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1816 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1817 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1818 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1819 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1820 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1821 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1822 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1823 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1824 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1825 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1826 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1827 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1828 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1829 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1830 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1831 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1832 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1833 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1834 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1835 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1836 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1837 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1838 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1839 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1840 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1841 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1842 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1843 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1844 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1845 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1846 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1847 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1848 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1849 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1850 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1851 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1852 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1853 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1854 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1855 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1856 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1857 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1858 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1859 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1860 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1861 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1862 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1863 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1864 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1865 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1866 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1867 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1868 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1869 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1870 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1871 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1872 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1873 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1874 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1875 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1876 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1877 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1878 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1879 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1880 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1881 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1882 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1883 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1884 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1885 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1886 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1887 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1888 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1889 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1890 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1891 #undef D3DSTATE_TO_STR
1892 default:
1893 FIXME("Unrecognized %u render state!\n", state);
1894 return "unrecognized";
1898 const char* debug_d3dsamplerstate(DWORD state) {
1899 switch (state) {
1900 #define D3DSTATE_TO_STR(u) case u: return #u
1901 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1902 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1903 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1904 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1905 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1906 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1907 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1908 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1909 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1910 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1911 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1912 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1913 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1914 #undef D3DSTATE_TO_STR
1915 default:
1916 FIXME("Unrecognized %u sampler state!\n", state);
1917 return "unrecognized";
1921 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1922 switch (filter_type) {
1923 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1924 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1925 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1926 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1927 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1928 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1929 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1930 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1931 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1932 #undef D3DTEXTUREFILTERTYPE_TO_STR
1933 default:
1934 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1935 return "unrecognized";
1939 const char* debug_d3dtexturestate(DWORD state) {
1940 switch (state) {
1941 #define D3DSTATE_TO_STR(u) case u: return #u
1942 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1943 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1944 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1945 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1946 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1947 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1948 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1949 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1950 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1951 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1952 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1953 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1954 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1955 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1956 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1957 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1958 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1959 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1960 #undef D3DSTATE_TO_STR
1961 default:
1962 FIXME("Unrecognized %u texture state!\n", state);
1963 return "unrecognized";
1967 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1968 switch (d3dtop) {
1969 #define D3DTOP_TO_STR(u) case u: return #u
1970 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1971 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1972 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1973 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1974 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1975 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1976 D3DTOP_TO_STR(WINED3DTOP_ADD);
1977 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1978 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1979 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1980 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1981 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1982 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1983 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1984 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1985 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1986 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1987 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1988 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1989 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1990 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1991 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1992 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1993 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1994 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1995 D3DTOP_TO_STR(WINED3DTOP_LERP);
1996 #undef D3DTOP_TO_STR
1997 default:
1998 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1999 return "unrecognized";
2003 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2004 switch (tstype) {
2005 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2006 TSTYPE_TO_STR(WINED3DTS_VIEW);
2007 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2008 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2009 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2010 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2011 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2012 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2013 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2014 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2015 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2016 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2017 #undef TSTYPE_TO_STR
2018 default:
2019 if (tstype > 256 && tstype < 512) {
2020 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2021 return ("WINED3DTS_WORLDMATRIX > 0");
2023 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2024 return "unrecognized";
2028 const char *debug_d3dstate(DWORD state)
2030 if (STATE_IS_RENDER(state))
2031 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2032 if (STATE_IS_TEXTURESTAGE(state))
2034 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2035 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2036 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2037 texture_stage, debug_d3dtexturestate(texture_state));
2039 if (STATE_IS_SAMPLER(state))
2040 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2041 if (STATE_IS_PIXELSHADER(state))
2042 return "STATE_PIXELSHADER";
2043 if (STATE_IS_TRANSFORM(state))
2044 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2045 if (STATE_IS_STREAMSRC(state))
2046 return "STATE_STREAMSRC";
2047 if (STATE_IS_INDEXBUFFER(state))
2048 return "STATE_INDEXBUFFER";
2049 if (STATE_IS_VDECL(state))
2050 return "STATE_VDECL";
2051 if (STATE_IS_VSHADER(state))
2052 return "STATE_VSHADER";
2053 if (STATE_IS_VIEWPORT(state))
2054 return "STATE_VIEWPORT";
2055 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2056 return "STATE_VERTEXSHADERCONSTANT";
2057 if (STATE_IS_PIXELSHADERCONSTANT(state))
2058 return "STATE_PIXELSHADERCONSTANT";
2059 if (STATE_IS_ACTIVELIGHT(state))
2060 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2061 if (STATE_IS_SCISSORRECT(state))
2062 return "STATE_SCISSORRECT";
2063 if (STATE_IS_CLIPPLANE(state))
2064 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2065 if (STATE_IS_MATERIAL(state))
2066 return "STATE_MATERIAL";
2067 if (STATE_IS_FRONTFACE(state))
2068 return "STATE_FRONTFACE";
2070 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2073 const char* debug_d3dpool(WINED3DPOOL Pool) {
2074 switch (Pool) {
2075 #define POOL_TO_STR(p) case p: return #p
2076 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2077 POOL_TO_STR(WINED3DPOOL_MANAGED);
2078 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2079 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2080 #undef POOL_TO_STR
2081 default:
2082 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
2083 return "unrecognized";
2087 const char *debug_fbostatus(GLenum status) {
2088 switch(status) {
2089 #define FBOSTATUS_TO_STR(u) case u: return #u
2090 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2091 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2092 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2093 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2094 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2095 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2096 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2097 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2098 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2099 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2100 #undef FBOSTATUS_TO_STR
2101 default:
2102 FIXME("Unrecognied FBO status 0x%08x\n", status);
2103 return "unrecognized";
2107 const char *debug_glerror(GLenum error) {
2108 switch(error) {
2109 #define GLERROR_TO_STR(u) case u: return #u
2110 GLERROR_TO_STR(GL_NO_ERROR);
2111 GLERROR_TO_STR(GL_INVALID_ENUM);
2112 GLERROR_TO_STR(GL_INVALID_VALUE);
2113 GLERROR_TO_STR(GL_INVALID_OPERATION);
2114 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2115 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2116 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2117 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2118 #undef GLERROR_TO_STR
2119 default:
2120 FIXME("Unrecognied GL error 0x%08x\n", error);
2121 return "unrecognized";
2125 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2126 switch(basis) {
2127 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2128 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2129 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2130 default: return "unrecognized";
2134 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2135 switch(degree) {
2136 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2137 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2138 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2139 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2140 default: return "unrecognized";
2144 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2146 switch(source)
2148 #define WINED3D_TO_STR(x) case x: return #x
2149 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2150 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2151 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2152 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2153 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2154 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2155 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2156 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2157 #undef WINED3D_TO_STR
2158 default:
2159 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2160 return "unrecognized";
2164 static const char *debug_complex_fixup(enum complex_fixup fixup)
2166 switch(fixup)
2168 #define WINED3D_TO_STR(x) case x: return #x
2169 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2170 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2171 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2172 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2173 #undef WINED3D_TO_STR
2174 default:
2175 FIXME("Unrecognized complex fixup %#x\n", fixup);
2176 return "unrecognized";
2180 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2182 if (is_complex_fixup(fixup))
2184 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2185 return;
2188 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2189 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2190 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2191 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2194 const char *debug_surflocation(DWORD flag) {
2195 char buf[128];
2197 buf[0] = 0;
2198 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2199 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2200 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2201 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2202 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2205 /*****************************************************************************
2206 * Useful functions mapping GL <-> D3D values
2208 GLenum StencilOp(DWORD op) {
2209 switch(op) {
2210 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2211 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2212 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2213 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2214 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2215 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2216 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2217 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2218 default:
2219 FIXME("Unrecognized stencil op %d\n", op);
2220 return GL_KEEP;
2224 GLenum CompareFunc(DWORD func) {
2225 switch ((WINED3DCMPFUNC)func) {
2226 case WINED3DCMP_NEVER : return GL_NEVER;
2227 case WINED3DCMP_LESS : return GL_LESS;
2228 case WINED3DCMP_EQUAL : return GL_EQUAL;
2229 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2230 case WINED3DCMP_GREATER : return GL_GREATER;
2231 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2232 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2233 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2234 default:
2235 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2236 return 0;
2240 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
2241 if (op == WINED3DTOP_DISABLE) return FALSE;
2242 if (This->stateBlock->textures[stage]) return FALSE;
2244 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2245 && op != WINED3DTOP_SELECTARG2) return TRUE;
2246 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2247 && op != WINED3DTOP_SELECTARG1) return TRUE;
2248 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2249 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2251 return FALSE;
2254 /* Setup this textures matrix according to the texture flags*/
2255 /* GL locking is done by the caller (state handler) */
2256 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2257 WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
2259 float mat[16];
2261 glMatrixMode(GL_TEXTURE);
2262 checkGLcall("glMatrixMode(GL_TEXTURE)");
2264 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2265 glLoadIdentity();
2266 checkGLcall("glLoadIdentity()");
2267 return;
2270 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2271 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2272 return;
2275 memcpy(mat, smat, 16 * sizeof(float));
2277 if (flags & WINED3DTTFF_PROJECTED) {
2278 if(!ffp_proj_control) {
2279 switch (flags & ~WINED3DTTFF_PROJECTED) {
2280 case WINED3DTTFF_COUNT2:
2281 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2282 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2283 break;
2284 case WINED3DTTFF_COUNT3:
2285 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2286 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2287 break;
2290 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2291 if(!calculatedCoords) {
2292 switch(vtx_fmt)
2294 case WINED3DFMT_R32_FLOAT:
2295 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2296 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2297 * the input value to the transformation will be 0, so the matrix value is irrelevant
2299 mat[12] = mat[4];
2300 mat[13] = mat[5];
2301 mat[14] = mat[6];
2302 mat[15] = mat[7];
2303 break;
2304 case WINED3DFMT_R32G32_FLOAT:
2305 /* See above, just 3rd and 4th coord
2307 mat[12] = mat[8];
2308 mat[13] = mat[9];
2309 mat[14] = mat[10];
2310 mat[15] = mat[11];
2311 break;
2312 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2313 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2315 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2316 * into a bad place. The division elimination below will apply to make sure the
2317 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2319 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2320 break;
2321 default:
2322 FIXME("Unexpected fixed function texture coord input\n");
2325 if(!ffp_proj_control) {
2326 switch (flags & ~WINED3DTTFF_PROJECTED) {
2327 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2328 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2329 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2330 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2331 * the 4th coord evaluates to 1.0 to eliminate that.
2333 * If the fixed function pipeline is used, the 4th value remains unused,
2334 * so there is no danger in doing this. With vertex shaders we have a
2335 * problem. Should an app hit that problem, the code here would have to
2336 * check for pixel shaders, and the shader has to undo the default gl divide.
2338 * A more serious problem occurs if the app passes 4 coordinates in, and the
2339 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2340 * or a replacement shader
2342 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2347 glLoadMatrixf(mat);
2348 checkGLcall("glLoadMatrixf(mat)");
2351 /* This small helper function is used to convert a bitmask into the number of masked bits */
2352 unsigned int count_bits(unsigned int mask)
2354 unsigned int count;
2355 for (count = 0; mask; ++count)
2357 mask &= mask - 1;
2359 return count;
2362 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2363 * The later function requires individual color components. */
2364 BOOL getColorBits(const struct wined3d_format_desc *format_desc,
2365 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2367 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2368 switch(format_desc->format)
2370 case WINED3DFMT_B8G8R8X8_UNORM:
2371 case WINED3DFMT_B8G8R8_UNORM:
2372 case WINED3DFMT_B8G8R8A8_UNORM:
2373 case WINED3DFMT_R8G8B8A8_UNORM:
2374 case WINED3DFMT_B10G10R10A2_UNORM:
2375 case WINED3DFMT_B5G5R5X1_UNORM:
2376 case WINED3DFMT_B5G5R5A1_UNORM:
2377 case WINED3DFMT_B5G6R5_UNORM:
2378 case WINED3DFMT_B4G4R4X4_UNORM:
2379 case WINED3DFMT_B4G4R4A4_UNORM:
2380 case WINED3DFMT_B2G3R3_UNORM:
2381 case WINED3DFMT_P8_UINT_A8_UNORM:
2382 case WINED3DFMT_P8_UINT:
2383 break;
2384 default:
2385 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
2386 return FALSE;
2389 *redSize = count_bits(format_desc->red_mask);
2390 *greenSize = count_bits(format_desc->green_mask);
2391 *blueSize = count_bits(format_desc->blue_mask);
2392 *alphaSize = count_bits(format_desc->alpha_mask);
2393 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2395 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
2396 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
2397 return TRUE;
2400 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2401 BOOL getDepthStencilBits(const struct wined3d_format_desc *format_desc, short *depthSize, short *stencilSize)
2403 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2404 switch(format_desc->format)
2406 case WINED3DFMT_D16_LOCKABLE:
2407 case WINED3DFMT_D16_UNORM:
2408 case WINED3DFMT_S1_UINT_D15_UNORM:
2409 case WINED3DFMT_X8D24_UNORM:
2410 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2411 case WINED3DFMT_D24_UNORM_S8_UINT:
2412 case WINED3DFMT_S8_UINT_D24_FLOAT:
2413 case WINED3DFMT_D32_UNORM:
2414 case WINED3DFMT_D32_FLOAT:
2415 break;
2416 default:
2417 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
2418 return FALSE;
2421 *depthSize = format_desc->depth_size;
2422 *stencilSize = format_desc->stencil_size;
2424 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
2425 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
2426 return TRUE;
2429 DWORD color_convert_argb_to_fmt(DWORD color, WINED3DFORMAT destfmt)
2431 unsigned int r, g, b, a;
2432 DWORD ret;
2434 if (destfmt == WINED3DFMT_B8G8R8A8_UNORM
2435 || destfmt == WINED3DFMT_B8G8R8X8_UNORM
2436 || destfmt == WINED3DFMT_B8G8R8_UNORM)
2437 return color;
2439 TRACE("Converting color %08x to format %s\n", color, debug_d3dformat(destfmt));
2441 a = (color & 0xff000000) >> 24;
2442 r = (color & 0x00ff0000) >> 16;
2443 g = (color & 0x0000ff00) >> 8;
2444 b = (color & 0x000000ff) >> 0;
2446 switch(destfmt)
2448 case WINED3DFMT_B5G6R5_UNORM:
2449 if(r == 0xff && g == 0xff && b == 0xff) return 0xffff;
2450 r = (r * 32) / 256;
2451 g = (g * 64) / 256;
2452 b = (b * 32) / 256;
2453 ret = r << 11;
2454 ret |= g << 5;
2455 ret |= b;
2456 TRACE("Returning %08x\n", ret);
2457 return ret;
2459 case WINED3DFMT_B5G5R5X1_UNORM:
2460 case WINED3DFMT_B5G5R5A1_UNORM:
2461 a = (a * 2) / 256;
2462 r = (r * 32) / 256;
2463 g = (g * 32) / 256;
2464 b = (b * 32) / 256;
2465 ret = a << 15;
2466 ret |= r << 10;
2467 ret |= g << 5;
2468 ret |= b << 0;
2469 TRACE("Returning %08x\n", ret);
2470 return ret;
2472 case WINED3DFMT_A8_UNORM:
2473 TRACE("Returning %08x\n", a);
2474 return a;
2476 case WINED3DFMT_B4G4R4X4_UNORM:
2477 case WINED3DFMT_B4G4R4A4_UNORM:
2478 a = (a * 16) / 256;
2479 r = (r * 16) / 256;
2480 g = (g * 16) / 256;
2481 b = (b * 16) / 256;
2482 ret = a << 12;
2483 ret |= r << 8;
2484 ret |= g << 4;
2485 ret |= b << 0;
2486 TRACE("Returning %08x\n", ret);
2487 return ret;
2489 case WINED3DFMT_B2G3R3_UNORM:
2490 r = (r * 8) / 256;
2491 g = (g * 8) / 256;
2492 b = (b * 4) / 256;
2493 ret = r << 5;
2494 ret |= g << 2;
2495 ret |= b << 0;
2496 TRACE("Returning %08x\n", ret);
2497 return ret;
2499 case WINED3DFMT_R8G8B8X8_UNORM:
2500 case WINED3DFMT_R8G8B8A8_UNORM:
2501 ret = a << 24;
2502 ret |= b << 16;
2503 ret |= g << 8;
2504 ret |= r << 0;
2505 TRACE("Returning %08x\n", ret);
2506 return ret;
2508 case WINED3DFMT_B10G10R10A2_UNORM:
2509 a = (a * 4) / 256;
2510 r = (r * 1024) / 256;
2511 g = (g * 1024) / 256;
2512 b = (b * 1024) / 256;
2513 ret = a << 30;
2514 ret |= r << 20;
2515 ret |= g << 10;
2516 ret |= b << 0;
2517 TRACE("Returning %08x\n", ret);
2518 return ret;
2520 case WINED3DFMT_R10G10B10A2_UNORM:
2521 a = (a * 4) / 256;
2522 r = (r * 1024) / 256;
2523 g = (g * 1024) / 256;
2524 b = (b * 1024) / 256;
2525 ret = a << 30;
2526 ret |= b << 20;
2527 ret |= g << 10;
2528 ret |= r << 0;
2529 TRACE("Returning %08x\n", ret);
2530 return ret;
2532 default:
2533 FIXME("Add a COLORFILL conversion for format %s\n", debug_d3dformat(destfmt));
2534 return 0;
2538 /* DirectDraw stuff */
2539 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2540 switch(depth) {
2541 case 8: return WINED3DFMT_P8_UINT;
2542 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2543 case 16: return WINED3DFMT_B5G6R5_UNORM;
2544 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2545 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2546 default: return WINED3DFMT_UNKNOWN;
2550 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2551 WINED3DMATRIX temp;
2553 /* Now do the multiplication 'by hand'.
2554 I know that all this could be optimised, but this will be done later :-) */
2555 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);
2556 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);
2557 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);
2558 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);
2560 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);
2561 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);
2562 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);
2563 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);
2565 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);
2566 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);
2567 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);
2568 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);
2570 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);
2571 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);
2572 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);
2573 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);
2575 /* And copy the new matrix in the good storage.. */
2576 memcpy(dest, &temp, 16 * sizeof(float));
2579 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2580 DWORD size = 0;
2581 int i;
2582 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2584 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2585 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2586 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2587 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2588 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2589 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2590 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2591 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2592 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2593 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2594 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2595 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2596 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2597 default: ERR("Unexpected position mask\n");
2599 for (i = 0; i < numTextures; i++) {
2600 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2603 return size;
2606 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2607 #define ARG1 0x01
2608 #define ARG2 0x02
2609 #define ARG0 0x04
2610 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2611 /* undefined */ 0,
2612 /* D3DTOP_DISABLE */ 0,
2613 /* D3DTOP_SELECTARG1 */ ARG1,
2614 /* D3DTOP_SELECTARG2 */ ARG2,
2615 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2616 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2617 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2618 /* D3DTOP_ADD */ ARG1 | ARG2,
2619 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2620 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2621 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2622 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2623 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2624 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2625 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2626 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2627 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2628 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2629 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2630 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2631 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2632 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2633 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2634 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2635 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2636 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2637 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2639 unsigned int i;
2640 DWORD ttff;
2641 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2642 IWineD3DDeviceImpl *device = stateblock->device;
2643 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2645 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2647 IWineD3DBaseTextureImpl *texture;
2648 settings->op[i].padding = 0;
2649 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2650 settings->op[i].cop = WINED3DTOP_DISABLE;
2651 settings->op[i].aop = WINED3DTOP_DISABLE;
2652 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2653 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2654 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2655 settings->op[i].dst = resultreg;
2656 settings->op[i].tex_type = tex_1d;
2657 settings->op[i].projected = proj_none;
2658 i++;
2659 break;
2662 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2663 if(texture) {
2664 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2665 if(ignore_textype) {
2666 settings->op[i].tex_type = tex_1d;
2667 } else {
2668 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2669 case GL_TEXTURE_1D:
2670 settings->op[i].tex_type = tex_1d;
2671 break;
2672 case GL_TEXTURE_2D:
2673 settings->op[i].tex_type = tex_2d;
2674 break;
2675 case GL_TEXTURE_3D:
2676 settings->op[i].tex_type = tex_3d;
2677 break;
2678 case GL_TEXTURE_CUBE_MAP_ARB:
2679 settings->op[i].tex_type = tex_cube;
2680 break;
2681 case GL_TEXTURE_RECTANGLE_ARB:
2682 settings->op[i].tex_type = tex_rect;
2683 break;
2686 } else {
2687 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2688 settings->op[i].tex_type = tex_1d;
2691 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2692 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2694 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2695 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2696 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2698 if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2699 carg0 = ARG_UNUSED;
2700 carg2 = ARG_UNUSED;
2701 carg1 = WINED3DTA_CURRENT;
2702 cop = WINED3DTOP_SELECTARG1;
2705 if(cop == WINED3DTOP_DOTPRODUCT3) {
2706 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2707 * the color result to the alpha component of the destination
2709 aop = cop;
2710 aarg1 = carg1;
2711 aarg2 = carg2;
2712 aarg0 = carg0;
2713 } else {
2714 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2715 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2716 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2719 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2721 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2723 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2725 IWineD3DSurfaceImpl *surf;
2726 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2728 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2730 if (aop == WINED3DTOP_DISABLE)
2732 aarg1 = WINED3DTA_TEXTURE;
2733 aop = WINED3DTOP_SELECTARG1;
2735 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2737 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2739 aarg2 = WINED3DTA_TEXTURE;
2740 aop = WINED3DTOP_MODULATE;
2742 else aarg1 = WINED3DTA_TEXTURE;
2744 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2746 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2748 aarg1 = WINED3DTA_TEXTURE;
2749 aop = WINED3DTOP_MODULATE;
2751 else aarg2 = WINED3DTA_TEXTURE;
2757 if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2758 aarg0 = ARG_UNUSED;
2759 aarg2 = ARG_UNUSED;
2760 aarg1 = WINED3DTA_CURRENT;
2761 aop = WINED3DTOP_SELECTARG1;
2764 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2765 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2766 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2767 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2768 settings->op[i].projected = proj_count3;
2769 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2770 settings->op[i].projected = proj_count4;
2771 } else {
2772 settings->op[i].projected = proj_none;
2774 } else {
2775 settings->op[i].projected = proj_none;
2778 settings->op[i].cop = cop;
2779 settings->op[i].aop = aop;
2780 settings->op[i].carg0 = carg0;
2781 settings->op[i].carg1 = carg1;
2782 settings->op[i].carg2 = carg2;
2783 settings->op[i].aarg0 = aarg0;
2784 settings->op[i].aarg1 = aarg1;
2785 settings->op[i].aarg2 = aarg2;
2787 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2788 settings->op[i].dst = tempreg;
2789 } else {
2790 settings->op[i].dst = resultreg;
2794 /* Clear unsupported stages */
2795 for(; i < MAX_TEXTURES; i++) {
2796 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2799 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2800 settings->fog = FOG_OFF;
2801 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2802 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2803 settings->fog = FOG_LINEAR;
2804 } else {
2805 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2806 case WINED3DFOG_NONE:
2807 case WINED3DFOG_LINEAR:
2808 settings->fog = FOG_LINEAR;
2809 break;
2810 case WINED3DFOG_EXP:
2811 settings->fog = FOG_EXP;
2812 break;
2813 case WINED3DFOG_EXP2:
2814 settings->fog = FOG_EXP2;
2815 break;
2818 } else {
2819 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2820 case WINED3DFOG_LINEAR:
2821 settings->fog = FOG_LINEAR;
2822 break;
2823 case WINED3DFOG_EXP:
2824 settings->fog = FOG_EXP;
2825 break;
2826 case WINED3DFOG_EXP2:
2827 settings->fog = FOG_EXP2;
2828 break;
2831 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2832 settings->sRGB_write = 1;
2833 } else {
2834 settings->sRGB_write = 0;
2836 if(device->vs_clipping || !use_vs(stateblock) || !stateblock->renderState[WINED3DRS_CLIPPING] ||
2837 !stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
2838 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2839 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2840 * if no clipplane is enabled
2842 settings->emul_clipplanes = 0;
2843 } else {
2844 settings->emul_clipplanes = 1;
2848 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2849 const struct ffp_frag_settings *settings)
2851 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2852 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2855 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2857 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2858 * whereas desc points to an extended structure with implementation specific parts. */
2859 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2861 ERR("Failed to insert ffp frag shader.\n");
2865 /* Activates the texture dimension according to the bound D3D texture.
2866 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2867 * Requires the caller to activate the correct unit before
2869 /* GL locking is done by the caller (state handler) */
2870 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2872 const struct wined3d_gl_info *gl_info = context->gl_info;
2874 if (stateblock->textures[stage])
2876 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2877 case GL_TEXTURE_2D:
2878 glDisable(GL_TEXTURE_3D);
2879 checkGLcall("glDisable(GL_TEXTURE_3D)");
2880 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2882 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2883 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2885 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2887 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2888 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2890 glEnable(GL_TEXTURE_2D);
2891 checkGLcall("glEnable(GL_TEXTURE_2D)");
2892 break;
2893 case GL_TEXTURE_RECTANGLE_ARB:
2894 glDisable(GL_TEXTURE_2D);
2895 checkGLcall("glDisable(GL_TEXTURE_2D)");
2896 glDisable(GL_TEXTURE_3D);
2897 checkGLcall("glDisable(GL_TEXTURE_3D)");
2898 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2900 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2901 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2903 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2904 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2905 break;
2906 case GL_TEXTURE_3D:
2907 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2909 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2910 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2912 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2914 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2915 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2917 glDisable(GL_TEXTURE_2D);
2918 checkGLcall("glDisable(GL_TEXTURE_2D)");
2919 glEnable(GL_TEXTURE_3D);
2920 checkGLcall("glEnable(GL_TEXTURE_3D)");
2921 break;
2922 case GL_TEXTURE_CUBE_MAP_ARB:
2923 glDisable(GL_TEXTURE_2D);
2924 checkGLcall("glDisable(GL_TEXTURE_2D)");
2925 glDisable(GL_TEXTURE_3D);
2926 checkGLcall("glDisable(GL_TEXTURE_3D)");
2927 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2929 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2930 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2932 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2933 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2934 break;
2936 } else {
2937 glEnable(GL_TEXTURE_2D);
2938 checkGLcall("glEnable(GL_TEXTURE_2D)");
2939 glDisable(GL_TEXTURE_3D);
2940 checkGLcall("glDisable(GL_TEXTURE_3D)");
2941 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2943 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2944 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2946 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2948 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2949 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2951 /* Binding textures is done by samplers. A dummy texture will be bound */
2955 /* GL locking is done by the caller (state handler) */
2956 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2958 DWORD sampler = state - STATE_SAMPLER(0);
2959 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
2961 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2962 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2963 * will take care of this business
2965 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
2966 if(sampler >= stateblock->lowest_disabled_stage) return;
2967 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2969 texture_activate_dimensions(sampler, stateblock, context);
2972 void *wined3d_rb_alloc(size_t size)
2974 return HeapAlloc(GetProcessHeap(), 0, size);
2977 void *wined3d_rb_realloc(void *ptr, size_t size)
2979 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
2982 void wined3d_rb_free(void *ptr)
2984 HeapFree(GetProcessHeap(), 0, ptr);
2987 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
2989 const struct ffp_frag_settings *ka = key;
2990 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
2992 return memcmp(ka, kb, sizeof(*ka));
2995 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
2997 wined3d_rb_alloc,
2998 wined3d_rb_realloc,
2999 wined3d_rb_free,
3000 ffp_frag_program_key_compare,
3003 UINT wined3d_log2i(UINT32 x)
3005 static const UINT l[] =
3007 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3008 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3009 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3010 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3011 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3012 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3013 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3014 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3015 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3016 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3017 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3018 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3019 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3020 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3021 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3022 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3024 UINT32 i;
3026 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3029 /* Set the shader type for this device, depending on the given capabilities
3030 * and the user preferences in wined3d_settings. */
3031 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3033 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3035 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3036 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3038 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3039 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3040 * shaders only on this card. */
3041 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3042 else *vs_selected = SHADER_GLSL;
3044 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3045 else *vs_selected = SHADER_NONE;
3047 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3048 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3049 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3050 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3051 else *ps_selected = SHADER_NONE;