msxml3: Add IObjectSafety support to IXMLHTTPRequest.
[wine.git] / dlls / wined3d / utils.c
blob220e5febdeaf277664d0586c38180cc2070b7d4e
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-2010 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 enum wined3d_format_id id;
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 /* format id 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_NVDB, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
133 {WINED3DFMT_INTZ, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
134 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
135 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
136 {WINED3DFMT_NULL, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
139 struct wined3d_format_base_flags
141 enum wined3d_format_id id;
142 DWORD flags;
145 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
146 * still needs to use the correct block based calculation for e.g. the
147 * resource size. */
148 static const struct wined3d_format_base_flags format_base_flags[] =
150 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
151 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
152 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
153 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
156 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
157 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
158 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
159 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
160 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
161 {WINED3DFMT_INTZ, WINED3DFMT_FLAG_FOURCC},
162 {WINED3DFMT_NULL, WINED3DFMT_FLAG_FOURCC},
163 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
164 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
165 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
166 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
171 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
172 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
173 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
174 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
175 {WINED3DFMT_NVDB, WINED3DFMT_FLAG_FOURCC},
176 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
177 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
178 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
179 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
181 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
182 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
184 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
185 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
186 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
189 struct wined3d_format_compression_info
191 enum wined3d_format_id id;
192 UINT block_width;
193 UINT block_height;
194 UINT block_byte_count;
197 static const struct wined3d_format_compression_info format_compression_info[] =
199 {WINED3DFMT_DXT1, 4, 4, 8},
200 {WINED3DFMT_DXT2, 4, 4, 16},
201 {WINED3DFMT_DXT3, 4, 4, 16},
202 {WINED3DFMT_DXT4, 4, 4, 16},
203 {WINED3DFMT_DXT5, 4, 4, 16},
204 {WINED3DFMT_ATI2N, 4, 4, 16},
207 struct wined3d_format_vertex_info
209 enum wined3d_format_id id;
210 enum wined3d_ffp_emit_idx emit_idx;
211 GLint component_count;
212 GLenum gl_vtx_type;
213 GLint gl_vtx_format;
214 GLboolean gl_normalized;
215 unsigned int component_size;
218 static const struct wined3d_format_vertex_info format_vertex_info[] =
220 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
221 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
222 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
223 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
224 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
225 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
226 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
227 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
228 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
229 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
230 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
231 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
232 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
233 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
234 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
235 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
236 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
239 struct wined3d_format_texture_info
241 enum wined3d_format_id id;
242 GLint gl_internal;
243 GLint gl_srgb_internal;
244 GLint gl_rt_internal;
245 GLint gl_format;
246 GLint gl_type;
247 unsigned int conv_byte_count;
248 unsigned int flags;
249 GL_SupportedExt extension;
250 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
253 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
255 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
256 * format+type combination to load it. Thus convert it to A8L8, then load it
257 * with A4L4 internal, but A8L8 format+type
259 unsigned int x, y;
260 const unsigned char *Source;
261 unsigned char *Dest;
262 UINT outpitch = pitch * 2;
264 for(y = 0; y < height; y++) {
265 Source = src + y * pitch;
266 Dest = dst + y * outpitch;
267 for (x = 0; x < width; x++ ) {
268 unsigned char color = (*Source++);
269 /* A */ Dest[1] = (color & 0xf0) << 0;
270 /* L */ Dest[0] = (color & 0x0f) << 4;
271 Dest += 2;
276 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
278 unsigned int x, y;
279 const WORD *Source;
281 for(y = 0; y < height; y++)
283 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
284 Source = (const WORD *)(src + y * pitch);
285 for (x = 0; x < width; x++ )
287 short color = (*Source++);
288 unsigned char l = ((color >> 10) & 0xfc);
289 short v = ((color >> 5) & 0x3e);
290 short u = ((color ) & 0x1f);
291 short v_conv = v + 16;
292 short u_conv = u + 16;
294 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
295 Dest_s += 1;
300 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
302 unsigned int x, y;
303 const WORD *Source;
304 unsigned char *Dest;
305 UINT outpitch = (pitch * 3)/2;
307 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
308 * fixed function and shaders without further conversion once the surface is
309 * loaded
311 for(y = 0; y < height; y++) {
312 Source = (const WORD *)(src + y * pitch);
313 Dest = dst + y * outpitch;
314 for (x = 0; x < width; x++ ) {
315 short color = (*Source++);
316 unsigned char l = ((color >> 10) & 0xfc);
317 char v = ((color >> 5) & 0x3e);
318 char u = ((color ) & 0x1f);
320 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
321 * and doubles the positive range. Thus shift left only once, gl does the 2nd
322 * shift. GL reads a signed value and converts it into an unsigned value.
324 /* M */ Dest[2] = l << 1;
326 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
327 * from 5 bit values to 8 bit values.
329 /* V */ Dest[1] = v << 3;
330 /* U */ Dest[0] = u << 3;
331 Dest += 3;
336 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
338 unsigned int x, y;
339 const short *Source;
340 unsigned char *Dest;
341 UINT outpitch = (pitch * 3)/2;
343 for(y = 0; y < height; y++)
345 Source = (const short *)(src + y * pitch);
346 Dest = dst + y * outpitch;
347 for (x = 0; x < width; x++ )
349 LONG color = (*Source++);
350 /* B */ Dest[0] = 0xff;
351 /* G */ Dest[1] = (color >> 8) + 128; /* V */
352 /* R */ Dest[2] = (color) + 128; /* U */
353 Dest += 3;
358 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
360 unsigned int x, y;
361 const DWORD *Source;
362 unsigned char *Dest;
364 /* Doesn't work correctly with the fixed function pipeline, but can work in
365 * shaders if the shader is adjusted. (There's no use for this format in gl's
366 * standard fixed function pipeline anyway).
368 for(y = 0; y < height; y++)
370 Source = (const DWORD *)(src + y * pitch);
371 Dest = dst + y * pitch;
372 for (x = 0; x < width; x++ )
374 LONG color = (*Source++);
375 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
376 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
377 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
378 Dest += 4;
383 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
385 unsigned int x, y;
386 const DWORD *Source;
387 unsigned char *Dest;
389 /* This implementation works with the fixed function pipeline and shaders
390 * without further modification after converting the surface.
392 for(y = 0; y < height; y++)
394 Source = (const DWORD *)(src + y * pitch);
395 Dest = dst + y * pitch;
396 for (x = 0; x < width; x++ )
398 LONG color = (*Source++);
399 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
400 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
401 /* U */ Dest[0] = (color & 0xff); /* U */
402 /* I */ Dest[3] = 255; /* X */
403 Dest += 4;
408 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
410 unsigned int x, y;
411 const DWORD *Source;
412 unsigned char *Dest;
414 for(y = 0; y < height; y++)
416 Source = (const DWORD *)(src + y * pitch);
417 Dest = dst + y * pitch;
418 for (x = 0; x < width; x++ )
420 LONG color = (*Source++);
421 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
422 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
423 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
424 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
425 Dest += 4;
430 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
432 unsigned int x, y;
433 const DWORD *Source;
434 unsigned short *Dest;
435 UINT outpitch = (pitch * 3)/2;
437 for(y = 0; y < height; y++)
439 Source = (const DWORD *)(src + y * pitch);
440 Dest = (unsigned short *) (dst + y * outpitch);
441 for (x = 0; x < width; x++ )
443 DWORD color = (*Source++);
444 /* B */ Dest[0] = 0xffff;
445 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
446 /* R */ Dest[2] = (color ) + 32768; /* U */
447 Dest += 3;
452 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
454 unsigned int x, y;
455 const WORD *Source;
456 WORD *Dest;
457 UINT outpitch = (pitch * 3)/2;
459 for(y = 0; y < height; y++)
461 Source = (const WORD *)(src + y * pitch);
462 Dest = (WORD *) (dst + y * outpitch);
463 for (x = 0; x < width; x++ )
465 WORD green = (*Source++);
466 WORD red = (*Source++);
467 Dest[0] = green;
468 Dest[1] = red;
469 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
470 * shader overwrites it anyway
472 Dest[2] = 0xffff;
473 Dest += 3;
478 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
480 unsigned int x, y;
481 const float *Source;
482 float *Dest;
483 UINT outpitch = (pitch * 3)/2;
485 for(y = 0; y < height; y++)
487 Source = (const float *)(src + y * pitch);
488 Dest = (float *) (dst + y * outpitch);
489 for (x = 0; x < width; x++ )
491 float green = (*Source++);
492 float red = (*Source++);
493 Dest[0] = green;
494 Dest[1] = red;
495 Dest[2] = 1.0f;
496 Dest += 3;
501 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
503 unsigned int x, y;
504 UINT outpitch = pitch * 2;
506 for (y = 0; y < height; ++y)
508 const WORD *source = (const WORD *)(src + y * pitch);
509 DWORD *dest = (DWORD *)(dst + y * outpitch);
511 for (x = 0; x < width; ++x)
513 /* The depth data is normalized, so needs to be scaled,
514 * the stencil data isn't. Scale depth data by
515 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
516 WORD d15 = source[x] >> 1;
517 DWORD d24 = (d15 << 9) + (d15 >> 6);
518 dest[x] = (d24 << 8) | (source[x] & 0x1);
523 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
525 unsigned int x, y;
527 for (y = 0; y < height; ++y)
529 const DWORD *source = (const DWORD *)(src + y * pitch);
530 DWORD *dest = (DWORD *)(dst + y * pitch);
532 for (x = 0; x < width; ++x)
534 /* Just need to clear out the X4 part. */
535 dest[x] = source[x] & ~0xf0;
540 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
542 unsigned int x, y;
543 UINT outpitch = pitch * 2;
545 for (y = 0; y < height; ++y)
547 const DWORD *source = (const DWORD *)(src + y * pitch);
548 float *dest_f = (float *)(dst + y * outpitch);
549 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
551 for (x = 0; x < width; ++x)
553 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
554 dest_s[x * 2 + 1] = source[x] & 0xff;
559 static const struct wined3d_format_texture_info format_texture_info[] =
561 /* format id internal srgbInternal rtInternal
562 format type
563 flags
564 extension */
565 /* FourCC formats */
566 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
567 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
568 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
569 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
570 * endian machine
572 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
573 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
574 WINED3DFMT_FLAG_FILTERING,
575 WINED3D_GL_EXT_NONE, NULL},
576 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
577 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
578 WINED3DFMT_FLAG_FILTERING,
579 APPLE_YCBCR_422, NULL},
580 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
581 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
582 WINED3DFMT_FLAG_FILTERING,
583 WINED3D_GL_EXT_NONE, NULL},
584 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
585 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
586 WINED3DFMT_FLAG_FILTERING,
587 APPLE_YCBCR_422, NULL},
588 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
589 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
590 WINED3DFMT_FLAG_FILTERING,
591 WINED3D_GL_EXT_NONE, NULL},
592 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
593 GL_RGBA, GL_UNSIGNED_BYTE, 0,
594 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
595 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
596 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
597 GL_RGBA, GL_UNSIGNED_BYTE, 0,
598 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
599 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
600 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
601 GL_RGBA, GL_UNSIGNED_BYTE, 0,
602 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
603 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
604 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
605 GL_RGBA, GL_UNSIGNED_BYTE, 0,
606 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
607 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
608 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
609 GL_RGBA, GL_UNSIGNED_BYTE, 0,
610 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
611 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
612 /* IEEE formats */
613 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
614 GL_RED, GL_FLOAT, 0,
615 WINED3DFMT_FLAG_RENDERTARGET,
616 ARB_TEXTURE_FLOAT, NULL},
617 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
618 GL_RED, GL_FLOAT, 0,
619 WINED3DFMT_FLAG_RENDERTARGET,
620 ARB_TEXTURE_RG, NULL},
621 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
622 GL_RGB, GL_FLOAT, 12,
623 WINED3DFMT_FLAG_RENDERTARGET,
624 ARB_TEXTURE_FLOAT, &convert_r32g32_float},
625 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
626 GL_RG, GL_FLOAT, 0,
627 WINED3DFMT_FLAG_RENDERTARGET,
628 ARB_TEXTURE_RG, NULL},
629 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
630 GL_RGBA, GL_FLOAT, 0,
631 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
632 ARB_TEXTURE_FLOAT, NULL},
633 /* Float */
634 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
635 GL_RED, GL_HALF_FLOAT_ARB, 0,
636 WINED3DFMT_FLAG_RENDERTARGET,
637 ARB_TEXTURE_FLOAT, NULL},
638 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
639 GL_RED, GL_HALF_FLOAT_ARB, 0,
640 WINED3DFMT_FLAG_RENDERTARGET,
641 ARB_TEXTURE_RG, NULL},
642 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
643 GL_RGB, GL_HALF_FLOAT_ARB, 6,
644 WINED3DFMT_FLAG_RENDERTARGET,
645 ARB_TEXTURE_FLOAT, &convert_r16g16},
646 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
647 GL_RG, GL_HALF_FLOAT_ARB, 0,
648 WINED3DFMT_FLAG_RENDERTARGET,
649 ARB_TEXTURE_RG, NULL},
650 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
651 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
652 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
653 ARB_TEXTURE_FLOAT, NULL},
654 /* Palettized formats */
655 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
656 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
658 ARB_FRAGMENT_PROGRAM, NULL},
659 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
660 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
662 EXT_PALETTED_TEXTURE, NULL},
663 /* Standard ARGB formats */
664 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
665 GL_BGR, GL_UNSIGNED_BYTE, 0,
666 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
667 WINED3D_GL_EXT_NONE, NULL},
668 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
669 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
670 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
671 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
672 WINED3D_GL_EXT_NONE, NULL},
673 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
674 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
675 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
676 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
677 WINED3D_GL_EXT_NONE, NULL},
678 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
679 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
680 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
681 WINED3D_GL_EXT_NONE, NULL},
682 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
683 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
684 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
685 WINED3D_GL_EXT_NONE, NULL},
686 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
687 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
688 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
689 WINED3D_GL_EXT_NONE, NULL},
690 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
691 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
692 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
693 WINED3D_GL_EXT_NONE, NULL},
694 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
695 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
696 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
697 WINED3D_GL_EXT_NONE, NULL},
698 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
699 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
700 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
701 WINED3D_GL_EXT_NONE, NULL},
702 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
703 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
704 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
705 WINED3D_GL_EXT_NONE, NULL},
706 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
707 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
708 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
709 WINED3D_GL_EXT_NONE, NULL},
710 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
711 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
712 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
713 WINED3D_GL_EXT_NONE, NULL},
714 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
715 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
716 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
717 WINED3D_GL_EXT_NONE, NULL},
718 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
719 GL_RGB, GL_UNSIGNED_SHORT, 6,
720 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
721 WINED3D_GL_EXT_NONE, &convert_r16g16},
722 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
723 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
724 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
725 WINED3D_GL_EXT_NONE, NULL},
726 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
727 GL_RGBA, GL_UNSIGNED_SHORT, 0,
728 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
729 WINED3D_GL_EXT_NONE, NULL},
730 /* Luminance */
731 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
732 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
733 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
734 WINED3D_GL_EXT_NONE, NULL},
735 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
736 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
737 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
738 WINED3D_GL_EXT_NONE, NULL},
739 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
740 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
742 WINED3D_GL_EXT_NONE, &convert_l4a4_unorm},
743 /* Bump mapping stuff */
744 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
745 GL_BGR, GL_UNSIGNED_BYTE, 3,
746 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
747 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm},
748 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
749 GL_DSDT_NV, GL_BYTE, 0,
750 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
751 NV_TEXTURE_SHADER, NULL},
752 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
753 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
754 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
755 WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm},
756 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
757 GL_DSDT_MAG_NV, GL_BYTE, 3,
758 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
759 NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv},
760 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
761 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
762 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
763 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm},
764 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
765 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
766 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
767 NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv},
768 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
769 GL_BGRA, GL_UNSIGNED_BYTE, 4,
770 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
771 WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm},
772 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
773 GL_RGBA, GL_BYTE, 0,
774 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
775 NV_TEXTURE_SHADER, NULL},
776 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
777 GL_BGR, GL_UNSIGNED_SHORT, 6,
778 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
779 WINED3D_GL_EXT_NONE, &convert_r16g16_snorm},
780 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
781 GL_HILO_NV, GL_SHORT, 0,
782 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
783 NV_TEXTURE_SHADER, NULL},
784 /* Depth stencil formats */
785 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
786 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
787 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
788 ARB_DEPTH_TEXTURE, NULL},
789 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
790 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
791 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
792 ARB_DEPTH_TEXTURE, NULL},
793 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
794 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
795 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
796 ARB_DEPTH_TEXTURE, NULL},
797 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
798 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
799 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
800 EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm},
801 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
802 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
803 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
804 ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm},
805 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
806 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
807 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
808 | WINED3DFMT_FLAG_SHADOW,
809 ARB_DEPTH_TEXTURE, NULL},
810 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
811 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
812 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
813 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
814 EXT_PACKED_DEPTH_STENCIL, NULL},
815 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
816 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
817 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
818 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
819 ARB_FRAMEBUFFER_OBJECT, NULL},
820 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
821 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
822 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
823 | WINED3DFMT_FLAG_SHADOW,
824 ARB_DEPTH_TEXTURE, NULL},
825 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
826 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
827 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
828 ARB_DEPTH_TEXTURE, NULL},
829 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
830 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
831 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
832 EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm},
833 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
834 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
835 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
836 ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm},
837 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
838 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
839 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
840 | WINED3DFMT_FLAG_SHADOW,
841 ARB_DEPTH_TEXTURE, NULL},
842 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
843 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
844 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
845 WINED3D_GL_EXT_NONE, NULL},
846 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
847 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
848 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
849 ARB_DEPTH_BUFFER_FLOAT, NULL},
850 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
851 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
852 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
853 ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float},
854 /* Vendor-specific formats */
855 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
856 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
857 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
858 ATI_TEXTURE_COMPRESSION_3DC, NULL},
859 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2, GL_COMPRESSED_RED_GREEN_RGTC2, 0,
860 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
861 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
862 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
863 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
864 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
865 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
866 | WINED3DFMT_FLAG_STENCIL,
867 EXT_PACKED_DEPTH_STENCIL, NULL},
868 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
869 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
870 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
871 | WINED3DFMT_FLAG_STENCIL,
872 ARB_FRAMEBUFFER_OBJECT, NULL},
873 {WINED3DFMT_NULL, GL_RGBA8, GL_RGBA8, 0,
874 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
875 WINED3DFMT_FLAG_RENDERTARGET,
876 ARB_FRAMEBUFFER_OBJECT, NULL},
879 static inline int getFmtIdx(enum wined3d_format_id format_id)
881 /* First check if the format is at the position of its value.
882 * This will catch the argb formats before the loop is entered. */
883 if (format_id < (sizeof(formats) / sizeof(*formats))
884 && formats[format_id].id == format_id)
886 return format_id;
888 else
890 unsigned int i;
892 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
894 if (formats[i].id == format_id) return i;
897 return -1;
900 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
902 UINT format_count = sizeof(formats) / sizeof(*formats);
903 UINT i;
905 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
906 if (!gl_info->formats)
908 ERR("Failed to allocate memory.\n");
909 return FALSE;
912 for (i = 0; i < format_count; ++i)
914 struct wined3d_format *format = &gl_info->formats[i];
915 format->id = formats[i].id;
916 format->red_mask = formats[i].redMask;
917 format->green_mask = formats[i].greenMask;
918 format->blue_mask = formats[i].blueMask;
919 format->alpha_mask = formats[i].alphaMask;
920 format->byte_count = formats[i].bpp;
921 format->depth_size = formats[i].depthSize;
922 format->stencil_size = formats[i].stencilSize;
925 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
927 int fmt_idx = getFmtIdx(format_base_flags[i].id);
929 if (fmt_idx == -1)
931 ERR("Format %s (%#x) not found.\n",
932 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
933 HeapFree(GetProcessHeap(), 0, gl_info->formats);
934 return FALSE;
937 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
940 return TRUE;
943 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
945 unsigned int i;
947 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
949 struct wined3d_format *format;
950 int fmt_idx = getFmtIdx(format_compression_info[i].id);
952 if (fmt_idx == -1)
954 ERR("Format %s (%#x) not found.\n",
955 debug_d3dformat(format_compression_info[i].id), format_compression_info[i].id);
956 return FALSE;
959 format = &gl_info->formats[fmt_idx];
960 format->block_width = format_compression_info[i].block_width;
961 format->block_height = format_compression_info[i].block_height;
962 format->block_byte_count = format_compression_info[i].block_byte_count;
963 format->flags |= WINED3DFMT_FLAG_COMPRESSED;
966 return TRUE;
969 /* Context activation is done by the caller. */
970 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
972 /* Check if the default internal format is supported as a frame buffer
973 * target, otherwise fall back to the render target internal.
975 * Try to stick to the standard format if possible, this limits precision differences. */
976 GLenum status;
977 GLuint tex;
979 ENTER_GL();
981 while(glGetError());
982 glDisable(GL_BLEND);
984 glGenTextures(1, &tex);
985 glBindTexture(GL_TEXTURE_2D, tex);
987 glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
988 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
989 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
991 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
993 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
994 checkGLcall("Framebuffer format check");
996 if (status == GL_FRAMEBUFFER_COMPLETE)
998 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
999 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1000 format->rtInternal = format->glInternal;
1002 else
1004 if (!format->rtInternal)
1006 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1008 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1009 " and no fallback specified.\n", debug_d3dformat(format->id));
1010 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1012 else
1014 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1016 format->rtInternal = format->glInternal;
1018 else
1020 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1021 debug_d3dformat(format->id));
1023 while(glGetError());
1025 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1027 glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1028 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1029 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1031 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1033 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1034 checkGLcall("Framebuffer format check");
1036 if (status == GL_FRAMEBUFFER_COMPLETE)
1038 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1039 debug_d3dformat(format->id));
1041 else
1043 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1044 debug_d3dformat(format->id));
1045 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1050 if (status == GL_FRAMEBUFFER_COMPLETE && format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1052 GLuint rb;
1054 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1055 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1057 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1058 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1059 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1060 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1061 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1062 checkGLcall("RB attachment");
1065 glEnable(GL_BLEND);
1066 glClear(GL_COLOR_BUFFER_BIT);
1067 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1069 while(glGetError());
1070 TRACE("Format doesn't support post-pixelshader blending.\n");
1071 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1074 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1075 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1077 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1078 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1079 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1080 checkGLcall("RB cleanup");
1084 if (format->glInternal != format->glGammaInternal)
1086 glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1087 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1089 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1090 checkGLcall("Framebuffer format check");
1092 if (status == GL_FRAMEBUFFER_COMPLETE)
1094 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1095 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1097 else
1099 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1103 glDeleteTextures(1, &tex);
1105 LEAVE_GL();
1108 /* Context activation is done by the caller. */
1109 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1111 unsigned int i;
1112 GLuint fbo;
1114 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1116 ENTER_GL();
1118 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1119 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1121 LEAVE_GL();
1124 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1126 struct wined3d_format *format = &gl_info->formats[i];
1128 if (!format->glInternal) continue;
1130 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1132 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1133 debug_d3dformat(format->id));
1134 continue;
1137 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1139 TRACE("Skipping format %s because it's a compressed format.\n",
1140 debug_d3dformat(format->id));
1141 continue;
1144 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1146 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1147 check_fbo_compat(gl_info, format);
1149 else
1151 format->rtInternal = format->glInternal;
1155 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1157 ENTER_GL();
1159 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1161 LEAVE_GL();
1165 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1167 unsigned int i;
1169 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1171 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1172 struct wined3d_format *format;
1174 if (fmt_idx == -1)
1176 ERR("Format %s (%#x) not found.\n",
1177 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1178 return FALSE;
1181 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1183 format = &gl_info->formats[fmt_idx];
1185 /* ARB_texture_rg defines floating point formats, but only if
1186 * ARB_texture_float is also supported. */
1187 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1188 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1189 continue;
1191 format->glInternal = format_texture_info[i].gl_internal;
1192 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1193 format->rtInternal = format_texture_info[i].gl_rt_internal;
1194 format->glFormat = format_texture_info[i].gl_format;
1195 format->glType = format_texture_info[i].gl_type;
1196 format->color_fixup = COLOR_FIXUP_IDENTITY;
1197 format->flags |= format_texture_info[i].flags;
1198 format->heightscale = 1.0f;
1200 /* Texture conversion stuff */
1201 format->convert = format_texture_info[i].convert;
1202 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1205 return TRUE;
1208 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1210 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1211 c1 >>= 8; c2 >>= 8;
1212 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1213 c1 >>= 8; c2 >>= 8;
1214 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1215 c1 >>= 8; c2 >>= 8;
1216 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1217 return TRUE;
1220 /* A context is provided by the caller */
1221 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1223 static const DWORD data[] = {0x00000000, 0xffffffff};
1224 GLuint tex, fbo, buffer;
1225 DWORD readback[16 * 1];
1226 BOOL ret = FALSE;
1228 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1229 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1230 * falling back to software. If this changes in the future this code will get fooled and
1231 * apps might hit the software path due to incorrectly advertised caps.
1233 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1234 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1235 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1238 ENTER_GL();
1239 while(glGetError());
1241 glGenTextures(1, &buffer);
1242 glBindTexture(GL_TEXTURE_2D, buffer);
1243 memset(readback, 0x7e, sizeof(readback));
1244 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1245 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1246 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1247 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1248 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1249 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1251 glGenTextures(1, &tex);
1252 glBindTexture(GL_TEXTURE_2D, tex);
1253 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1254 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1255 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1256 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1257 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1258 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1259 glEnable(GL_TEXTURE_2D);
1261 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1262 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1263 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1264 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1266 glViewport(0, 0, 16, 1);
1267 glDisable(GL_LIGHTING);
1268 glMatrixMode(GL_MODELVIEW);
1269 glLoadIdentity();
1270 glMatrixMode(GL_PROJECTION);
1271 glLoadIdentity();
1273 glClearColor(0, 1, 0, 0);
1274 glClear(GL_COLOR_BUFFER_BIT);
1276 glBegin(GL_TRIANGLE_STRIP);
1277 glTexCoord2f(0.0, 0.0);
1278 glVertex2f(-1.0f, -1.0f);
1279 glTexCoord2f(1.0, 0.0);
1280 glVertex2f(1.0f, -1.0f);
1281 glTexCoord2f(0.0, 1.0);
1282 glVertex2f(-1.0f, 1.0f);
1283 glTexCoord2f(1.0, 1.0);
1284 glVertex2f(1.0f, 1.0f);
1285 glEnd();
1287 glBindTexture(GL_TEXTURE_2D, buffer);
1288 memset(readback, 0x7f, sizeof(readback));
1289 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1290 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1291 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1293 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1294 readback[6], readback[9]);
1295 ret = FALSE;
1297 else
1299 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1300 readback[6], readback[9]);
1301 ret = TRUE;
1304 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1305 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1306 glDeleteTextures(1, &tex);
1307 glDeleteTextures(1, &buffer);
1309 if(glGetError())
1311 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1312 ret = FALSE;
1314 LEAVE_GL();
1315 return ret;
1318 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1320 struct wined3d_format *format;
1321 unsigned int fmt_idx, i;
1322 static const enum wined3d_format_id fmts16[] =
1324 WINED3DFMT_R16_FLOAT,
1325 WINED3DFMT_R16G16_FLOAT,
1326 WINED3DFMT_R16G16B16A16_FLOAT,
1328 BOOL filtered;
1330 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1332 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1333 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1335 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1336 filtered = TRUE;
1338 else if (gl_info->limits.glsl_varyings > 44)
1340 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1341 filtered = TRUE;
1343 else
1345 TRACE("Assuming no float16 blending\n");
1346 filtered = FALSE;
1349 if(filtered)
1351 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1353 fmt_idx = getFmtIdx(fmts16[i]);
1354 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1357 return;
1360 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1362 fmt_idx = getFmtIdx(fmts16[i]);
1363 format = &gl_info->formats[fmt_idx];
1364 if (!format->glInternal) continue; /* Not supported by GL */
1366 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1367 if(filtered)
1369 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1370 format->flags |= WINED3DFMT_FLAG_FILTERING;
1372 else
1374 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1379 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1381 int idx;
1383 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1384 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1385 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1387 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1388 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1389 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1391 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1392 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1393 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1395 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1396 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1397 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1399 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1400 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1401 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1403 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1404 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1405 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1406 * the only driver that implements it(fglrx) has a buggy implementation.
1408 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1409 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1410 * conversion for this format.
1412 if (!gl_info->supported[NV_TEXTURE_SHADER])
1414 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1415 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1416 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1417 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1418 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1419 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1421 else
1423 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1424 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1425 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1427 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1428 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1429 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1432 if (!gl_info->supported[NV_TEXTURE_SHADER])
1434 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1435 * with each other
1437 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1438 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1439 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1440 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1441 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1442 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1443 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1444 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1445 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1447 else
1449 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1450 * are converted at surface loading time, but they do not need any modification in
1451 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1452 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1456 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1458 idx = getFmtIdx(WINED3DFMT_ATI2N);
1459 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1460 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1462 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1464 idx = getFmtIdx(WINED3DFMT_ATI2N);
1465 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1466 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1469 if (!gl_info->supported[APPLE_YCBCR_422])
1471 idx = getFmtIdx(WINED3DFMT_YUY2);
1472 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1474 idx = getFmtIdx(WINED3DFMT_UYVY);
1475 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1478 idx = getFmtIdx(WINED3DFMT_YV12);
1479 gl_info->formats[idx].heightscale = 1.5f;
1480 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1482 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1484 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1485 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1488 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1490 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1491 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1494 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1496 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1497 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1498 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1499 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1501 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1502 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1506 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1508 unsigned int i;
1510 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1512 struct wined3d_format *format;
1513 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1515 if (fmt_idx == -1)
1517 ERR("Format %s (%#x) not found.\n",
1518 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1519 return FALSE;
1522 format = &gl_info->formats[fmt_idx];
1523 format->emit_idx = format_vertex_info[i].emit_idx;
1524 format->component_count = format_vertex_info[i].component_count;
1525 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1526 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1527 format->gl_normalized = format_vertex_info[i].gl_normalized;
1528 format->component_size = format_vertex_info[i].component_size;
1531 return TRUE;
1534 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1536 if (!init_format_base_info(gl_info)) return FALSE;
1538 if (!init_format_compression_info(gl_info))
1540 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1541 gl_info->formats = NULL;
1542 return FALSE;
1545 return TRUE;
1548 /* Context activation is done by the caller. */
1549 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1551 if (!init_format_base_info(gl_info)) return FALSE;
1553 if (!init_format_compression_info(gl_info)) goto fail;
1554 if (!init_format_texture_info(gl_info)) goto fail;
1555 if (!init_format_vertex_info(gl_info)) goto fail;
1557 apply_format_fixups(gl_info);
1558 init_format_fbo_compat_info(gl_info);
1559 init_format_filter_info(gl_info, vendor);
1561 return TRUE;
1563 fail:
1564 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1565 gl_info->formats = NULL;
1566 return FALSE;
1569 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1570 enum wined3d_format_id format_id)
1572 int idx = getFmtIdx(format_id);
1574 if (idx == -1)
1576 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1577 debug_d3dformat(format_id), format_id);
1578 /* Get the caller a valid pointer */
1579 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1582 return &gl_info->formats[idx];
1585 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1587 UINT size;
1589 if (format->id == WINED3DFMT_UNKNOWN)
1591 size = 0;
1593 else if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1595 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1596 UINT row_count = (height + format->block_height - 1) / format->block_height;
1597 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1599 else
1601 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1604 if (format->heightscale != 0.0f) size *= format->heightscale;
1606 return size;
1609 /*****************************************************************************
1610 * Trace formatting of useful values
1612 const char *debug_d3dformat(enum wined3d_format_id format_id)
1614 switch (format_id)
1616 #define FMT_TO_STR(format_id) case format_id: return #format_id
1617 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1618 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1619 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1620 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1621 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1622 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1623 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1624 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1625 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1626 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1627 FMT_TO_STR(WINED3DFMT_P8_UINT);
1628 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1629 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1630 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1631 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1632 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1633 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1634 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1635 FMT_TO_STR(WINED3DFMT_UYVY);
1636 FMT_TO_STR(WINED3DFMT_YUY2);
1637 FMT_TO_STR(WINED3DFMT_YV12);
1638 FMT_TO_STR(WINED3DFMT_DXT1);
1639 FMT_TO_STR(WINED3DFMT_DXT2);
1640 FMT_TO_STR(WINED3DFMT_DXT3);
1641 FMT_TO_STR(WINED3DFMT_DXT4);
1642 FMT_TO_STR(WINED3DFMT_DXT5);
1643 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1644 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1645 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1646 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1647 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1648 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1649 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1650 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1651 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1652 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1653 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1654 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1655 FMT_TO_STR(WINED3DFMT_ATI2N);
1656 FMT_TO_STR(WINED3DFMT_NVDB);
1657 FMT_TO_STR(WINED3DFMT_NVHU);
1658 FMT_TO_STR(WINED3DFMT_NVHS);
1659 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1660 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1661 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1662 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1663 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1664 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1665 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1666 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1667 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1668 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1669 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1670 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1671 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1672 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1673 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1674 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1675 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1676 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1677 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1678 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1679 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1680 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1681 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1682 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1683 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1684 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1685 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1686 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1687 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1688 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1689 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1690 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1691 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1692 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1693 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1694 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1695 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1696 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1697 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1698 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1699 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1700 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1701 FMT_TO_STR(WINED3DFMT_R32_UINT);
1702 FMT_TO_STR(WINED3DFMT_R32_SINT);
1703 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1704 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1705 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1706 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1707 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1708 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1709 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1710 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1711 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1712 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1713 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1714 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1715 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1716 FMT_TO_STR(WINED3DFMT_R16_UINT);
1717 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1718 FMT_TO_STR(WINED3DFMT_R16_SINT);
1719 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1720 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1721 FMT_TO_STR(WINED3DFMT_R8_UINT);
1722 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1723 FMT_TO_STR(WINED3DFMT_R8_SINT);
1724 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1725 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1726 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1727 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1728 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1729 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1730 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1731 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1732 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1733 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1734 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1735 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1736 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1737 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1738 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1739 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1740 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1741 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1742 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1743 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1744 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1745 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1746 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1747 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1748 FMT_TO_STR(WINED3DFMT_INTZ);
1749 FMT_TO_STR(WINED3DFMT_NULL);
1750 #undef FMT_TO_STR
1751 default:
1753 char fourcc[5];
1754 fourcc[0] = (char)(format_id);
1755 fourcc[1] = (char)(format_id >> 8);
1756 fourcc[2] = (char)(format_id >> 16);
1757 fourcc[3] = (char)(format_id >> 24);
1758 fourcc[4] = 0;
1759 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1760 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1761 else
1762 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1764 return "unrecognized";
1768 const char *debug_d3ddevicetype(WINED3DDEVTYPE devtype)
1770 switch (devtype)
1772 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1773 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1774 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1775 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1776 #undef DEVTYPE_TO_STR
1777 default:
1778 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1779 return "unrecognized";
1783 const char *debug_d3dusage(DWORD usage)
1785 char buf[333];
1787 buf[0] = '\0';
1788 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1789 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1790 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1791 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1792 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1793 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1794 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1795 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1796 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1797 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1798 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1799 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1800 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1801 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1802 #undef WINED3DUSAGE_TO_STR
1803 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1805 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1808 const char *debug_d3dusagequery(DWORD usagequery)
1810 char buf[238];
1812 buf[0] = '\0';
1813 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1814 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1815 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1816 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1817 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1818 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1819 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1820 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1821 #undef WINED3DUSAGEQUERY_TO_STR
1822 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1824 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1827 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1828 switch (method) {
1829 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1830 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1831 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1832 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1833 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1834 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1835 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1836 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1837 #undef WINED3DDECLMETHOD_TO_STR
1838 default:
1839 FIXME("Unrecognized %u declaration method!\n", method);
1840 return "unrecognized";
1844 const char* debug_d3ddeclusage(BYTE usage) {
1845 switch (usage) {
1846 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1847 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1848 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1849 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1850 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1851 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1852 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1853 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1854 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1855 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1856 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1857 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1858 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1859 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1860 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1861 #undef WINED3DDECLUSAGE_TO_STR
1862 default:
1863 FIXME("Unrecognized %u declaration usage!\n", usage);
1864 return "unrecognized";
1868 const char *debug_d3dresourcetype(WINED3DRESOURCETYPE res)
1870 switch (res)
1872 #define RES_TO_STR(res) case res: return #res
1873 RES_TO_STR(WINED3DRTYPE_SURFACE);
1874 RES_TO_STR(WINED3DRTYPE_VOLUME);
1875 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1876 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1877 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1878 RES_TO_STR(WINED3DRTYPE_BUFFER);
1879 #undef RES_TO_STR
1880 default:
1881 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1882 return "unrecognized";
1886 const char *debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType)
1888 switch (PrimitiveType)
1890 #define PRIM_TO_STR(prim) case prim: return #prim
1891 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1892 PRIM_TO_STR(WINED3DPT_POINTLIST);
1893 PRIM_TO_STR(WINED3DPT_LINELIST);
1894 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1895 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1896 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1897 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1898 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1899 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1900 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1901 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1902 #undef PRIM_TO_STR
1903 default:
1904 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1905 return "unrecognized";
1909 const char *debug_d3drenderstate(WINED3DRENDERSTATETYPE state)
1911 switch (state)
1913 #define D3DSTATE_TO_STR(u) case u: return #u
1914 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS);
1915 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE);
1916 D3DSTATE_TO_STR(WINED3DRS_WRAPU);
1917 D3DSTATE_TO_STR(WINED3DRS_WRAPV);
1918 D3DSTATE_TO_STR(WINED3DRS_ZENABLE);
1919 D3DSTATE_TO_STR(WINED3DRS_FILLMODE);
1920 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE);
1921 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN);
1922 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE);
1923 D3DSTATE_TO_STR(WINED3DRS_ROP2);
1924 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK);
1925 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE);
1926 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE);
1927 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL);
1928 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND);
1929 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND);
1930 D3DSTATE_TO_STR(WINED3DRS_CULLMODE);
1931 D3DSTATE_TO_STR(WINED3DRS_ZFUNC);
1932 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF);
1933 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC);
1934 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE);
1935 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE);
1936 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE);
1937 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE);
1938 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE);
1939 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL);
1940 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX);
1941 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA);
1942 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR);
1943 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE);
1944 D3DSTATE_TO_STR(WINED3DRS_FOGSTART);
1945 D3DSTATE_TO_STR(WINED3DRS_FOGEND);
1946 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY);
1947 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE);
1948 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS);
1949 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE);
1950 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS);
1951 D3DSTATE_TO_STR(WINED3DRS_ZBIAS);
1952 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE);
1953 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY);
1954 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH);
1955 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1956 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE);
1957 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL);
1958 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL);
1959 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS);
1960 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC);
1961 D3DSTATE_TO_STR(WINED3DRS_STENCILREF);
1962 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK);
1963 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK);
1964 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR);
1965 D3DSTATE_TO_STR(WINED3DRS_WRAP0);
1966 D3DSTATE_TO_STR(WINED3DRS_WRAP1);
1967 D3DSTATE_TO_STR(WINED3DRS_WRAP2);
1968 D3DSTATE_TO_STR(WINED3DRS_WRAP3);
1969 D3DSTATE_TO_STR(WINED3DRS_WRAP4);
1970 D3DSTATE_TO_STR(WINED3DRS_WRAP5);
1971 D3DSTATE_TO_STR(WINED3DRS_WRAP6);
1972 D3DSTATE_TO_STR(WINED3DRS_WRAP7);
1973 D3DSTATE_TO_STR(WINED3DRS_CLIPPING);
1974 D3DSTATE_TO_STR(WINED3DRS_LIGHTING);
1975 D3DSTATE_TO_STR(WINED3DRS_EXTENTS);
1976 D3DSTATE_TO_STR(WINED3DRS_AMBIENT);
1977 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE);
1978 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX);
1979 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER);
1980 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS);
1981 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE);
1982 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE);
1983 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE);
1984 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE);
1985 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE);
1986 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND);
1987 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE);
1988 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING);
1989 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE);
1990 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN);
1991 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE);
1992 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE);
1993 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A);
1994 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B);
1995 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C);
1996 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS);
1997 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK);
1998 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE);
1999 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS);
2000 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN);
2001 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX);
2002 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE);
2003 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE);
2004 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR);
2005 D3DSTATE_TO_STR(WINED3DRS_BLENDOP);
2006 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE);
2007 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE);
2008 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE);
2009 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS);
2010 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE);
2011 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL);
2012 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL);
2013 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X);
2014 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y);
2015 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z);
2016 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W);
2017 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
2018 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE);
2019 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL);
2020 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL);
2021 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS);
2022 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC);
2023 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1);
2024 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2);
2025 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3);
2026 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR);
2027 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE);
2028 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS);
2029 D3DSTATE_TO_STR(WINED3DRS_WRAP8);
2030 D3DSTATE_TO_STR(WINED3DRS_WRAP9);
2031 D3DSTATE_TO_STR(WINED3DRS_WRAP10);
2032 D3DSTATE_TO_STR(WINED3DRS_WRAP11);
2033 D3DSTATE_TO_STR(WINED3DRS_WRAP12);
2034 D3DSTATE_TO_STR(WINED3DRS_WRAP13);
2035 D3DSTATE_TO_STR(WINED3DRS_WRAP14);
2036 D3DSTATE_TO_STR(WINED3DRS_WRAP15);
2037 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE);
2038 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA);
2039 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA);
2040 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA);
2041 #undef D3DSTATE_TO_STR
2042 default:
2043 FIXME("Unrecognized %u render state!\n", state);
2044 return "unrecognized";
2048 const char *debug_d3dsamplerstate(DWORD state)
2050 switch (state)
2052 #define D3DSTATE_TO_STR(u) case u: return #u
2053 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR);
2054 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU);
2055 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV);
2056 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW);
2057 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER);
2058 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER);
2059 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER);
2060 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
2061 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL);
2062 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
2063 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE);
2064 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX);
2065 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET);
2066 #undef D3DSTATE_TO_STR
2067 default:
2068 FIXME("Unrecognized %u sampler state!\n", state);
2069 return "unrecognized";
2073 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2074 switch (filter_type) {
2075 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2076 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2077 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2078 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2079 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2080 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2081 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2082 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2083 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2084 #undef D3DTEXTUREFILTERTYPE_TO_STR
2085 default:
2086 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2087 return "unrecognized";
2091 const char *debug_d3dtexturestate(DWORD state)
2093 switch (state)
2095 #define D3DSTATE_TO_STR(u) case u: return #u
2096 D3DSTATE_TO_STR(WINED3DTSS_COLOROP);
2097 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1);
2098 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2);
2099 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP);
2100 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1);
2101 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2);
2102 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00);
2103 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01);
2104 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10);
2105 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11);
2106 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX);
2107 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE);
2108 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET);
2109 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS);
2110 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0);
2111 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0);
2112 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG);
2113 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT);
2114 #undef D3DSTATE_TO_STR
2115 default:
2116 FIXME("Unrecognized %u texture state!\n", state);
2117 return "unrecognized";
2121 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2122 switch (d3dtop) {
2123 #define D3DTOP_TO_STR(u) case u: return #u
2124 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2125 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2126 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2127 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2128 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2129 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2130 D3DTOP_TO_STR(WINED3DTOP_ADD);
2131 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2132 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2133 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2134 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2135 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2136 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2137 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2138 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2139 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2140 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2141 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2142 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2143 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2144 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2145 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2146 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2147 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2148 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2149 D3DTOP_TO_STR(WINED3DTOP_LERP);
2150 #undef D3DTOP_TO_STR
2151 default:
2152 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2153 return "unrecognized";
2157 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2158 switch (tstype) {
2159 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2160 TSTYPE_TO_STR(WINED3DTS_VIEW);
2161 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2162 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2163 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2164 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2165 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2166 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2167 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2168 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2169 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2170 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2171 #undef TSTYPE_TO_STR
2172 default:
2173 if (tstype > 256 && tstype < 512) {
2174 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2175 return ("WINED3DTS_WORLDMATRIX > 0");
2177 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2178 return "unrecognized";
2182 const char *debug_d3dstate(DWORD state)
2184 if (STATE_IS_RENDER(state))
2185 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2186 if (STATE_IS_TEXTURESTAGE(state))
2188 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2189 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2190 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2191 texture_stage, debug_d3dtexturestate(texture_state));
2193 if (STATE_IS_SAMPLER(state))
2194 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2195 if (STATE_IS_PIXELSHADER(state))
2196 return "STATE_PIXELSHADER";
2197 if (STATE_IS_TRANSFORM(state))
2198 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2199 if (STATE_IS_STREAMSRC(state))
2200 return "STATE_STREAMSRC";
2201 if (STATE_IS_INDEXBUFFER(state))
2202 return "STATE_INDEXBUFFER";
2203 if (STATE_IS_VDECL(state))
2204 return "STATE_VDECL";
2205 if (STATE_IS_VSHADER(state))
2206 return "STATE_VSHADER";
2207 if (STATE_IS_VIEWPORT(state))
2208 return "STATE_VIEWPORT";
2209 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2210 return "STATE_VERTEXSHADERCONSTANT";
2211 if (STATE_IS_PIXELSHADERCONSTANT(state))
2212 return "STATE_PIXELSHADERCONSTANT";
2213 if (STATE_IS_ACTIVELIGHT(state))
2214 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2215 if (STATE_IS_SCISSORRECT(state))
2216 return "STATE_SCISSORRECT";
2217 if (STATE_IS_CLIPPLANE(state))
2218 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2219 if (STATE_IS_MATERIAL(state))
2220 return "STATE_MATERIAL";
2221 if (STATE_IS_FRONTFACE(state))
2222 return "STATE_FRONTFACE";
2223 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2224 return "STATE_POINTSPRITECOORDORIGIN";
2226 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2229 const char *debug_d3dpool(WINED3DPOOL pool)
2231 switch (pool)
2233 #define POOL_TO_STR(p) case p: return #p
2234 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2235 POOL_TO_STR(WINED3DPOOL_MANAGED);
2236 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2237 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2238 #undef POOL_TO_STR
2239 default:
2240 FIXME("Unrecognized %u WINED3DPOOL!\n", pool);
2241 return "unrecognized";
2245 const char *debug_fbostatus(GLenum status) {
2246 switch(status) {
2247 #define FBOSTATUS_TO_STR(u) case u: return #u
2248 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2249 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2250 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2251 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2252 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2253 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2254 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2255 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2256 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2257 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2258 #undef FBOSTATUS_TO_STR
2259 default:
2260 FIXME("Unrecognied FBO status 0x%08x\n", status);
2261 return "unrecognized";
2265 const char *debug_glerror(GLenum error) {
2266 switch(error) {
2267 #define GLERROR_TO_STR(u) case u: return #u
2268 GLERROR_TO_STR(GL_NO_ERROR);
2269 GLERROR_TO_STR(GL_INVALID_ENUM);
2270 GLERROR_TO_STR(GL_INVALID_VALUE);
2271 GLERROR_TO_STR(GL_INVALID_OPERATION);
2272 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2273 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2274 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2275 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2276 #undef GLERROR_TO_STR
2277 default:
2278 FIXME("Unrecognied GL error 0x%08x\n", error);
2279 return "unrecognized";
2283 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2284 switch(basis) {
2285 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2286 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2287 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2288 default: return "unrecognized";
2292 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2293 switch(degree) {
2294 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2295 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2296 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2297 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2298 default: return "unrecognized";
2302 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2304 switch(source)
2306 #define WINED3D_TO_STR(x) case x: return #x
2307 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2308 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2309 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2310 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2311 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2312 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2313 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2314 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2315 #undef WINED3D_TO_STR
2316 default:
2317 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2318 return "unrecognized";
2322 static const char *debug_complex_fixup(enum complex_fixup fixup)
2324 switch(fixup)
2326 #define WINED3D_TO_STR(x) case x: return #x
2327 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2328 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2329 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2330 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2331 #undef WINED3D_TO_STR
2332 default:
2333 FIXME("Unrecognized complex fixup %#x\n", fixup);
2334 return "unrecognized";
2338 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2340 if (is_complex_fixup(fixup))
2342 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2343 return;
2346 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2347 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2348 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2349 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2352 const char *debug_surflocation(DWORD flag) {
2353 char buf[128];
2355 buf[0] = 0;
2356 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2357 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2358 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2359 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2360 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2363 /*****************************************************************************
2364 * Useful functions mapping GL <-> D3D values
2366 GLenum StencilOp(DWORD op) {
2367 switch(op) {
2368 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2369 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2370 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2371 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2372 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2373 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2374 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2375 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2376 default:
2377 FIXME("Unrecognized stencil op %d\n", op);
2378 return GL_KEEP;
2382 GLenum CompareFunc(DWORD func) {
2383 switch ((WINED3DCMPFUNC)func) {
2384 case WINED3DCMP_NEVER : return GL_NEVER;
2385 case WINED3DCMP_LESS : return GL_LESS;
2386 case WINED3DCMP_EQUAL : return GL_EQUAL;
2387 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2388 case WINED3DCMP_GREATER : return GL_GREATER;
2389 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2390 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2391 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2392 default:
2393 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2394 return 0;
2398 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2399 WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
2401 if (op == WINED3DTOP_DISABLE) return FALSE;
2402 if (state->textures[stage]) return FALSE;
2404 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2405 && op != WINED3DTOP_SELECTARG2) return TRUE;
2406 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2407 && op != WINED3DTOP_SELECTARG1) return TRUE;
2408 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2409 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2411 return FALSE;
2414 /* Setup this textures matrix according to the texture flags*/
2415 /* GL locking is done by the caller (state handler) */
2416 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2417 enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2419 float mat[16];
2421 glMatrixMode(GL_TEXTURE);
2422 checkGLcall("glMatrixMode(GL_TEXTURE)");
2424 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2425 glLoadIdentity();
2426 checkGLcall("glLoadIdentity()");
2427 return;
2430 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2431 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2432 return;
2435 memcpy(mat, smat, 16 * sizeof(float));
2437 if (flags & WINED3DTTFF_PROJECTED) {
2438 if(!ffp_proj_control) {
2439 switch (flags & ~WINED3DTTFF_PROJECTED) {
2440 case WINED3DTTFF_COUNT2:
2441 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2442 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2443 break;
2444 case WINED3DTTFF_COUNT3:
2445 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2446 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2447 break;
2450 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2451 if(!calculatedCoords) {
2452 switch(vtx_fmt)
2454 case WINED3DFMT_R32_FLOAT:
2455 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2456 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2457 * the input value to the transformation will be 0, so the matrix value is irrelevant
2459 mat[12] = mat[4];
2460 mat[13] = mat[5];
2461 mat[14] = mat[6];
2462 mat[15] = mat[7];
2463 break;
2464 case WINED3DFMT_R32G32_FLOAT:
2465 /* See above, just 3rd and 4th coord
2467 mat[12] = mat[8];
2468 mat[13] = mat[9];
2469 mat[14] = mat[10];
2470 mat[15] = mat[11];
2471 break;
2472 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2473 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2475 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2476 * into a bad place. The division elimination below will apply to make sure the
2477 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2479 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2480 break;
2481 default:
2482 FIXME("Unexpected fixed function texture coord input\n");
2485 if(!ffp_proj_control) {
2486 switch (flags & ~WINED3DTTFF_PROJECTED) {
2487 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2488 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2489 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2490 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2491 * the 4th coord evaluates to 1.0 to eliminate that.
2493 * If the fixed function pipeline is used, the 4th value remains unused,
2494 * so there is no danger in doing this. With vertex shaders we have a
2495 * problem. Should an app hit that problem, the code here would have to
2496 * check for pixel shaders, and the shader has to undo the default gl divide.
2498 * A more serious problem occurs if the app passes 4 coordinates in, and the
2499 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2500 * or a replacement shader
2502 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2507 glLoadMatrixf(mat);
2508 checkGLcall("glLoadMatrixf(mat)");
2511 /* This small helper function is used to convert a bitmask into the number of masked bits */
2512 unsigned int count_bits(unsigned int mask)
2514 unsigned int count;
2515 for (count = 0; mask; ++count)
2517 mask &= mask - 1;
2519 return count;
2522 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2523 * The later function requires individual color components. */
2524 BOOL getColorBits(const struct wined3d_format *format,
2525 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2527 TRACE("format %s.\n", debug_d3dformat(format->id));
2529 switch (format->id)
2531 case WINED3DFMT_B10G10R10A2_UNORM:
2532 case WINED3DFMT_R10G10B10A2_UNORM:
2533 case WINED3DFMT_B8G8R8X8_UNORM:
2534 case WINED3DFMT_B8G8R8_UNORM:
2535 case WINED3DFMT_B8G8R8A8_UNORM:
2536 case WINED3DFMT_R8G8B8A8_UNORM:
2537 case WINED3DFMT_B5G5R5X1_UNORM:
2538 case WINED3DFMT_B5G5R5A1_UNORM:
2539 case WINED3DFMT_B5G6R5_UNORM:
2540 case WINED3DFMT_B4G4R4X4_UNORM:
2541 case WINED3DFMT_B4G4R4A4_UNORM:
2542 case WINED3DFMT_B2G3R3_UNORM:
2543 case WINED3DFMT_P8_UINT_A8_UNORM:
2544 case WINED3DFMT_P8_UINT:
2545 break;
2546 default:
2547 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2548 return FALSE;
2551 *redSize = count_bits(format->red_mask);
2552 *greenSize = count_bits(format->green_mask);
2553 *blueSize = count_bits(format->blue_mask);
2554 *alphaSize = count_bits(format->alpha_mask);
2555 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2557 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2558 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2559 return TRUE;
2562 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2563 BOOL getDepthStencilBits(const struct wined3d_format *format, short *depthSize, short *stencilSize)
2565 TRACE("format %s.\n", debug_d3dformat(format->id));
2567 switch (format->id)
2569 case WINED3DFMT_D16_LOCKABLE:
2570 case WINED3DFMT_D16_UNORM:
2571 case WINED3DFMT_S1_UINT_D15_UNORM:
2572 case WINED3DFMT_X8D24_UNORM:
2573 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2574 case WINED3DFMT_D24_UNORM_S8_UINT:
2575 case WINED3DFMT_S8_UINT_D24_FLOAT:
2576 case WINED3DFMT_D32_UNORM:
2577 case WINED3DFMT_D32_FLOAT:
2578 case WINED3DFMT_INTZ:
2579 break;
2580 default:
2581 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2582 return FALSE;
2585 *depthSize = format->depth_size;
2586 *stencilSize = format->stencil_size;
2588 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2589 *depthSize, *stencilSize, debug_d3dformat(format->id));
2590 return TRUE;
2593 /* Note: It's the caller's responsibility to ensure values can be expressed
2594 * in the requested format. UNORM formats for example can only express values
2595 * in the range 0.0f -> 1.0f. */
2596 DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, const WINED3DCOLORVALUE *color)
2598 static const struct
2600 enum wined3d_format_id format_id;
2601 float r_mul;
2602 float g_mul;
2603 float b_mul;
2604 float a_mul;
2605 BYTE r_shift;
2606 BYTE g_shift;
2607 BYTE b_shift;
2608 BYTE a_shift;
2610 conv[] =
2612 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2613 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2614 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2615 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2616 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2617 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2618 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2619 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2620 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2621 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2622 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2623 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2624 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2625 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2627 unsigned int i;
2629 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2630 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2632 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2634 DWORD ret;
2636 if (format->id != conv[i].format_id) continue;
2638 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2639 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2640 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2641 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2643 TRACE("Returning 0x%08x.\n", ret);
2645 return ret;
2648 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2650 return 0;
2653 /* DirectDraw stuff */
2654 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2656 switch (depth)
2658 case 8: return WINED3DFMT_P8_UINT;
2659 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2660 case 16: return WINED3DFMT_B5G6R5_UNORM;
2661 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2662 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2663 default: return WINED3DFMT_UNKNOWN;
2667 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2668 WINED3DMATRIX temp;
2670 /* Now do the multiplication 'by hand'.
2671 I know that all this could be optimised, but this will be done later :-) */
2672 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);
2673 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);
2674 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);
2675 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);
2677 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);
2678 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);
2679 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);
2680 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);
2682 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);
2683 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);
2684 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);
2685 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);
2687 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);
2688 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);
2689 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);
2690 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);
2692 /* And copy the new matrix in the good storage.. */
2693 memcpy(dest, &temp, 16 * sizeof(float));
2696 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2697 DWORD size = 0;
2698 int i;
2699 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2701 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2702 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2703 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2704 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2705 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2706 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2707 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2708 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2709 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2710 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2711 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2712 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2713 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2714 default: ERR("Unexpected position mask\n");
2716 for (i = 0; i < numTextures; i++) {
2717 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2720 return size;
2723 void gen_ffp_frag_op(struct wined3d_stateblock *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype)
2725 #define ARG1 0x01
2726 #define ARG2 0x02
2727 #define ARG0 0x04
2728 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2729 /* undefined */ 0,
2730 /* D3DTOP_DISABLE */ 0,
2731 /* D3DTOP_SELECTARG1 */ ARG1,
2732 /* D3DTOP_SELECTARG2 */ ARG2,
2733 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2734 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2735 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2736 /* D3DTOP_ADD */ ARG1 | ARG2,
2737 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2738 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2739 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2740 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2741 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2742 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2743 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2744 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2745 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2746 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2747 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2748 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2749 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2750 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2751 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2752 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2753 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2754 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2755 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2757 unsigned int i;
2758 DWORD ttff;
2759 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2760 IWineD3DDeviceImpl *device = stateblock->device;
2761 IWineD3DSurfaceImpl *rt = device->render_targets[0];
2762 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2764 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2766 IWineD3DBaseTextureImpl *texture;
2767 settings->op[i].padding = 0;
2768 if (stateblock->state.texture_states[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE)
2770 settings->op[i].cop = WINED3DTOP_DISABLE;
2771 settings->op[i].aop = WINED3DTOP_DISABLE;
2772 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2773 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2774 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2775 settings->op[i].dst = resultreg;
2776 settings->op[i].tex_type = tex_1d;
2777 settings->op[i].projected = proj_none;
2778 i++;
2779 break;
2782 if ((texture = stateblock->state.textures[i]))
2784 settings->op[i].color_fixup = texture->resource.format->color_fixup;
2785 if (ignore_textype)
2787 settings->op[i].tex_type = tex_1d;
2789 else
2791 switch (texture->baseTexture.target)
2793 case GL_TEXTURE_1D:
2794 settings->op[i].tex_type = tex_1d;
2795 break;
2796 case GL_TEXTURE_2D:
2797 settings->op[i].tex_type = tex_2d;
2798 break;
2799 case GL_TEXTURE_3D:
2800 settings->op[i].tex_type = tex_3d;
2801 break;
2802 case GL_TEXTURE_CUBE_MAP_ARB:
2803 settings->op[i].tex_type = tex_cube;
2804 break;
2805 case GL_TEXTURE_RECTANGLE_ARB:
2806 settings->op[i].tex_type = tex_rect;
2807 break;
2810 } else {
2811 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2812 settings->op[i].tex_type = tex_1d;
2815 cop = stateblock->state.texture_states[i][WINED3DTSS_COLOROP];
2816 aop = stateblock->state.texture_states[i][WINED3DTSS_ALPHAOP];
2818 carg1 = (args[cop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2819 carg2 = (args[cop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2820 carg0 = (args[cop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2822 if (is_invalid_op(&stateblock->state, i, cop, carg1, carg2, carg0))
2824 carg0 = ARG_UNUSED;
2825 carg2 = ARG_UNUSED;
2826 carg1 = WINED3DTA_CURRENT;
2827 cop = WINED3DTOP_SELECTARG1;
2830 if(cop == WINED3DTOP_DOTPRODUCT3) {
2831 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2832 * the color result to the alpha component of the destination
2834 aop = cop;
2835 aarg1 = carg1;
2836 aarg2 = carg2;
2837 aarg0 = carg0;
2839 else
2841 aarg1 = (args[aop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2842 aarg2 = (args[aop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2843 aarg0 = (args[aop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2846 if (!i && stateblock->state.textures[0] && stateblock->state.render_states[WINED3DRS_COLORKEYENABLE])
2848 IWineD3DBaseTextureImpl *texture = stateblock->state.textures[0];
2849 GLenum texture_dimensions = texture->baseTexture.target;
2851 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2853 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
2855 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
2857 if (aop == WINED3DTOP_DISABLE)
2859 aarg1 = WINED3DTA_TEXTURE;
2860 aop = WINED3DTOP_SELECTARG1;
2862 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2864 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2866 aarg2 = WINED3DTA_TEXTURE;
2867 aop = WINED3DTOP_MODULATE;
2869 else aarg1 = WINED3DTA_TEXTURE;
2871 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2873 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2875 aarg1 = WINED3DTA_TEXTURE;
2876 aop = WINED3DTOP_MODULATE;
2878 else aarg2 = WINED3DTA_TEXTURE;
2884 if (is_invalid_op(&stateblock->state, i, aop, aarg1, aarg2, aarg0))
2886 aarg0 = ARG_UNUSED;
2887 aarg2 = ARG_UNUSED;
2888 aarg1 = WINED3DTA_CURRENT;
2889 aop = WINED3DTOP_SELECTARG1;
2892 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
2893 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
2895 ttff = stateblock->state.texture_states[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2896 if (ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3))
2898 settings->op[i].projected = proj_count3;
2899 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2900 settings->op[i].projected = proj_count4;
2901 } else {
2902 settings->op[i].projected = proj_none;
2904 } else {
2905 settings->op[i].projected = proj_none;
2908 settings->op[i].cop = cop;
2909 settings->op[i].aop = aop;
2910 settings->op[i].carg0 = carg0;
2911 settings->op[i].carg1 = carg1;
2912 settings->op[i].carg2 = carg2;
2913 settings->op[i].aarg0 = aarg0;
2914 settings->op[i].aarg1 = aarg1;
2915 settings->op[i].aarg2 = aarg2;
2917 if (stateblock->state.texture_states[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP)
2919 settings->op[i].dst = tempreg;
2920 } else {
2921 settings->op[i].dst = resultreg;
2925 /* Clear unsupported stages */
2926 for(; i < MAX_TEXTURES; i++) {
2927 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2930 if (!stateblock->state.render_states[WINED3DRS_FOGENABLE])
2932 settings->fog = FOG_OFF;
2934 else if (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
2936 if (use_vs(&stateblock->state) || stateblock->state.vertex_declaration->position_transformed)
2938 settings->fog = FOG_LINEAR;
2940 else
2942 switch (stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE])
2944 case WINED3DFOG_NONE:
2945 case WINED3DFOG_LINEAR:
2946 settings->fog = FOG_LINEAR;
2947 break;
2948 case WINED3DFOG_EXP:
2949 settings->fog = FOG_EXP;
2950 break;
2951 case WINED3DFOG_EXP2:
2952 settings->fog = FOG_EXP2;
2953 break;
2957 else
2959 switch (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE])
2961 case WINED3DFOG_LINEAR:
2962 settings->fog = FOG_LINEAR;
2963 break;
2964 case WINED3DFOG_EXP:
2965 settings->fog = FOG_EXP;
2966 break;
2967 case WINED3DFOG_EXP2:
2968 settings->fog = FOG_EXP2;
2969 break;
2972 if (stateblock->state.render_states[WINED3DRS_SRGBWRITEENABLE]
2973 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
2975 settings->sRGB_write = 1;
2976 } else {
2977 settings->sRGB_write = 0;
2979 if (device->vs_clipping || !use_vs(&stateblock->state) || !stateblock->state.render_states[WINED3DRS_CLIPPING]
2980 || !stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE])
2982 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2983 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2984 * if no clipplane is enabled
2986 settings->emul_clipplanes = 0;
2987 } else {
2988 settings->emul_clipplanes = 1;
2992 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2993 const struct ffp_frag_settings *settings)
2995 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2996 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2999 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3001 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3002 * whereas desc points to an extended structure with implementation specific parts. */
3003 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3005 ERR("Failed to insert ffp frag shader.\n");
3009 /* Activates the texture dimension according to the bound D3D texture.
3010 * Does not care for the colorop or correct gl texture unit(when using nvrc)
3011 * Requires the caller to activate the correct unit before
3013 /* GL locking is done by the caller (state handler) */
3014 void texture_activate_dimensions(IWineD3DBaseTextureImpl *texture, const struct wined3d_gl_info *gl_info)
3016 if (texture)
3018 switch (texture->baseTexture.target)
3020 case GL_TEXTURE_2D:
3021 glDisable(GL_TEXTURE_3D);
3022 checkGLcall("glDisable(GL_TEXTURE_3D)");
3023 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3025 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3026 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3028 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3030 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3031 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3033 glEnable(GL_TEXTURE_2D);
3034 checkGLcall("glEnable(GL_TEXTURE_2D)");
3035 break;
3036 case GL_TEXTURE_RECTANGLE_ARB:
3037 glDisable(GL_TEXTURE_2D);
3038 checkGLcall("glDisable(GL_TEXTURE_2D)");
3039 glDisable(GL_TEXTURE_3D);
3040 checkGLcall("glDisable(GL_TEXTURE_3D)");
3041 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3043 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3044 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3046 glEnable(GL_TEXTURE_RECTANGLE_ARB);
3047 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3048 break;
3049 case GL_TEXTURE_3D:
3050 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3052 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3053 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3055 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3057 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3058 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3060 glDisable(GL_TEXTURE_2D);
3061 checkGLcall("glDisable(GL_TEXTURE_2D)");
3062 glEnable(GL_TEXTURE_3D);
3063 checkGLcall("glEnable(GL_TEXTURE_3D)");
3064 break;
3065 case GL_TEXTURE_CUBE_MAP_ARB:
3066 glDisable(GL_TEXTURE_2D);
3067 checkGLcall("glDisable(GL_TEXTURE_2D)");
3068 glDisable(GL_TEXTURE_3D);
3069 checkGLcall("glDisable(GL_TEXTURE_3D)");
3070 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3072 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3073 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3075 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3076 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3077 break;
3079 } else {
3080 glEnable(GL_TEXTURE_2D);
3081 checkGLcall("glEnable(GL_TEXTURE_2D)");
3082 glDisable(GL_TEXTURE_3D);
3083 checkGLcall("glDisable(GL_TEXTURE_3D)");
3084 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3086 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3087 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3089 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3091 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3092 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3094 /* Binding textures is done by samplers. A dummy texture will be bound */
3098 /* GL locking is done by the caller (state handler) */
3099 void sampler_texdim(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3101 DWORD sampler = state - STATE_SAMPLER(0);
3102 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3104 /* No need to enable / disable anything here for unused samplers. The tex_colorop
3105 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3106 * will take care of this business
3108 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3109 if (sampler >= stateblock->state.lowest_disabled_stage) return;
3110 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3112 texture_activate_dimensions(stateblock->state.textures[sampler], context->gl_info);
3115 void *wined3d_rb_alloc(size_t size)
3117 return HeapAlloc(GetProcessHeap(), 0, size);
3120 void *wined3d_rb_realloc(void *ptr, size_t size)
3122 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3125 void wined3d_rb_free(void *ptr)
3127 HeapFree(GetProcessHeap(), 0, ptr);
3130 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3132 const struct ffp_frag_settings *ka = key;
3133 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3135 return memcmp(ka, kb, sizeof(*ka));
3138 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3140 wined3d_rb_alloc,
3141 wined3d_rb_realloc,
3142 wined3d_rb_free,
3143 ffp_frag_program_key_compare,
3146 UINT wined3d_log2i(UINT32 x)
3148 static const UINT l[] =
3150 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3151 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3152 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3153 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3154 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3155 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3156 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3157 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3158 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3159 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3160 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3161 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3162 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3163 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3164 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3165 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3167 UINT32 i;
3169 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3172 /* Set the shader type for this device, depending on the given capabilities
3173 * and the user preferences in wined3d_settings. */
3174 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3176 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3178 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3179 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3181 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3182 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3183 * shaders only on this card. */
3184 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3185 else *vs_selected = SHADER_GLSL;
3187 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3188 else *vs_selected = SHADER_NONE;
3190 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3191 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3192 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3193 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3194 else *ps_selected = SHADER_NONE;
3197 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
3198 const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format *src_format,
3199 const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format *dst_format)
3201 static const struct blit_shader * const blitters[] =
3203 &arbfp_blit,
3204 &ffp_blit,
3205 &cpu_blit,
3207 unsigned int i;
3209 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3211 if (blitters[i]->blit_supported(gl_info, blit_op,
3212 src_rect, src_usage, src_pool, src_format,
3213 dst_rect, dst_usage, dst_pool, dst_format))
3214 return blitters[i];
3217 return NULL;