d3dx9/tests: Add tests for D3DXLoadMeshHierarchyFromXInMemory.
[wine.git] / dlls / wined3d / utils.c
blob8f48e46d9256c68f5eba3faeac479fc3e981b6c2
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 BYTE 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 const short color = (*Source++);
350 /* B */ Dest[0] = 0xff;
351 /* G */ Dest[1] = (color >> 8) + 128; /* V */
352 /* R */ Dest[2] = (color & 0xff) + 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 const DWORD color = (*Source++);
444 /* B */ Dest[0] = 0xffff;
445 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
446 /* R */ Dest[2] = (color & 0xffff) + 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 | WINED3DFMT_FLAG_FILTERING,
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 | WINED3DFMT_FLAG_FILTERING,
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,
741 WINED3DFMT_FLAG_FILTERING,
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 if (format->glGammaInternal != format->glInternal)
1202 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1203 if (!gl_info->supported[EXT_TEXTURE_SRGB])
1205 format->glGammaInternal = format->glInternal;
1206 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1208 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1210 format->glInternal = format->glGammaInternal;
1214 /* Texture conversion stuff */
1215 format->convert = format_texture_info[i].convert;
1216 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1219 return TRUE;
1222 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1224 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1225 c1 >>= 8; c2 >>= 8;
1226 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1227 c1 >>= 8; c2 >>= 8;
1228 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1229 c1 >>= 8; c2 >>= 8;
1230 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1231 return TRUE;
1234 /* A context is provided by the caller */
1235 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1237 static const DWORD data[] = {0x00000000, 0xffffffff};
1238 GLuint tex, fbo, buffer;
1239 DWORD readback[16 * 1];
1240 BOOL ret = FALSE;
1242 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1243 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1244 * falling back to software. If this changes in the future this code will get fooled and
1245 * apps might hit the software path due to incorrectly advertised caps.
1247 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1248 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1249 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1252 ENTER_GL();
1253 while(glGetError());
1255 glGenTextures(1, &buffer);
1256 glBindTexture(GL_TEXTURE_2D, buffer);
1257 memset(readback, 0x7e, sizeof(readback));
1258 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1259 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1260 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1261 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1265 glGenTextures(1, &tex);
1266 glBindTexture(GL_TEXTURE_2D, tex);
1267 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1268 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1270 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1271 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1272 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1273 glEnable(GL_TEXTURE_2D);
1275 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1276 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1277 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1278 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1280 glViewport(0, 0, 16, 1);
1281 glDisable(GL_LIGHTING);
1282 glMatrixMode(GL_MODELVIEW);
1283 glLoadIdentity();
1284 glMatrixMode(GL_PROJECTION);
1285 glLoadIdentity();
1287 glClearColor(0, 1, 0, 0);
1288 glClear(GL_COLOR_BUFFER_BIT);
1290 glBegin(GL_TRIANGLE_STRIP);
1291 glTexCoord2f(0.0, 0.0);
1292 glVertex2f(-1.0f, -1.0f);
1293 glTexCoord2f(1.0, 0.0);
1294 glVertex2f(1.0f, -1.0f);
1295 glTexCoord2f(0.0, 1.0);
1296 glVertex2f(-1.0f, 1.0f);
1297 glTexCoord2f(1.0, 1.0);
1298 glVertex2f(1.0f, 1.0f);
1299 glEnd();
1301 glBindTexture(GL_TEXTURE_2D, buffer);
1302 memset(readback, 0x7f, sizeof(readback));
1303 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1304 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1305 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1307 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1308 readback[6], readback[9]);
1309 ret = FALSE;
1311 else
1313 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1314 readback[6], readback[9]);
1315 ret = TRUE;
1318 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1319 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1320 glDeleteTextures(1, &tex);
1321 glDeleteTextures(1, &buffer);
1323 if(glGetError())
1325 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1326 ret = FALSE;
1328 LEAVE_GL();
1329 return ret;
1332 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1334 struct wined3d_format *format;
1335 unsigned int fmt_idx, i;
1336 static const enum wined3d_format_id fmts16[] =
1338 WINED3DFMT_R16_FLOAT,
1339 WINED3DFMT_R16G16_FLOAT,
1340 WINED3DFMT_R16G16B16A16_FLOAT,
1342 BOOL filtered;
1344 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1346 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1347 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1349 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1350 filtered = TRUE;
1352 else if (gl_info->limits.glsl_varyings > 44)
1354 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1355 filtered = TRUE;
1357 else
1359 TRACE("Assuming no float16 blending\n");
1360 filtered = FALSE;
1363 if(filtered)
1365 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1367 fmt_idx = getFmtIdx(fmts16[i]);
1368 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1371 return;
1374 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1376 fmt_idx = getFmtIdx(fmts16[i]);
1377 format = &gl_info->formats[fmt_idx];
1378 if (!format->glInternal) continue; /* Not supported by GL */
1380 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1381 if(filtered)
1383 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1384 format->flags |= WINED3DFMT_FLAG_FILTERING;
1386 else
1388 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1393 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1395 int idx;
1397 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1398 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1399 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1401 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1402 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1403 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1405 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1406 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1407 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1409 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1410 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1411 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1413 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1414 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1415 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1417 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1418 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1419 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1420 * the only driver that implements it(fglrx) has a buggy implementation.
1422 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1423 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1424 * conversion for this format.
1426 if (!gl_info->supported[NV_TEXTURE_SHADER])
1428 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1429 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1430 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1431 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1432 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1433 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1435 else
1437 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1438 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1439 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1441 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1442 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1443 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1446 if (!gl_info->supported[NV_TEXTURE_SHADER])
1448 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1449 * with each other
1451 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1452 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1453 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1454 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1455 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1456 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1457 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1458 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1459 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1461 else
1463 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1464 * are converted at surface loading time, but they do not need any modification in
1465 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1466 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1470 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1472 idx = getFmtIdx(WINED3DFMT_ATI2N);
1473 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1474 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1476 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1478 idx = getFmtIdx(WINED3DFMT_ATI2N);
1479 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1480 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1483 if (!gl_info->supported[APPLE_YCBCR_422])
1485 idx = getFmtIdx(WINED3DFMT_YUY2);
1486 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1488 idx = getFmtIdx(WINED3DFMT_UYVY);
1489 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1492 idx = getFmtIdx(WINED3DFMT_YV12);
1493 gl_info->formats[idx].heightscale = 1.5f;
1494 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1496 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1498 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1499 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1502 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1504 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1505 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1508 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1510 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1511 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1512 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1513 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1515 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1516 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1520 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1522 unsigned int i;
1524 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1526 struct wined3d_format *format;
1527 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1529 if (fmt_idx == -1)
1531 ERR("Format %s (%#x) not found.\n",
1532 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1533 return FALSE;
1536 format = &gl_info->formats[fmt_idx];
1537 format->emit_idx = format_vertex_info[i].emit_idx;
1538 format->component_count = format_vertex_info[i].component_count;
1539 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1540 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1541 format->gl_normalized = format_vertex_info[i].gl_normalized;
1542 format->component_size = format_vertex_info[i].component_size;
1545 return TRUE;
1548 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1550 if (!init_format_base_info(gl_info)) return FALSE;
1552 if (!init_format_compression_info(gl_info))
1554 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1555 gl_info->formats = NULL;
1556 return FALSE;
1559 return TRUE;
1562 /* Context activation is done by the caller. */
1563 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1565 if (!init_format_base_info(gl_info)) return FALSE;
1567 if (!init_format_compression_info(gl_info)) goto fail;
1568 if (!init_format_texture_info(gl_info)) goto fail;
1569 if (!init_format_vertex_info(gl_info)) goto fail;
1571 apply_format_fixups(gl_info);
1572 init_format_fbo_compat_info(gl_info);
1573 init_format_filter_info(gl_info, vendor);
1575 return TRUE;
1577 fail:
1578 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1579 gl_info->formats = NULL;
1580 return FALSE;
1583 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1584 enum wined3d_format_id format_id)
1586 int idx = getFmtIdx(format_id);
1588 if (idx == -1)
1590 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1591 debug_d3dformat(format_id), format_id);
1592 /* Get the caller a valid pointer */
1593 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1596 return &gl_info->formats[idx];
1599 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1601 UINT size;
1603 if (format->id == WINED3DFMT_UNKNOWN)
1605 size = 0;
1607 else if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1609 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1610 UINT row_count = (height + format->block_height - 1) / format->block_height;
1611 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1613 else
1615 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1618 if (format->heightscale != 0.0f)
1620 /* The D3D format requirements make sure that the resulting format is an integer again */
1621 size = (UINT) (size * format->heightscale);
1624 return size;
1627 /*****************************************************************************
1628 * Trace formatting of useful values
1630 const char *debug_d3dformat(enum wined3d_format_id format_id)
1632 switch (format_id)
1634 #define FMT_TO_STR(format_id) case format_id: return #format_id
1635 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1636 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1637 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1638 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1639 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1640 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1641 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1642 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1643 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1644 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1645 FMT_TO_STR(WINED3DFMT_P8_UINT);
1646 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1647 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1648 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1649 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1650 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1651 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1652 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1653 FMT_TO_STR(WINED3DFMT_UYVY);
1654 FMT_TO_STR(WINED3DFMT_YUY2);
1655 FMT_TO_STR(WINED3DFMT_YV12);
1656 FMT_TO_STR(WINED3DFMT_DXT1);
1657 FMT_TO_STR(WINED3DFMT_DXT2);
1658 FMT_TO_STR(WINED3DFMT_DXT3);
1659 FMT_TO_STR(WINED3DFMT_DXT4);
1660 FMT_TO_STR(WINED3DFMT_DXT5);
1661 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1662 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1663 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1664 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1665 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1666 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1667 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1668 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1669 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1670 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1671 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1672 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1673 FMT_TO_STR(WINED3DFMT_ATI2N);
1674 FMT_TO_STR(WINED3DFMT_NVDB);
1675 FMT_TO_STR(WINED3DFMT_NVHU);
1676 FMT_TO_STR(WINED3DFMT_NVHS);
1677 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1678 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1679 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1680 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1681 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1682 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1683 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1684 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1685 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1686 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1687 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1688 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1689 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1690 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1691 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1692 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1693 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1694 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1695 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1696 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1697 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1698 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1699 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1700 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1701 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1702 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1703 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1704 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1705 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1706 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1707 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1708 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1709 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1710 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1711 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1712 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1713 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1714 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1715 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1716 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1717 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1718 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1719 FMT_TO_STR(WINED3DFMT_R32_UINT);
1720 FMT_TO_STR(WINED3DFMT_R32_SINT);
1721 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1722 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1723 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1724 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1725 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1726 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1727 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1728 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1729 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1730 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1731 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1732 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1733 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1734 FMT_TO_STR(WINED3DFMT_R16_UINT);
1735 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1736 FMT_TO_STR(WINED3DFMT_R16_SINT);
1737 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1738 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1739 FMT_TO_STR(WINED3DFMT_R8_UINT);
1740 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1741 FMT_TO_STR(WINED3DFMT_R8_SINT);
1742 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1743 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1744 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1745 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1746 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1747 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1748 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1749 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1750 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1751 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1752 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1753 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1754 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1755 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1756 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1757 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1758 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1759 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1760 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1761 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1762 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1763 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1764 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1765 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1766 FMT_TO_STR(WINED3DFMT_INTZ);
1767 FMT_TO_STR(WINED3DFMT_NULL);
1768 #undef FMT_TO_STR
1769 default:
1771 char fourcc[5];
1772 fourcc[0] = (char)(format_id);
1773 fourcc[1] = (char)(format_id >> 8);
1774 fourcc[2] = (char)(format_id >> 16);
1775 fourcc[3] = (char)(format_id >> 24);
1776 fourcc[4] = 0;
1777 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1778 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1779 else
1780 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1782 return "unrecognized";
1786 const char *debug_d3ddevicetype(WINED3DDEVTYPE devtype)
1788 switch (devtype)
1790 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1791 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1792 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1793 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1794 #undef DEVTYPE_TO_STR
1795 default:
1796 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1797 return "unrecognized";
1801 const char *debug_d3dusage(DWORD usage)
1803 char buf[333];
1805 buf[0] = '\0';
1806 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1807 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1808 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1809 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1810 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1811 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1812 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1813 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1814 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1815 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1816 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1817 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1818 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1819 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1820 #undef WINED3DUSAGE_TO_STR
1821 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1823 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1826 const char *debug_d3dusagequery(DWORD usagequery)
1828 char buf[238];
1830 buf[0] = '\0';
1831 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1832 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1833 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1834 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1835 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1836 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1837 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1838 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1839 #undef WINED3DUSAGEQUERY_TO_STR
1840 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1842 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1845 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1846 switch (method) {
1847 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1848 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1849 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1850 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1851 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1852 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1853 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1854 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1855 #undef WINED3DDECLMETHOD_TO_STR
1856 default:
1857 FIXME("Unrecognized %u declaration method!\n", method);
1858 return "unrecognized";
1862 const char* debug_d3ddeclusage(BYTE usage) {
1863 switch (usage) {
1864 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1865 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1866 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1867 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1868 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1869 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1870 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1871 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1872 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1873 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1874 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1875 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1876 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1877 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1878 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1879 #undef WINED3DDECLUSAGE_TO_STR
1880 default:
1881 FIXME("Unrecognized %u declaration usage!\n", usage);
1882 return "unrecognized";
1886 const char *debug_d3dresourcetype(WINED3DRESOURCETYPE res)
1888 switch (res)
1890 #define RES_TO_STR(res) case res: return #res
1891 RES_TO_STR(WINED3DRTYPE_SURFACE);
1892 RES_TO_STR(WINED3DRTYPE_VOLUME);
1893 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1894 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1895 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1896 RES_TO_STR(WINED3DRTYPE_BUFFER);
1897 #undef RES_TO_STR
1898 default:
1899 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1900 return "unrecognized";
1904 const char *debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType)
1906 switch (PrimitiveType)
1908 #define PRIM_TO_STR(prim) case prim: return #prim
1909 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1910 PRIM_TO_STR(WINED3DPT_POINTLIST);
1911 PRIM_TO_STR(WINED3DPT_LINELIST);
1912 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1913 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1914 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1915 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1916 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1917 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1918 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1919 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1920 #undef PRIM_TO_STR
1921 default:
1922 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1923 return "unrecognized";
1927 const char *debug_d3drenderstate(WINED3DRENDERSTATETYPE state)
1929 switch (state)
1931 #define D3DSTATE_TO_STR(u) case u: return #u
1932 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS);
1933 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE);
1934 D3DSTATE_TO_STR(WINED3DRS_WRAPU);
1935 D3DSTATE_TO_STR(WINED3DRS_WRAPV);
1936 D3DSTATE_TO_STR(WINED3DRS_ZENABLE);
1937 D3DSTATE_TO_STR(WINED3DRS_FILLMODE);
1938 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE);
1939 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN);
1940 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE);
1941 D3DSTATE_TO_STR(WINED3DRS_ROP2);
1942 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK);
1943 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE);
1944 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE);
1945 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL);
1946 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND);
1947 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND);
1948 D3DSTATE_TO_STR(WINED3DRS_CULLMODE);
1949 D3DSTATE_TO_STR(WINED3DRS_ZFUNC);
1950 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF);
1951 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC);
1952 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE);
1953 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE);
1954 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE);
1955 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE);
1956 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE);
1957 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL);
1958 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX);
1959 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA);
1960 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR);
1961 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE);
1962 D3DSTATE_TO_STR(WINED3DRS_FOGSTART);
1963 D3DSTATE_TO_STR(WINED3DRS_FOGEND);
1964 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY);
1965 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE);
1966 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS);
1967 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE);
1968 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS);
1969 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE);
1970 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY);
1971 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH);
1972 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1973 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE);
1974 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL);
1975 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL);
1976 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS);
1977 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC);
1978 D3DSTATE_TO_STR(WINED3DRS_STENCILREF);
1979 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK);
1980 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK);
1981 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR);
1982 D3DSTATE_TO_STR(WINED3DRS_WRAP0);
1983 D3DSTATE_TO_STR(WINED3DRS_WRAP1);
1984 D3DSTATE_TO_STR(WINED3DRS_WRAP2);
1985 D3DSTATE_TO_STR(WINED3DRS_WRAP3);
1986 D3DSTATE_TO_STR(WINED3DRS_WRAP4);
1987 D3DSTATE_TO_STR(WINED3DRS_WRAP5);
1988 D3DSTATE_TO_STR(WINED3DRS_WRAP6);
1989 D3DSTATE_TO_STR(WINED3DRS_WRAP7);
1990 D3DSTATE_TO_STR(WINED3DRS_CLIPPING);
1991 D3DSTATE_TO_STR(WINED3DRS_LIGHTING);
1992 D3DSTATE_TO_STR(WINED3DRS_EXTENTS);
1993 D3DSTATE_TO_STR(WINED3DRS_AMBIENT);
1994 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE);
1995 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX);
1996 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER);
1997 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS);
1998 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE);
1999 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE);
2000 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE);
2001 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE);
2002 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE);
2003 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND);
2004 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE);
2005 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING);
2006 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE);
2007 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN);
2008 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE);
2009 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE);
2010 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A);
2011 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B);
2012 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C);
2013 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS);
2014 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK);
2015 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE);
2016 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS);
2017 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN);
2018 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX);
2019 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE);
2020 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE);
2021 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR);
2022 D3DSTATE_TO_STR(WINED3DRS_BLENDOP);
2023 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE);
2024 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE);
2025 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE);
2026 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS);
2027 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE);
2028 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL);
2029 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL);
2030 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X);
2031 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y);
2032 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z);
2033 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W);
2034 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
2035 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE);
2036 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL);
2037 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL);
2038 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS);
2039 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC);
2040 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1);
2041 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2);
2042 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3);
2043 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR);
2044 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE);
2045 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS);
2046 D3DSTATE_TO_STR(WINED3DRS_WRAP8);
2047 D3DSTATE_TO_STR(WINED3DRS_WRAP9);
2048 D3DSTATE_TO_STR(WINED3DRS_WRAP10);
2049 D3DSTATE_TO_STR(WINED3DRS_WRAP11);
2050 D3DSTATE_TO_STR(WINED3DRS_WRAP12);
2051 D3DSTATE_TO_STR(WINED3DRS_WRAP13);
2052 D3DSTATE_TO_STR(WINED3DRS_WRAP14);
2053 D3DSTATE_TO_STR(WINED3DRS_WRAP15);
2054 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE);
2055 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA);
2056 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA);
2057 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA);
2058 #undef D3DSTATE_TO_STR
2059 default:
2060 FIXME("Unrecognized %u render state!\n", state);
2061 return "unrecognized";
2065 const char *debug_d3dsamplerstate(DWORD state)
2067 switch (state)
2069 #define D3DSTATE_TO_STR(u) case u: return #u
2070 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR);
2071 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU);
2072 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV);
2073 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW);
2074 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER);
2075 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER);
2076 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER);
2077 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
2078 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL);
2079 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
2080 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE);
2081 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX);
2082 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET);
2083 #undef D3DSTATE_TO_STR
2084 default:
2085 FIXME("Unrecognized %u sampler state!\n", state);
2086 return "unrecognized";
2090 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2091 switch (filter_type) {
2092 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2093 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2094 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2095 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2096 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2097 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2098 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2099 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2100 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2101 #undef D3DTEXTUREFILTERTYPE_TO_STR
2102 default:
2103 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2104 return "unrecognized";
2108 const char *debug_d3dtexturestate(DWORD state)
2110 switch (state)
2112 #define D3DSTATE_TO_STR(u) case u: return #u
2113 D3DSTATE_TO_STR(WINED3DTSS_COLOROP);
2114 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1);
2115 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2);
2116 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP);
2117 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1);
2118 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2);
2119 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00);
2120 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01);
2121 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10);
2122 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11);
2123 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX);
2124 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE);
2125 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET);
2126 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS);
2127 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0);
2128 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0);
2129 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG);
2130 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT);
2131 #undef D3DSTATE_TO_STR
2132 default:
2133 FIXME("Unrecognized %u texture state!\n", state);
2134 return "unrecognized";
2138 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2139 switch (d3dtop) {
2140 #define D3DTOP_TO_STR(u) case u: return #u
2141 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2142 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2143 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2144 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2145 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2146 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2147 D3DTOP_TO_STR(WINED3DTOP_ADD);
2148 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2149 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2150 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2151 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2152 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2153 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2154 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2155 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2156 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2157 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2158 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2159 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2160 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2161 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2162 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2163 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2164 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2165 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2166 D3DTOP_TO_STR(WINED3DTOP_LERP);
2167 #undef D3DTOP_TO_STR
2168 default:
2169 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2170 return "unrecognized";
2174 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2175 switch (tstype) {
2176 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2177 TSTYPE_TO_STR(WINED3DTS_VIEW);
2178 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2179 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2180 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2181 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2182 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2183 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2184 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2185 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2186 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2187 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2188 #undef TSTYPE_TO_STR
2189 default:
2190 if (tstype > 256 && tstype < 512) {
2191 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2192 return ("WINED3DTS_WORLDMATRIX > 0");
2194 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2195 return "unrecognized";
2199 const char *debug_d3dstate(DWORD state)
2201 if (STATE_IS_RENDER(state))
2202 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2203 if (STATE_IS_TEXTURESTAGE(state))
2205 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2206 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2207 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2208 texture_stage, debug_d3dtexturestate(texture_state));
2210 if (STATE_IS_SAMPLER(state))
2211 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2212 if (STATE_IS_PIXELSHADER(state))
2213 return "STATE_PIXELSHADER";
2214 if (STATE_IS_TRANSFORM(state))
2215 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2216 if (STATE_IS_STREAMSRC(state))
2217 return "STATE_STREAMSRC";
2218 if (STATE_IS_INDEXBUFFER(state))
2219 return "STATE_INDEXBUFFER";
2220 if (STATE_IS_VDECL(state))
2221 return "STATE_VDECL";
2222 if (STATE_IS_VSHADER(state))
2223 return "STATE_VSHADER";
2224 if (STATE_IS_VIEWPORT(state))
2225 return "STATE_VIEWPORT";
2226 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2227 return "STATE_VERTEXSHADERCONSTANT";
2228 if (STATE_IS_PIXELSHADERCONSTANT(state))
2229 return "STATE_PIXELSHADERCONSTANT";
2230 if (STATE_IS_ACTIVELIGHT(state))
2231 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2232 if (STATE_IS_SCISSORRECT(state))
2233 return "STATE_SCISSORRECT";
2234 if (STATE_IS_CLIPPLANE(state))
2235 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2236 if (STATE_IS_MATERIAL(state))
2237 return "STATE_MATERIAL";
2238 if (STATE_IS_FRONTFACE(state))
2239 return "STATE_FRONTFACE";
2240 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2241 return "STATE_POINTSPRITECOORDORIGIN";
2243 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2246 const char *debug_d3dpool(WINED3DPOOL pool)
2248 switch (pool)
2250 #define POOL_TO_STR(p) case p: return #p
2251 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2252 POOL_TO_STR(WINED3DPOOL_MANAGED);
2253 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2254 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2255 #undef POOL_TO_STR
2256 default:
2257 FIXME("Unrecognized %u WINED3DPOOL!\n", pool);
2258 return "unrecognized";
2262 const char *debug_fbostatus(GLenum status) {
2263 switch(status) {
2264 #define FBOSTATUS_TO_STR(u) case u: return #u
2265 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2266 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2267 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2268 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2269 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2270 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2271 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2272 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2273 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2274 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2275 #undef FBOSTATUS_TO_STR
2276 default:
2277 FIXME("Unrecognied FBO status 0x%08x\n", status);
2278 return "unrecognized";
2282 const char *debug_glerror(GLenum error) {
2283 switch(error) {
2284 #define GLERROR_TO_STR(u) case u: return #u
2285 GLERROR_TO_STR(GL_NO_ERROR);
2286 GLERROR_TO_STR(GL_INVALID_ENUM);
2287 GLERROR_TO_STR(GL_INVALID_VALUE);
2288 GLERROR_TO_STR(GL_INVALID_OPERATION);
2289 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2290 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2291 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2292 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2293 #undef GLERROR_TO_STR
2294 default:
2295 FIXME("Unrecognied GL error 0x%08x\n", error);
2296 return "unrecognized";
2300 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2301 switch(basis) {
2302 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2303 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2304 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2305 default: return "unrecognized";
2309 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2310 switch(degree) {
2311 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2312 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2313 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2314 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2315 default: return "unrecognized";
2319 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2321 switch(source)
2323 #define WINED3D_TO_STR(x) case x: return #x
2324 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2325 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2326 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2327 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2328 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2329 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2330 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2331 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2332 #undef WINED3D_TO_STR
2333 default:
2334 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2335 return "unrecognized";
2339 static const char *debug_complex_fixup(enum complex_fixup fixup)
2341 switch(fixup)
2343 #define WINED3D_TO_STR(x) case x: return #x
2344 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2345 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2346 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2347 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2348 #undef WINED3D_TO_STR
2349 default:
2350 FIXME("Unrecognized complex fixup %#x\n", fixup);
2351 return "unrecognized";
2355 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2357 if (is_complex_fixup(fixup))
2359 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2360 return;
2363 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2364 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2365 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2366 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2369 const char *debug_surflocation(DWORD flag) {
2370 char buf[128];
2372 buf[0] = 0;
2373 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2374 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2375 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2376 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2377 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2380 /*****************************************************************************
2381 * Useful functions mapping GL <-> D3D values
2383 GLenum StencilOp(DWORD op) {
2384 switch(op) {
2385 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2386 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2387 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2388 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2389 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2390 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2391 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2392 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2393 default:
2394 FIXME("Unrecognized stencil op %d\n", op);
2395 return GL_KEEP;
2399 GLenum CompareFunc(DWORD func) {
2400 switch ((WINED3DCMPFUNC)func) {
2401 case WINED3DCMP_NEVER : return GL_NEVER;
2402 case WINED3DCMP_LESS : return GL_LESS;
2403 case WINED3DCMP_EQUAL : return GL_EQUAL;
2404 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2405 case WINED3DCMP_GREATER : return GL_GREATER;
2406 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2407 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2408 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2409 default:
2410 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2411 return 0;
2415 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2416 WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
2418 if (op == WINED3DTOP_DISABLE) return FALSE;
2419 if (state->textures[stage]) return FALSE;
2421 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2422 && op != WINED3DTOP_SELECTARG2) return TRUE;
2423 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2424 && op != WINED3DTOP_SELECTARG1) return TRUE;
2425 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2426 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2428 return FALSE;
2431 /* Setup this textures matrix according to the texture flags*/
2432 /* GL locking is done by the caller (state handler) */
2433 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2434 enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2436 float mat[16];
2438 glMatrixMode(GL_TEXTURE);
2439 checkGLcall("glMatrixMode(GL_TEXTURE)");
2441 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2442 glLoadIdentity();
2443 checkGLcall("glLoadIdentity()");
2444 return;
2447 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2448 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2449 return;
2452 memcpy(mat, smat, 16 * sizeof(float));
2454 if (flags & WINED3DTTFF_PROJECTED) {
2455 if(!ffp_proj_control) {
2456 switch (flags & ~WINED3DTTFF_PROJECTED) {
2457 case WINED3DTTFF_COUNT2:
2458 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2459 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2460 break;
2461 case WINED3DTTFF_COUNT3:
2462 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2463 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2464 break;
2467 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2468 if(!calculatedCoords) {
2469 switch(vtx_fmt)
2471 case WINED3DFMT_R32_FLOAT:
2472 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2473 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2474 * the input value to the transformation will be 0, so the matrix value is irrelevant
2476 mat[12] = mat[4];
2477 mat[13] = mat[5];
2478 mat[14] = mat[6];
2479 mat[15] = mat[7];
2480 break;
2481 case WINED3DFMT_R32G32_FLOAT:
2482 /* See above, just 3rd and 4th coord
2484 mat[12] = mat[8];
2485 mat[13] = mat[9];
2486 mat[14] = mat[10];
2487 mat[15] = mat[11];
2488 break;
2489 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2490 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2492 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2493 * into a bad place. The division elimination below will apply to make sure the
2494 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2496 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2497 break;
2498 default:
2499 FIXME("Unexpected fixed function texture coord input\n");
2502 if(!ffp_proj_control) {
2503 switch (flags & ~WINED3DTTFF_PROJECTED) {
2504 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2505 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2506 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2507 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2508 * the 4th coord evaluates to 1.0 to eliminate that.
2510 * If the fixed function pipeline is used, the 4th value remains unused,
2511 * so there is no danger in doing this. With vertex shaders we have a
2512 * problem. Should an app hit that problem, the code here would have to
2513 * check for pixel shaders, and the shader has to undo the default gl divide.
2515 * A more serious problem occurs if the app passes 4 coordinates in, and the
2516 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2517 * or a replacement shader
2519 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2524 glLoadMatrixf(mat);
2525 checkGLcall("glLoadMatrixf(mat)");
2528 /* This small helper function is used to convert a bitmask into the number of masked bits */
2529 unsigned int count_bits(unsigned int mask)
2531 unsigned int count;
2532 for (count = 0; mask; ++count)
2534 mask &= mask - 1;
2536 return count;
2539 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2540 * The later function requires individual color components. */
2541 BOOL getColorBits(const struct wined3d_format *format,
2542 BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2544 TRACE("format %s.\n", debug_d3dformat(format->id));
2546 switch (format->id)
2548 case WINED3DFMT_B10G10R10A2_UNORM:
2549 case WINED3DFMT_R10G10B10A2_UNORM:
2550 case WINED3DFMT_B8G8R8X8_UNORM:
2551 case WINED3DFMT_B8G8R8_UNORM:
2552 case WINED3DFMT_B8G8R8A8_UNORM:
2553 case WINED3DFMT_R8G8B8A8_UNORM:
2554 case WINED3DFMT_B5G5R5X1_UNORM:
2555 case WINED3DFMT_B5G5R5A1_UNORM:
2556 case WINED3DFMT_B5G6R5_UNORM:
2557 case WINED3DFMT_B4G4R4X4_UNORM:
2558 case WINED3DFMT_B4G4R4A4_UNORM:
2559 case WINED3DFMT_B2G3R3_UNORM:
2560 case WINED3DFMT_P8_UINT_A8_UNORM:
2561 case WINED3DFMT_P8_UINT:
2562 break;
2563 default:
2564 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2565 return FALSE;
2568 *redSize = count_bits(format->red_mask);
2569 *greenSize = count_bits(format->green_mask);
2570 *blueSize = count_bits(format->blue_mask);
2571 *alphaSize = count_bits(format->alpha_mask);
2572 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2574 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2575 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2576 return TRUE;
2579 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2580 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
2582 TRACE("format %s.\n", debug_d3dformat(format->id));
2584 switch (format->id)
2586 case WINED3DFMT_D16_LOCKABLE:
2587 case WINED3DFMT_D16_UNORM:
2588 case WINED3DFMT_S1_UINT_D15_UNORM:
2589 case WINED3DFMT_X8D24_UNORM:
2590 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2591 case WINED3DFMT_D24_UNORM_S8_UINT:
2592 case WINED3DFMT_S8_UINT_D24_FLOAT:
2593 case WINED3DFMT_D32_UNORM:
2594 case WINED3DFMT_D32_FLOAT:
2595 case WINED3DFMT_INTZ:
2596 break;
2597 default:
2598 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2599 return FALSE;
2602 *depthSize = format->depth_size;
2603 *stencilSize = format->stencil_size;
2605 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2606 *depthSize, *stencilSize, debug_d3dformat(format->id));
2607 return TRUE;
2610 /* Note: It's the caller's responsibility to ensure values can be expressed
2611 * in the requested format. UNORM formats for example can only express values
2612 * in the range 0.0f -> 1.0f. */
2613 DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, const WINED3DCOLORVALUE *color)
2615 static const struct
2617 enum wined3d_format_id format_id;
2618 float r_mul;
2619 float g_mul;
2620 float b_mul;
2621 float a_mul;
2622 BYTE r_shift;
2623 BYTE g_shift;
2624 BYTE b_shift;
2625 BYTE a_shift;
2627 conv[] =
2629 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2630 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2631 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2632 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2633 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2634 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2635 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2636 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2637 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2638 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2639 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2640 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2641 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2642 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2644 unsigned int i;
2646 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2647 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2649 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2651 DWORD ret;
2653 if (format->id != conv[i].format_id) continue;
2655 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2656 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2657 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2658 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2660 TRACE("Returning 0x%08x.\n", ret);
2662 return ret;
2665 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2667 return 0;
2670 /* DirectDraw stuff */
2671 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2673 switch (depth)
2675 case 8: return WINED3DFMT_P8_UINT;
2676 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2677 case 16: return WINED3DFMT_B5G6R5_UNORM;
2678 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2679 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2680 default: return WINED3DFMT_UNKNOWN;
2684 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2685 WINED3DMATRIX temp;
2687 /* Now do the multiplication 'by hand'.
2688 I know that all this could be optimised, but this will be done later :-) */
2689 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);
2690 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);
2691 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);
2692 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);
2694 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);
2695 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);
2696 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);
2697 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);
2699 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);
2700 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);
2701 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);
2702 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);
2704 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);
2705 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);
2706 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);
2707 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);
2709 /* And copy the new matrix in the good storage.. */
2710 memcpy(dest, &temp, 16 * sizeof(float));
2713 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2714 DWORD size = 0;
2715 int i;
2716 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2718 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2719 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2720 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2721 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2722 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2723 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2724 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2725 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2726 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2727 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2728 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2729 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2730 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2731 default: ERR("Unexpected position mask\n");
2733 for (i = 0; i < numTextures; i++) {
2734 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2737 return size;
2740 void gen_ffp_frag_op(struct wined3d_stateblock *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype)
2742 #define ARG1 0x01
2743 #define ARG2 0x02
2744 #define ARG0 0x04
2745 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2746 /* undefined */ 0,
2747 /* D3DTOP_DISABLE */ 0,
2748 /* D3DTOP_SELECTARG1 */ ARG1,
2749 /* D3DTOP_SELECTARG2 */ ARG2,
2750 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2751 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2752 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2753 /* D3DTOP_ADD */ ARG1 | ARG2,
2754 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2755 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2756 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2757 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2758 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2759 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2760 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2761 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2762 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2763 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2764 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2765 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2766 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2767 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2768 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2769 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2770 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2771 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2772 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2774 unsigned int i;
2775 DWORD ttff;
2776 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2777 struct wined3d_device *device = stateblock->device;
2778 struct wined3d_surface *rt = device->fb.render_targets[0];
2779 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2781 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2783 const struct wined3d_texture *texture;
2785 settings->op[i].padding = 0;
2786 if (stateblock->state.texture_states[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE)
2788 settings->op[i].cop = WINED3DTOP_DISABLE;
2789 settings->op[i].aop = WINED3DTOP_DISABLE;
2790 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2791 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2792 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2793 settings->op[i].dst = resultreg;
2794 settings->op[i].tex_type = tex_1d;
2795 settings->op[i].projected = proj_none;
2796 i++;
2797 break;
2800 if ((texture = stateblock->state.textures[i]))
2802 settings->op[i].color_fixup = texture->resource.format->color_fixup;
2803 if (ignore_textype)
2805 settings->op[i].tex_type = tex_1d;
2807 else
2809 switch (texture->target)
2811 case GL_TEXTURE_1D:
2812 settings->op[i].tex_type = tex_1d;
2813 break;
2814 case GL_TEXTURE_2D:
2815 settings->op[i].tex_type = tex_2d;
2816 break;
2817 case GL_TEXTURE_3D:
2818 settings->op[i].tex_type = tex_3d;
2819 break;
2820 case GL_TEXTURE_CUBE_MAP_ARB:
2821 settings->op[i].tex_type = tex_cube;
2822 break;
2823 case GL_TEXTURE_RECTANGLE_ARB:
2824 settings->op[i].tex_type = tex_rect;
2825 break;
2828 } else {
2829 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2830 settings->op[i].tex_type = tex_1d;
2833 cop = stateblock->state.texture_states[i][WINED3DTSS_COLOROP];
2834 aop = stateblock->state.texture_states[i][WINED3DTSS_ALPHAOP];
2836 carg1 = (args[cop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2837 carg2 = (args[cop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2838 carg0 = (args[cop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2840 if (is_invalid_op(&stateblock->state, i, cop, carg1, carg2, carg0))
2842 carg0 = ARG_UNUSED;
2843 carg2 = ARG_UNUSED;
2844 carg1 = WINED3DTA_CURRENT;
2845 cop = WINED3DTOP_SELECTARG1;
2848 if(cop == WINED3DTOP_DOTPRODUCT3) {
2849 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2850 * the color result to the alpha component of the destination
2852 aop = cop;
2853 aarg1 = carg1;
2854 aarg2 = carg2;
2855 aarg0 = carg0;
2857 else
2859 aarg1 = (args[aop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2860 aarg2 = (args[aop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2861 aarg0 = (args[aop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2864 if (!i && stateblock->state.textures[0] && stateblock->state.render_states[WINED3DRS_COLORKEYENABLE])
2866 GLenum texture_dimensions;
2868 texture = stateblock->state.textures[0];
2869 texture_dimensions = texture->target;
2871 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2873 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
2875 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
2877 if (aop == WINED3DTOP_DISABLE)
2879 aarg1 = WINED3DTA_TEXTURE;
2880 aop = WINED3DTOP_SELECTARG1;
2882 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2884 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2886 aarg2 = WINED3DTA_TEXTURE;
2887 aop = WINED3DTOP_MODULATE;
2889 else aarg1 = WINED3DTA_TEXTURE;
2891 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2893 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2895 aarg1 = WINED3DTA_TEXTURE;
2896 aop = WINED3DTOP_MODULATE;
2898 else aarg2 = WINED3DTA_TEXTURE;
2904 if (is_invalid_op(&stateblock->state, i, aop, aarg1, aarg2, aarg0))
2906 aarg0 = ARG_UNUSED;
2907 aarg2 = ARG_UNUSED;
2908 aarg1 = WINED3DTA_CURRENT;
2909 aop = WINED3DTOP_SELECTARG1;
2912 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
2913 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
2915 ttff = stateblock->state.texture_states[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2916 if (ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3))
2918 settings->op[i].projected = proj_count3;
2919 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2920 settings->op[i].projected = proj_count4;
2921 } else {
2922 settings->op[i].projected = proj_none;
2924 } else {
2925 settings->op[i].projected = proj_none;
2928 settings->op[i].cop = cop;
2929 settings->op[i].aop = aop;
2930 settings->op[i].carg0 = carg0;
2931 settings->op[i].carg1 = carg1;
2932 settings->op[i].carg2 = carg2;
2933 settings->op[i].aarg0 = aarg0;
2934 settings->op[i].aarg1 = aarg1;
2935 settings->op[i].aarg2 = aarg2;
2937 if (stateblock->state.texture_states[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP)
2939 settings->op[i].dst = tempreg;
2940 } else {
2941 settings->op[i].dst = resultreg;
2945 /* Clear unsupported stages */
2946 for(; i < MAX_TEXTURES; i++) {
2947 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2950 if (!stateblock->state.render_states[WINED3DRS_FOGENABLE])
2952 settings->fog = FOG_OFF;
2954 else if (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
2956 if (use_vs(&stateblock->state) || stateblock->state.vertex_declaration->position_transformed)
2958 settings->fog = FOG_LINEAR;
2960 else
2962 switch (stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE])
2964 case WINED3DFOG_NONE:
2965 case WINED3DFOG_LINEAR:
2966 settings->fog = FOG_LINEAR;
2967 break;
2968 case WINED3DFOG_EXP:
2969 settings->fog = FOG_EXP;
2970 break;
2971 case WINED3DFOG_EXP2:
2972 settings->fog = FOG_EXP2;
2973 break;
2977 else
2979 switch (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE])
2981 case WINED3DFOG_LINEAR:
2982 settings->fog = FOG_LINEAR;
2983 break;
2984 case WINED3DFOG_EXP:
2985 settings->fog = FOG_EXP;
2986 break;
2987 case WINED3DFOG_EXP2:
2988 settings->fog = FOG_EXP2;
2989 break;
2992 if (stateblock->state.render_states[WINED3DRS_SRGBWRITEENABLE]
2993 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
2995 settings->sRGB_write = 1;
2996 } else {
2997 settings->sRGB_write = 0;
2999 if (device->vs_clipping || !use_vs(&stateblock->state) || !stateblock->state.render_states[WINED3DRS_CLIPPING]
3000 || !stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE])
3002 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3003 * the fixed function vertex pipeline is used(which always supports clipplanes), or
3004 * if no clipplane is enabled
3006 settings->emul_clipplanes = 0;
3007 } else {
3008 settings->emul_clipplanes = 1;
3012 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3013 const struct ffp_frag_settings *settings)
3015 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3016 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3019 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3021 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3022 * whereas desc points to an extended structure with implementation specific parts. */
3023 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3025 ERR("Failed to insert ffp frag shader.\n");
3029 /* Activates the texture dimension according to the bound D3D texture.
3030 * Does not care for the colorop or correct gl texture unit(when using nvrc)
3031 * Requires the caller to activate the correct unit before
3033 /* GL locking is done by the caller (state handler) */
3034 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3036 if (texture)
3038 switch (texture->target)
3040 case GL_TEXTURE_2D:
3041 glDisable(GL_TEXTURE_3D);
3042 checkGLcall("glDisable(GL_TEXTURE_3D)");
3043 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3045 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3046 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3048 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3050 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3051 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3053 glEnable(GL_TEXTURE_2D);
3054 checkGLcall("glEnable(GL_TEXTURE_2D)");
3055 break;
3056 case GL_TEXTURE_RECTANGLE_ARB:
3057 glDisable(GL_TEXTURE_2D);
3058 checkGLcall("glDisable(GL_TEXTURE_2D)");
3059 glDisable(GL_TEXTURE_3D);
3060 checkGLcall("glDisable(GL_TEXTURE_3D)");
3061 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3063 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3064 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3066 glEnable(GL_TEXTURE_RECTANGLE_ARB);
3067 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3068 break;
3069 case GL_TEXTURE_3D:
3070 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3072 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3073 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3075 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3077 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3078 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3080 glDisable(GL_TEXTURE_2D);
3081 checkGLcall("glDisable(GL_TEXTURE_2D)");
3082 glEnable(GL_TEXTURE_3D);
3083 checkGLcall("glEnable(GL_TEXTURE_3D)");
3084 break;
3085 case GL_TEXTURE_CUBE_MAP_ARB:
3086 glDisable(GL_TEXTURE_2D);
3087 checkGLcall("glDisable(GL_TEXTURE_2D)");
3088 glDisable(GL_TEXTURE_3D);
3089 checkGLcall("glDisable(GL_TEXTURE_3D)");
3090 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3092 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3093 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3095 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3096 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3097 break;
3099 } else {
3100 glEnable(GL_TEXTURE_2D);
3101 checkGLcall("glEnable(GL_TEXTURE_2D)");
3102 glDisable(GL_TEXTURE_3D);
3103 checkGLcall("glDisable(GL_TEXTURE_3D)");
3104 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3106 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3107 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3109 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3111 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3112 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3114 /* Binding textures is done by samplers. A dummy texture will be bound */
3118 /* GL locking is done by the caller (state handler) */
3119 void sampler_texdim(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3121 DWORD sampler = state - STATE_SAMPLER(0);
3122 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3124 /* No need to enable / disable anything here for unused samplers. The tex_colorop
3125 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3126 * will take care of this business
3128 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3129 if (sampler >= stateblock->state.lowest_disabled_stage) return;
3130 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3132 texture_activate_dimensions(stateblock->state.textures[sampler], context->gl_info);
3135 void *wined3d_rb_alloc(size_t size)
3137 return HeapAlloc(GetProcessHeap(), 0, size);
3140 void *wined3d_rb_realloc(void *ptr, size_t size)
3142 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3145 void wined3d_rb_free(void *ptr)
3147 HeapFree(GetProcessHeap(), 0, ptr);
3150 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3152 const struct ffp_frag_settings *ka = key;
3153 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3155 return memcmp(ka, kb, sizeof(*ka));
3158 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3160 wined3d_rb_alloc,
3161 wined3d_rb_realloc,
3162 wined3d_rb_free,
3163 ffp_frag_program_key_compare,
3166 UINT wined3d_log2i(UINT32 x)
3168 static const UINT l[] =
3170 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3171 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3172 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3173 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3174 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3175 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3176 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3177 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3178 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3179 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3180 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3181 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3182 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3183 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3184 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3185 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3187 UINT32 i;
3189 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3192 /* Set the shader type for this device, depending on the given capabilities
3193 * and the user preferences in wined3d_settings. */
3194 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3196 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3198 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3199 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3201 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3202 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3203 * shaders only on this card. */
3204 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3205 else *vs_selected = SHADER_GLSL;
3207 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3208 else *vs_selected = SHADER_NONE;
3210 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3211 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3212 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3213 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3214 else *ps_selected = SHADER_NONE;
3217 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3218 const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format *src_format,
3219 const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format *dst_format)
3221 static const struct blit_shader * const blitters[] =
3223 &arbfp_blit,
3224 &ffp_blit,
3225 &cpu_blit,
3227 unsigned int i;
3229 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3231 if (blitters[i]->blit_supported(gl_info, blit_op,
3232 src_rect, src_usage, src_pool, src_format,
3233 dst_rect, dst_usage, dst_pool, dst_format))
3234 return blitters[i];
3237 return NULL;