msxml3: Fix attributes formatting.
[wine/multimedia.git] / dlls / wined3d / utils.c
blob2ef27d01e46fb735e548ff10a46ac12afbab36e5
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},
137 /* Unsure about them, could not find a Windows driver that supports them */
138 {WINED3DFMT_R16, 0x0, 0x0000ffff, 0x0, 0x0, 2, 0, 0},
139 {WINED3DFMT_AL16, 0xffff0000, 0x0, 0x0, 0x0, 4, 0, 0},
142 struct wined3d_format_base_flags
144 enum wined3d_format_id id;
145 DWORD flags;
148 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
149 * still needs to use the correct block based calculation for e.g. the
150 * resource size. */
151 static const struct wined3d_format_base_flags format_base_flags[] =
153 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
156 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
157 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
158 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
159 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
160 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
161 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
162 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
163 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
164 {WINED3DFMT_INTZ, WINED3DFMT_FLAG_FOURCC},
165 {WINED3DFMT_NULL, WINED3DFMT_FLAG_FOURCC},
166 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
171 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
172 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
173 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
174 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
175 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
176 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
177 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
178 {WINED3DFMT_NVDB, WINED3DFMT_FLAG_FOURCC},
179 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
180 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
181 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
182 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
184 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
185 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
186 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
187 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
188 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
189 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
192 struct wined3d_format_compression_info
194 enum wined3d_format_id id;
195 UINT block_width;
196 UINT block_height;
197 UINT block_byte_count;
200 static const struct wined3d_format_compression_info format_compression_info[] =
202 {WINED3DFMT_DXT1, 4, 4, 8},
203 {WINED3DFMT_DXT2, 4, 4, 16},
204 {WINED3DFMT_DXT3, 4, 4, 16},
205 {WINED3DFMT_DXT4, 4, 4, 16},
206 {WINED3DFMT_DXT5, 4, 4, 16},
207 {WINED3DFMT_ATI2N, 4, 4, 16},
210 struct wined3d_format_vertex_info
212 enum wined3d_format_id id;
213 enum wined3d_ffp_emit_idx emit_idx;
214 GLint component_count;
215 GLenum gl_vtx_type;
216 GLint gl_vtx_format;
217 GLboolean gl_normalized;
218 unsigned int component_size;
221 static const struct wined3d_format_vertex_info format_vertex_info[] =
223 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
224 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
225 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
226 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
227 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
228 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
229 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
230 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
231 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
232 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
233 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
234 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
235 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
236 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
237 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
238 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
239 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
242 struct wined3d_format_texture_info
244 enum wined3d_format_id id;
245 GLint gl_internal;
246 GLint gl_srgb_internal;
247 GLint gl_rt_internal;
248 GLint gl_format;
249 GLint gl_type;
250 unsigned int conv_byte_count;
251 unsigned int flags;
252 enum wined3d_gl_extension extension;
253 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
256 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
258 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
259 * format+type combination to load it. Thus convert it to A8L8, then load it
260 * with A4L4 internal, but A8L8 format+type
262 unsigned int x, y;
263 const unsigned char *Source;
264 unsigned char *Dest;
265 UINT outpitch = pitch * 2;
267 for(y = 0; y < height; y++) {
268 Source = src + y * pitch;
269 Dest = dst + y * outpitch;
270 for (x = 0; x < width; x++ ) {
271 unsigned char color = (*Source++);
272 /* A */ Dest[1] = (color & 0xf0) << 0;
273 /* L */ Dest[0] = (color & 0x0f) << 4;
274 Dest += 2;
279 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
281 unsigned int x, y;
282 const WORD *Source;
284 for(y = 0; y < height; y++)
286 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
287 Source = (const WORD *)(src + y * pitch);
288 for (x = 0; x < width; x++ )
290 short color = (*Source++);
291 unsigned char l = ((color >> 10) & 0xfc);
292 short v = ((color >> 5) & 0x3e);
293 short u = ((color ) & 0x1f);
294 short v_conv = v + 16;
295 short u_conv = u + 16;
297 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
298 Dest_s += 1;
303 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
305 unsigned int x, y;
306 const WORD *Source;
307 unsigned char *Dest;
308 UINT outpitch = (pitch * 3)/2;
310 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
311 * fixed function and shaders without further conversion once the surface is
312 * loaded
314 for(y = 0; y < height; y++) {
315 Source = (const WORD *)(src + y * pitch);
316 Dest = dst + y * outpitch;
317 for (x = 0; x < width; x++ ) {
318 short color = (*Source++);
319 unsigned char l = ((color >> 10) & 0xfc);
320 char v = ((color >> 5) & 0x3e);
321 char u = ((color ) & 0x1f);
323 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
324 * and doubles the positive range. Thus shift left only once, gl does the 2nd
325 * shift. GL reads a signed value and converts it into an unsigned value.
327 /* M */ Dest[2] = l << 1;
329 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
330 * from 5 bit values to 8 bit values.
332 /* V */ Dest[1] = v << 3;
333 /* U */ Dest[0] = u << 3;
334 Dest += 3;
339 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
341 unsigned int x, y;
342 const short *Source;
343 unsigned char *Dest;
344 UINT outpitch = (pitch * 3)/2;
346 for(y = 0; y < height; y++)
348 Source = (const short *)(src + y * pitch);
349 Dest = dst + y * outpitch;
350 for (x = 0; x < width; x++ )
352 const short color = (*Source++);
353 /* B */ Dest[0] = 0xff;
354 /* G */ Dest[1] = (color >> 8) + 128; /* V */
355 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
356 Dest += 3;
361 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
363 unsigned int x, y;
364 const DWORD *Source;
365 unsigned char *Dest;
367 /* Doesn't work correctly with the fixed function pipeline, but can work in
368 * shaders if the shader is adjusted. (There's no use for this format in gl's
369 * standard fixed function pipeline anyway).
371 for(y = 0; y < height; y++)
373 Source = (const DWORD *)(src + y * pitch);
374 Dest = dst + y * pitch;
375 for (x = 0; x < width; x++ )
377 LONG color = (*Source++);
378 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
379 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
380 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
381 Dest += 4;
386 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
388 unsigned int x, y;
389 const DWORD *Source;
390 unsigned char *Dest;
392 /* This implementation works with the fixed function pipeline and shaders
393 * without further modification after converting the surface.
395 for(y = 0; y < height; y++)
397 Source = (const DWORD *)(src + y * pitch);
398 Dest = dst + y * pitch;
399 for (x = 0; x < width; x++ )
401 LONG color = (*Source++);
402 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
403 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
404 /* U */ Dest[0] = (color & 0xff); /* U */
405 /* I */ Dest[3] = 255; /* X */
406 Dest += 4;
411 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
413 unsigned int x, y;
414 const DWORD *Source;
415 unsigned char *Dest;
417 for(y = 0; y < height; y++)
419 Source = (const DWORD *)(src + y * pitch);
420 Dest = dst + y * pitch;
421 for (x = 0; x < width; x++ )
423 LONG color = (*Source++);
424 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
425 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
426 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
427 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
428 Dest += 4;
433 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
435 unsigned int x, y;
436 const DWORD *Source;
437 unsigned short *Dest;
438 UINT outpitch = (pitch * 3)/2;
440 for(y = 0; y < height; y++)
442 Source = (const DWORD *)(src + y * pitch);
443 Dest = (unsigned short *) (dst + y * outpitch);
444 for (x = 0; x < width; x++ )
446 const DWORD color = (*Source++);
447 /* B */ Dest[0] = 0xffff;
448 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
449 /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */
450 Dest += 3;
455 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
457 unsigned int x, y;
458 const WORD *Source;
459 WORD *Dest;
460 UINT outpitch = (pitch * 3)/2;
462 for(y = 0; y < height; y++)
464 Source = (const WORD *)(src + y * pitch);
465 Dest = (WORD *) (dst + y * outpitch);
466 for (x = 0; x < width; x++ )
468 WORD green = (*Source++);
469 WORD red = (*Source++);
470 Dest[0] = green;
471 Dest[1] = red;
472 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
473 * shader overwrites it anyway
475 Dest[2] = 0xffff;
476 Dest += 3;
481 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
483 unsigned int x, y;
484 const float *Source;
485 float *Dest;
486 UINT outpitch = (pitch * 3)/2;
488 for(y = 0; y < height; y++)
490 Source = (const float *)(src + y * pitch);
491 Dest = (float *) (dst + y * outpitch);
492 for (x = 0; x < width; x++ )
494 float green = (*Source++);
495 float red = (*Source++);
496 Dest[0] = green;
497 Dest[1] = red;
498 Dest[2] = 1.0f;
499 Dest += 3;
504 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
506 unsigned int x, y;
507 UINT outpitch = pitch * 2;
509 for (y = 0; y < height; ++y)
511 const WORD *source = (const WORD *)(src + y * pitch);
512 DWORD *dest = (DWORD *)(dst + y * outpitch);
514 for (x = 0; x < width; ++x)
516 /* The depth data is normalized, so needs to be scaled,
517 * the stencil data isn't. Scale depth data by
518 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
519 WORD d15 = source[x] >> 1;
520 DWORD d24 = (d15 << 9) + (d15 >> 6);
521 dest[x] = (d24 << 8) | (source[x] & 0x1);
526 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
528 unsigned int x, y;
530 for (y = 0; y < height; ++y)
532 const DWORD *source = (const DWORD *)(src + y * pitch);
533 DWORD *dest = (DWORD *)(dst + y * pitch);
535 for (x = 0; x < width; ++x)
537 /* Just need to clear out the X4 part. */
538 dest[x] = source[x] & ~0xf0;
543 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
545 unsigned int x, y;
546 UINT outpitch = pitch * 2;
548 for (y = 0; y < height; ++y)
550 const DWORD *source = (const DWORD *)(src + y * pitch);
551 float *dest_f = (float *)(dst + y * outpitch);
552 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
554 for (x = 0; x < width; ++x)
556 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
557 dest_s[x * 2 + 1] = source[x] & 0xff;
562 static const struct wined3d_format_texture_info format_texture_info[] =
564 /* format id internal srgbInternal rtInternal
565 format type
566 flags
567 extension */
568 /* FourCC formats */
569 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
570 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
571 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
572 * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
573 * endian machine
575 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
576 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
577 WINED3DFMT_FLAG_FILTERING,
578 WINED3D_GL_EXT_NONE, NULL},
579 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
580 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
581 WINED3DFMT_FLAG_FILTERING,
582 APPLE_YCBCR_422, NULL},
583 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
584 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
585 WINED3DFMT_FLAG_FILTERING,
586 WINED3D_GL_EXT_NONE, NULL},
587 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
588 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
589 WINED3DFMT_FLAG_FILTERING,
590 APPLE_YCBCR_422, NULL},
591 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
592 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
593 WINED3DFMT_FLAG_FILTERING,
594 WINED3D_GL_EXT_NONE, NULL},
595 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
596 GL_RGBA, GL_UNSIGNED_BYTE, 0,
597 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
598 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
599 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
600 GL_RGBA, GL_UNSIGNED_BYTE, 0,
601 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
602 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
603 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
604 GL_RGBA, GL_UNSIGNED_BYTE, 0,
605 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
606 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
607 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
608 GL_RGBA, GL_UNSIGNED_BYTE, 0,
609 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
610 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
611 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
612 GL_RGBA, GL_UNSIGNED_BYTE, 0,
613 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
614 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
615 /* IEEE formats */
616 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
617 GL_RED, GL_FLOAT, 0,
618 WINED3DFMT_FLAG_RENDERTARGET,
619 ARB_TEXTURE_FLOAT, NULL},
620 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
621 GL_RED, GL_FLOAT, 0,
622 WINED3DFMT_FLAG_RENDERTARGET,
623 ARB_TEXTURE_RG, NULL},
624 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
625 GL_RGB, GL_FLOAT, 12,
626 WINED3DFMT_FLAG_RENDERTARGET,
627 ARB_TEXTURE_FLOAT, &convert_r32g32_float},
628 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
629 GL_RG, GL_FLOAT, 0,
630 WINED3DFMT_FLAG_RENDERTARGET,
631 ARB_TEXTURE_RG, NULL},
632 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
633 GL_RGBA, GL_FLOAT, 0,
634 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
635 ARB_TEXTURE_FLOAT, NULL},
636 /* Float */
637 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
638 GL_RED, GL_HALF_FLOAT_ARB, 0,
639 WINED3DFMT_FLAG_RENDERTARGET,
640 ARB_TEXTURE_FLOAT, NULL},
641 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
642 GL_RED, GL_HALF_FLOAT_ARB, 0,
643 WINED3DFMT_FLAG_RENDERTARGET,
644 ARB_TEXTURE_RG, NULL},
645 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
646 GL_RGB, GL_HALF_FLOAT_ARB, 6,
647 WINED3DFMT_FLAG_RENDERTARGET,
648 ARB_TEXTURE_FLOAT, &convert_r16g16},
649 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
650 GL_RG, GL_HALF_FLOAT_ARB, 0,
651 WINED3DFMT_FLAG_RENDERTARGET,
652 ARB_TEXTURE_RG, NULL},
653 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
654 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
655 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
656 ARB_TEXTURE_FLOAT, NULL},
657 /* Palettized formats */
658 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
659 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
661 ARB_FRAGMENT_PROGRAM, NULL},
662 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
663 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
665 EXT_PALETTED_TEXTURE, NULL},
666 /* Standard ARGB formats */
667 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
668 GL_BGR, GL_UNSIGNED_BYTE, 0,
669 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
670 WINED3D_GL_EXT_NONE, NULL},
671 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
672 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
673 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
674 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
675 WINED3D_GL_EXT_NONE, NULL},
676 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
677 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
678 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
679 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
680 WINED3D_GL_EXT_NONE, NULL},
681 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
682 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
683 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
684 WINED3D_GL_EXT_NONE, NULL},
685 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
686 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
687 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
688 WINED3D_GL_EXT_NONE, NULL},
689 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
690 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
691 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
692 WINED3D_GL_EXT_NONE, NULL},
693 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
694 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
695 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
696 WINED3D_GL_EXT_NONE, NULL},
697 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
698 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
699 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
700 WINED3D_GL_EXT_NONE, NULL},
701 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
702 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
703 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
704 WINED3D_GL_EXT_NONE, NULL},
705 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
706 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
707 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
708 WINED3D_GL_EXT_NONE, NULL},
709 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
710 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
711 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
712 WINED3D_GL_EXT_NONE, NULL},
713 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
714 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
715 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
716 WINED3D_GL_EXT_NONE, NULL},
717 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
718 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
719 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
720 WINED3D_GL_EXT_NONE, NULL},
721 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
722 GL_RGB, GL_UNSIGNED_SHORT, 6,
723 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
724 WINED3D_GL_EXT_NONE, &convert_r16g16},
725 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
726 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
727 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
728 WINED3D_GL_EXT_NONE, NULL},
729 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
730 GL_RGBA, GL_UNSIGNED_SHORT, 0,
731 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
732 WINED3D_GL_EXT_NONE, NULL},
733 /* Luminance */
734 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
735 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
736 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
737 WINED3D_GL_EXT_NONE, NULL},
738 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
739 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
740 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
741 WINED3D_GL_EXT_NONE, NULL},
742 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
743 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
744 WINED3DFMT_FLAG_FILTERING,
745 WINED3D_GL_EXT_NONE, &convert_l4a4_unorm},
746 /* Bump mapping stuff */
747 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
748 GL_BGR, GL_UNSIGNED_BYTE, 3,
749 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
750 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm},
751 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
752 GL_DSDT_NV, GL_BYTE, 0,
753 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
754 NV_TEXTURE_SHADER, NULL},
755 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
756 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
757 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
758 WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm},
759 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
760 GL_DSDT_MAG_NV, GL_BYTE, 3,
761 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
762 NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv},
763 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
764 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
765 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
766 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm},
767 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
768 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
769 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
770 NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv},
771 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
772 GL_BGRA, GL_UNSIGNED_BYTE, 4,
773 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
774 WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm},
775 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
776 GL_RGBA, GL_BYTE, 0,
777 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
778 NV_TEXTURE_SHADER, NULL},
779 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
780 GL_BGR, GL_UNSIGNED_SHORT, 6,
781 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
782 WINED3D_GL_EXT_NONE, &convert_r16g16_snorm},
783 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
784 GL_HILO_NV, GL_SHORT, 0,
785 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
786 NV_TEXTURE_SHADER, NULL},
787 /* Depth stencil formats */
788 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
789 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
790 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
791 ARB_DEPTH_TEXTURE, NULL},
792 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
793 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
794 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
795 ARB_DEPTH_TEXTURE, NULL},
796 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
797 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
798 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
799 ARB_DEPTH_TEXTURE, NULL},
800 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
801 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
802 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
803 EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm},
804 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
805 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
806 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
807 ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm},
808 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
809 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
810 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
811 | WINED3DFMT_FLAG_SHADOW,
812 ARB_DEPTH_TEXTURE, NULL},
813 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
814 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
815 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
816 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
817 EXT_PACKED_DEPTH_STENCIL, NULL},
818 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
819 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
820 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
821 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
822 ARB_FRAMEBUFFER_OBJECT, NULL},
823 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
824 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
825 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
826 | WINED3DFMT_FLAG_SHADOW,
827 ARB_DEPTH_TEXTURE, NULL},
828 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
829 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
830 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
831 ARB_DEPTH_TEXTURE, NULL},
832 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
833 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
834 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
835 EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm},
836 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
837 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
838 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
839 ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm},
840 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
841 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
842 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
843 | WINED3DFMT_FLAG_SHADOW,
844 ARB_DEPTH_TEXTURE, NULL},
845 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
846 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
847 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
848 WINED3D_GL_EXT_NONE, NULL},
849 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
850 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
851 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
852 ARB_DEPTH_BUFFER_FLOAT, NULL},
853 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
854 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
855 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
856 ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float},
857 /* Vendor-specific formats */
858 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
859 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
860 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
861 ATI_TEXTURE_COMPRESSION_3DC, NULL},
862 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2, GL_COMPRESSED_RED_GREEN_RGTC2, 0,
863 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
864 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
865 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
866 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
867 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
868 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
869 | WINED3DFMT_FLAG_STENCIL,
870 EXT_PACKED_DEPTH_STENCIL, NULL},
871 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
872 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
873 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
874 | WINED3DFMT_FLAG_STENCIL,
875 ARB_FRAMEBUFFER_OBJECT, NULL},
876 {WINED3DFMT_NULL, GL_RGBA8, GL_RGBA8, 0,
877 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
878 WINED3DFMT_FLAG_RENDERTARGET,
879 ARB_FRAMEBUFFER_OBJECT, NULL},
882 static inline int getFmtIdx(enum wined3d_format_id format_id)
884 /* First check if the format is at the position of its value.
885 * This will catch the argb formats before the loop is entered. */
886 if (format_id < (sizeof(formats) / sizeof(*formats))
887 && formats[format_id].id == format_id)
889 return format_id;
891 else
893 unsigned int i;
895 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
897 if (formats[i].id == format_id) return i;
900 return -1;
903 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
905 UINT format_count = sizeof(formats) / sizeof(*formats);
906 UINT i;
908 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
909 if (!gl_info->formats)
911 ERR("Failed to allocate memory.\n");
912 return FALSE;
915 for (i = 0; i < format_count; ++i)
917 struct wined3d_format *format = &gl_info->formats[i];
918 format->id = formats[i].id;
919 format->red_mask = formats[i].redMask;
920 format->green_mask = formats[i].greenMask;
921 format->blue_mask = formats[i].blueMask;
922 format->alpha_mask = formats[i].alphaMask;
923 format->byte_count = formats[i].bpp;
924 format->depth_size = formats[i].depthSize;
925 format->stencil_size = formats[i].stencilSize;
926 format->block_width = 1;
927 format->block_height = 1;
928 format->block_byte_count = formats[i].bpp;
931 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
933 int fmt_idx = getFmtIdx(format_base_flags[i].id);
935 if (fmt_idx == -1)
937 ERR("Format %s (%#x) not found.\n",
938 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
939 HeapFree(GetProcessHeap(), 0, gl_info->formats);
940 return FALSE;
943 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
946 return TRUE;
949 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
951 unsigned int i;
953 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
955 struct wined3d_format *format;
956 int fmt_idx = getFmtIdx(format_compression_info[i].id);
958 if (fmt_idx == -1)
960 ERR("Format %s (%#x) not found.\n",
961 debug_d3dformat(format_compression_info[i].id), format_compression_info[i].id);
962 return FALSE;
965 format = &gl_info->formats[fmt_idx];
966 format->block_width = format_compression_info[i].block_width;
967 format->block_height = format_compression_info[i].block_height;
968 format->block_byte_count = format_compression_info[i].block_byte_count;
969 format->flags |= WINED3DFMT_FLAG_COMPRESSED;
972 return TRUE;
975 /* Context activation is done by the caller. */
976 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
978 /* Check if the default internal format is supported as a frame buffer
979 * target, otherwise fall back to the render target internal.
981 * Try to stick to the standard format if possible, this limits precision differences. */
982 GLenum status;
983 GLuint tex;
985 ENTER_GL();
987 while(glGetError());
988 glDisable(GL_BLEND);
990 glGenTextures(1, &tex);
991 glBindTexture(GL_TEXTURE_2D, tex);
993 glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
994 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
995 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
997 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
999 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1000 checkGLcall("Framebuffer format check");
1002 if (status == GL_FRAMEBUFFER_COMPLETE)
1004 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1005 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1006 format->rtInternal = format->glInternal;
1008 else
1010 if (!format->rtInternal)
1012 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1014 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1015 " and no fallback specified.\n", debug_d3dformat(format->id));
1016 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1018 else
1020 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1022 format->rtInternal = format->glInternal;
1024 else
1026 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1027 debug_d3dformat(format->id));
1029 while(glGetError());
1031 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1033 glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1034 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1035 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1037 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1039 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1040 checkGLcall("Framebuffer format check");
1042 if (status == GL_FRAMEBUFFER_COMPLETE)
1044 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1045 debug_d3dformat(format->id));
1047 else
1049 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1050 debug_d3dformat(format->id));
1051 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1056 if (status == GL_FRAMEBUFFER_COMPLETE && format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1058 GLuint rb;
1060 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1061 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1063 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1064 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1065 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1066 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1067 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1068 checkGLcall("RB attachment");
1071 glEnable(GL_BLEND);
1072 glClear(GL_COLOR_BUFFER_BIT);
1073 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1075 while(glGetError());
1076 TRACE("Format doesn't support post-pixelshader blending.\n");
1077 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1080 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1081 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1083 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1084 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1085 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1086 checkGLcall("RB cleanup");
1090 if (format->glInternal != format->glGammaInternal)
1092 glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1093 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1095 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1096 checkGLcall("Framebuffer format check");
1098 if (status == GL_FRAMEBUFFER_COMPLETE)
1100 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1101 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1103 else
1105 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1109 glDeleteTextures(1, &tex);
1111 LEAVE_GL();
1114 /* Context activation is done by the caller. */
1115 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1117 unsigned int i;
1118 GLuint fbo;
1120 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1122 ENTER_GL();
1124 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1125 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1127 LEAVE_GL();
1130 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1132 struct wined3d_format *format = &gl_info->formats[i];
1134 if (!format->glInternal) continue;
1136 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1138 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1139 debug_d3dformat(format->id));
1140 continue;
1143 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1145 TRACE("Skipping format %s because it's a compressed format.\n",
1146 debug_d3dformat(format->id));
1147 continue;
1150 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1152 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1153 check_fbo_compat(gl_info, format);
1155 else
1157 format->rtInternal = format->glInternal;
1161 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1163 ENTER_GL();
1165 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1167 LEAVE_GL();
1171 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1173 unsigned int i;
1175 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1177 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1178 struct wined3d_format *format;
1180 if (fmt_idx == -1)
1182 ERR("Format %s (%#x) not found.\n",
1183 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1184 return FALSE;
1187 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1189 format = &gl_info->formats[fmt_idx];
1191 /* ARB_texture_rg defines floating point formats, but only if
1192 * ARB_texture_float is also supported. */
1193 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1194 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1195 continue;
1197 format->glInternal = format_texture_info[i].gl_internal;
1198 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1199 format->rtInternal = format_texture_info[i].gl_rt_internal;
1200 format->glFormat = format_texture_info[i].gl_format;
1201 format->glType = format_texture_info[i].gl_type;
1202 format->color_fixup = COLOR_FIXUP_IDENTITY;
1203 format->flags |= format_texture_info[i].flags;
1204 format->heightscale = 1.0f;
1206 if (format->glGammaInternal != format->glInternal)
1208 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1209 if (!gl_info->supported[EXT_TEXTURE_SRGB])
1211 format->glGammaInternal = format->glInternal;
1212 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1214 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1216 format->glInternal = format->glGammaInternal;
1220 /* Texture conversion stuff */
1221 format->convert = format_texture_info[i].convert;
1222 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1225 return TRUE;
1228 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1230 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1231 c1 >>= 8; c2 >>= 8;
1232 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1233 c1 >>= 8; c2 >>= 8;
1234 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1235 c1 >>= 8; c2 >>= 8;
1236 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1237 return TRUE;
1240 /* A context is provided by the caller */
1241 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1243 static const DWORD data[] = {0x00000000, 0xffffffff};
1244 GLuint tex, fbo, buffer;
1245 DWORD readback[16 * 1];
1246 BOOL ret = FALSE;
1248 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1249 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1250 * falling back to software. If this changes in the future this code will get fooled and
1251 * apps might hit the software path due to incorrectly advertised caps.
1253 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1254 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1255 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1258 ENTER_GL();
1259 while(glGetError());
1261 glGenTextures(1, &buffer);
1262 glBindTexture(GL_TEXTURE_2D, buffer);
1263 memset(readback, 0x7e, sizeof(readback));
1264 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1265 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1266 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1267 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1268 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1271 glGenTextures(1, &tex);
1272 glBindTexture(GL_TEXTURE_2D, tex);
1273 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1274 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1275 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1276 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1277 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1278 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1279 glEnable(GL_TEXTURE_2D);
1281 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1282 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1283 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1284 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1286 glViewport(0, 0, 16, 1);
1287 glDisable(GL_LIGHTING);
1288 glMatrixMode(GL_MODELVIEW);
1289 glLoadIdentity();
1290 glMatrixMode(GL_PROJECTION);
1291 glLoadIdentity();
1293 glClearColor(0, 1, 0, 0);
1294 glClear(GL_COLOR_BUFFER_BIT);
1296 glBegin(GL_TRIANGLE_STRIP);
1297 glTexCoord2f(0.0, 0.0);
1298 glVertex2f(-1.0f, -1.0f);
1299 glTexCoord2f(1.0, 0.0);
1300 glVertex2f(1.0f, -1.0f);
1301 glTexCoord2f(0.0, 1.0);
1302 glVertex2f(-1.0f, 1.0f);
1303 glTexCoord2f(1.0, 1.0);
1304 glVertex2f(1.0f, 1.0f);
1305 glEnd();
1307 glBindTexture(GL_TEXTURE_2D, buffer);
1308 memset(readback, 0x7f, sizeof(readback));
1309 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1310 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1311 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1313 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1314 readback[6], readback[9]);
1315 ret = FALSE;
1317 else
1319 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1320 readback[6], readback[9]);
1321 ret = TRUE;
1324 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1325 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1326 glDeleteTextures(1, &tex);
1327 glDeleteTextures(1, &buffer);
1329 if(glGetError())
1331 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1332 ret = FALSE;
1334 LEAVE_GL();
1335 return ret;
1338 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1340 struct wined3d_format *format;
1341 unsigned int fmt_idx, i;
1342 static const enum wined3d_format_id fmts16[] =
1344 WINED3DFMT_R16_FLOAT,
1345 WINED3DFMT_R16G16_FLOAT,
1346 WINED3DFMT_R16G16B16A16_FLOAT,
1348 BOOL filtered;
1350 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1352 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1353 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1355 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1356 filtered = TRUE;
1358 else if (gl_info->limits.glsl_varyings > 44)
1360 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1361 filtered = TRUE;
1363 else
1365 TRACE("Assuming no float16 blending\n");
1366 filtered = FALSE;
1369 if(filtered)
1371 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1373 fmt_idx = getFmtIdx(fmts16[i]);
1374 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1377 return;
1380 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1382 fmt_idx = getFmtIdx(fmts16[i]);
1383 format = &gl_info->formats[fmt_idx];
1384 if (!format->glInternal) continue; /* Not supported by GL */
1386 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1387 if(filtered)
1389 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1390 format->flags |= WINED3DFMT_FLAG_FILTERING;
1392 else
1394 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1399 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1401 int idx;
1403 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1404 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1405 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1407 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1408 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1409 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1411 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1412 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1413 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1415 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1416 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1417 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1419 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1420 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1421 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1423 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1424 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1425 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1426 * the only driver that implements it(fglrx) has a buggy implementation.
1428 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1429 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1430 * conversion for this format.
1432 if (!gl_info->supported[NV_TEXTURE_SHADER])
1434 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1435 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1436 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1437 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1438 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1439 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1441 else
1443 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1444 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1445 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1447 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1448 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1449 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1452 if (!gl_info->supported[NV_TEXTURE_SHADER])
1454 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1455 * with each other
1457 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1458 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1459 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1460 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1461 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1462 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1463 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1464 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1465 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1467 else
1469 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1470 * are converted at surface loading time, but they do not need any modification in
1471 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1472 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1476 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1478 idx = getFmtIdx(WINED3DFMT_ATI2N);
1479 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1480 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1482 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1484 idx = getFmtIdx(WINED3DFMT_ATI2N);
1485 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1486 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1489 if (!gl_info->supported[APPLE_YCBCR_422])
1491 idx = getFmtIdx(WINED3DFMT_YUY2);
1492 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1494 idx = getFmtIdx(WINED3DFMT_UYVY);
1495 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1498 idx = getFmtIdx(WINED3DFMT_YV12);
1499 gl_info->formats[idx].heightscale = 1.5f;
1500 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1502 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1504 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1505 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1508 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1510 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1511 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1514 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1516 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1517 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1518 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1519 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1521 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1522 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1526 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1528 unsigned int i;
1530 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1532 struct wined3d_format *format;
1533 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1535 if (fmt_idx == -1)
1537 ERR("Format %s (%#x) not found.\n",
1538 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1539 return FALSE;
1542 format = &gl_info->formats[fmt_idx];
1543 format->emit_idx = format_vertex_info[i].emit_idx;
1544 format->component_count = format_vertex_info[i].component_count;
1545 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1546 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1547 format->gl_normalized = format_vertex_info[i].gl_normalized;
1548 format->component_size = format_vertex_info[i].component_size;
1551 return TRUE;
1554 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1556 if (!init_format_base_info(gl_info)) return FALSE;
1558 if (!init_format_compression_info(gl_info))
1560 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1561 gl_info->formats = NULL;
1562 return FALSE;
1565 return TRUE;
1568 /* Context activation is done by the caller. */
1569 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1571 if (!init_format_base_info(gl_info)) return FALSE;
1573 if (!init_format_compression_info(gl_info)) goto fail;
1574 if (!init_format_texture_info(gl_info)) goto fail;
1575 if (!init_format_vertex_info(gl_info)) goto fail;
1577 apply_format_fixups(gl_info);
1578 init_format_fbo_compat_info(gl_info);
1579 init_format_filter_info(gl_info, vendor);
1581 return TRUE;
1583 fail:
1584 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1585 gl_info->formats = NULL;
1586 return FALSE;
1589 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1590 enum wined3d_format_id format_id)
1592 int idx = getFmtIdx(format_id);
1594 if (idx == -1)
1596 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1597 debug_d3dformat(format_id), format_id);
1598 /* Get the caller a valid pointer */
1599 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1602 return &gl_info->formats[idx];
1605 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1607 UINT size;
1609 if (format->id == WINED3DFMT_UNKNOWN)
1611 size = 0;
1613 else if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1615 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1616 UINT row_count = (height + format->block_height - 1) / format->block_height;
1617 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1619 else
1621 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1624 if (format->heightscale != 0.0f)
1626 /* The D3D format requirements make sure that the resulting format is an integer again */
1627 size = (UINT) (size * format->heightscale);
1630 return size;
1633 /*****************************************************************************
1634 * Trace formatting of useful values
1636 const char *debug_d3dformat(enum wined3d_format_id format_id)
1638 switch (format_id)
1640 #define FMT_TO_STR(format_id) case format_id: return #format_id
1641 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1642 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1643 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1644 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1645 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1646 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1647 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1648 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1649 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1650 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1651 FMT_TO_STR(WINED3DFMT_P8_UINT);
1652 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1653 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1654 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1655 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1656 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1657 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1658 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1659 FMT_TO_STR(WINED3DFMT_UYVY);
1660 FMT_TO_STR(WINED3DFMT_YUY2);
1661 FMT_TO_STR(WINED3DFMT_YV12);
1662 FMT_TO_STR(WINED3DFMT_DXT1);
1663 FMT_TO_STR(WINED3DFMT_DXT2);
1664 FMT_TO_STR(WINED3DFMT_DXT3);
1665 FMT_TO_STR(WINED3DFMT_DXT4);
1666 FMT_TO_STR(WINED3DFMT_DXT5);
1667 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1668 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1669 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1670 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1671 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1672 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1673 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1674 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1675 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1676 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1677 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1678 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1679 FMT_TO_STR(WINED3DFMT_ATI2N);
1680 FMT_TO_STR(WINED3DFMT_NVDB);
1681 FMT_TO_STR(WINED3DFMT_NVHU);
1682 FMT_TO_STR(WINED3DFMT_NVHS);
1683 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1684 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1685 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1686 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1687 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1688 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1689 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1690 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1691 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1692 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1693 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1694 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1695 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1696 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1697 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1698 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1699 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1700 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1701 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1702 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1703 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1704 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1705 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1706 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1707 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1708 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1709 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1710 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1711 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1712 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1713 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1714 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1715 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1716 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1717 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1718 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1719 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1720 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1721 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1722 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1723 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1724 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1725 FMT_TO_STR(WINED3DFMT_R32_UINT);
1726 FMT_TO_STR(WINED3DFMT_R32_SINT);
1727 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1728 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1729 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1730 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1731 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1732 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1733 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1734 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1735 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1736 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1737 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1738 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1739 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1740 FMT_TO_STR(WINED3DFMT_R16_UINT);
1741 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1742 FMT_TO_STR(WINED3DFMT_R16_SINT);
1743 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1744 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1745 FMT_TO_STR(WINED3DFMT_R8_UINT);
1746 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1747 FMT_TO_STR(WINED3DFMT_R8_SINT);
1748 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1749 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1750 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1751 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1752 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1753 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1754 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1755 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1756 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1757 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1758 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1759 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1760 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1761 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1762 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1763 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1764 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1765 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1766 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1767 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1768 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1769 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1770 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1771 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1772 FMT_TO_STR(WINED3DFMT_INTZ);
1773 FMT_TO_STR(WINED3DFMT_NULL);
1774 FMT_TO_STR(WINED3DFMT_R16);
1775 FMT_TO_STR(WINED3DFMT_AL16);
1776 #undef FMT_TO_STR
1777 default:
1779 char fourcc[5];
1780 fourcc[0] = (char)(format_id);
1781 fourcc[1] = (char)(format_id >> 8);
1782 fourcc[2] = (char)(format_id >> 16);
1783 fourcc[3] = (char)(format_id >> 24);
1784 fourcc[4] = 0;
1785 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1786 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1787 else
1788 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1790 return "unrecognized";
1794 const char *debug_d3ddevicetype(WINED3DDEVTYPE devtype)
1796 switch (devtype)
1798 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1799 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1800 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1801 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1802 #undef DEVTYPE_TO_STR
1803 default:
1804 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1805 return "unrecognized";
1809 const char *debug_d3dusage(DWORD usage)
1811 char buf[333];
1813 buf[0] = '\0';
1814 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1815 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1816 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1817 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1818 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1819 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1820 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1821 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1822 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1823 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1824 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1825 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1826 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1827 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1828 #undef WINED3DUSAGE_TO_STR
1829 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1831 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1834 const char *debug_d3dusagequery(DWORD usagequery)
1836 char buf[238];
1838 buf[0] = '\0';
1839 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1840 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1841 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1842 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1843 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1844 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1845 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1846 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1847 #undef WINED3DUSAGEQUERY_TO_STR
1848 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1850 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1853 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1854 switch (method) {
1855 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1856 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1857 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1858 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1859 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1860 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1861 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1862 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1863 #undef WINED3DDECLMETHOD_TO_STR
1864 default:
1865 FIXME("Unrecognized %u declaration method!\n", method);
1866 return "unrecognized";
1870 const char* debug_d3ddeclusage(BYTE usage) {
1871 switch (usage) {
1872 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1873 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1874 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1875 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1876 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1877 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1878 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1879 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1880 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1881 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1882 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1883 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1884 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1885 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1886 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1887 #undef WINED3DDECLUSAGE_TO_STR
1888 default:
1889 FIXME("Unrecognized %u declaration usage!\n", usage);
1890 return "unrecognized";
1894 const char *debug_d3dresourcetype(WINED3DRESOURCETYPE res)
1896 switch (res)
1898 #define RES_TO_STR(res) case res: return #res
1899 RES_TO_STR(WINED3DRTYPE_SURFACE);
1900 RES_TO_STR(WINED3DRTYPE_VOLUME);
1901 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1902 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1903 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1904 RES_TO_STR(WINED3DRTYPE_BUFFER);
1905 #undef RES_TO_STR
1906 default:
1907 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1908 return "unrecognized";
1912 const char *debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType)
1914 switch (PrimitiveType)
1916 #define PRIM_TO_STR(prim) case prim: return #prim
1917 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1918 PRIM_TO_STR(WINED3DPT_POINTLIST);
1919 PRIM_TO_STR(WINED3DPT_LINELIST);
1920 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1921 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1922 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1923 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1924 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1925 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1926 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1927 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1928 #undef PRIM_TO_STR
1929 default:
1930 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1931 return "unrecognized";
1935 const char *debug_d3drenderstate(WINED3DRENDERSTATETYPE state)
1937 switch (state)
1939 #define D3DSTATE_TO_STR(u) case u: return #u
1940 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS);
1941 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE);
1942 D3DSTATE_TO_STR(WINED3DRS_WRAPU);
1943 D3DSTATE_TO_STR(WINED3DRS_WRAPV);
1944 D3DSTATE_TO_STR(WINED3DRS_ZENABLE);
1945 D3DSTATE_TO_STR(WINED3DRS_FILLMODE);
1946 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE);
1947 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN);
1948 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE);
1949 D3DSTATE_TO_STR(WINED3DRS_ROP2);
1950 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK);
1951 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE);
1952 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE);
1953 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL);
1954 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND);
1955 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND);
1956 D3DSTATE_TO_STR(WINED3DRS_CULLMODE);
1957 D3DSTATE_TO_STR(WINED3DRS_ZFUNC);
1958 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF);
1959 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC);
1960 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE);
1961 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE);
1962 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE);
1963 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE);
1964 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE);
1965 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL);
1966 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX);
1967 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA);
1968 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR);
1969 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE);
1970 D3DSTATE_TO_STR(WINED3DRS_FOGSTART);
1971 D3DSTATE_TO_STR(WINED3DRS_FOGEND);
1972 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY);
1973 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE);
1974 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS);
1975 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE);
1976 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS);
1977 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE);
1978 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY);
1979 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH);
1980 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1981 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE);
1982 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL);
1983 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL);
1984 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS);
1985 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC);
1986 D3DSTATE_TO_STR(WINED3DRS_STENCILREF);
1987 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK);
1988 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK);
1989 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR);
1990 D3DSTATE_TO_STR(WINED3DRS_WRAP0);
1991 D3DSTATE_TO_STR(WINED3DRS_WRAP1);
1992 D3DSTATE_TO_STR(WINED3DRS_WRAP2);
1993 D3DSTATE_TO_STR(WINED3DRS_WRAP3);
1994 D3DSTATE_TO_STR(WINED3DRS_WRAP4);
1995 D3DSTATE_TO_STR(WINED3DRS_WRAP5);
1996 D3DSTATE_TO_STR(WINED3DRS_WRAP6);
1997 D3DSTATE_TO_STR(WINED3DRS_WRAP7);
1998 D3DSTATE_TO_STR(WINED3DRS_CLIPPING);
1999 D3DSTATE_TO_STR(WINED3DRS_LIGHTING);
2000 D3DSTATE_TO_STR(WINED3DRS_EXTENTS);
2001 D3DSTATE_TO_STR(WINED3DRS_AMBIENT);
2002 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE);
2003 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX);
2004 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER);
2005 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS);
2006 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE);
2007 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE);
2008 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE);
2009 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE);
2010 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE);
2011 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND);
2012 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE);
2013 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING);
2014 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE);
2015 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN);
2016 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE);
2017 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE);
2018 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A);
2019 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B);
2020 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C);
2021 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS);
2022 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK);
2023 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE);
2024 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS);
2025 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN);
2026 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX);
2027 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE);
2028 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE);
2029 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR);
2030 D3DSTATE_TO_STR(WINED3DRS_BLENDOP);
2031 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE);
2032 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE);
2033 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE);
2034 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS);
2035 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE);
2036 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL);
2037 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL);
2038 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X);
2039 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y);
2040 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z);
2041 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W);
2042 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
2043 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE);
2044 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL);
2045 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL);
2046 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS);
2047 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC);
2048 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1);
2049 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2);
2050 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3);
2051 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR);
2052 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE);
2053 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS);
2054 D3DSTATE_TO_STR(WINED3DRS_WRAP8);
2055 D3DSTATE_TO_STR(WINED3DRS_WRAP9);
2056 D3DSTATE_TO_STR(WINED3DRS_WRAP10);
2057 D3DSTATE_TO_STR(WINED3DRS_WRAP11);
2058 D3DSTATE_TO_STR(WINED3DRS_WRAP12);
2059 D3DSTATE_TO_STR(WINED3DRS_WRAP13);
2060 D3DSTATE_TO_STR(WINED3DRS_WRAP14);
2061 D3DSTATE_TO_STR(WINED3DRS_WRAP15);
2062 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE);
2063 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA);
2064 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA);
2065 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA);
2066 #undef D3DSTATE_TO_STR
2067 default:
2068 FIXME("Unrecognized %u render state!\n", state);
2069 return "unrecognized";
2073 const char *debug_d3dsamplerstate(DWORD state)
2075 switch (state)
2077 #define D3DSTATE_TO_STR(u) case u: return #u
2078 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR);
2079 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU);
2080 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV);
2081 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW);
2082 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER);
2083 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER);
2084 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER);
2085 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
2086 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL);
2087 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
2088 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE);
2089 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX);
2090 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET);
2091 #undef D3DSTATE_TO_STR
2092 default:
2093 FIXME("Unrecognized %u sampler state!\n", state);
2094 return "unrecognized";
2098 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2099 switch (filter_type) {
2100 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2101 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2102 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2103 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2104 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2105 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2106 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2107 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2108 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2109 #undef D3DTEXTUREFILTERTYPE_TO_STR
2110 default:
2111 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2112 return "unrecognized";
2116 const char *debug_d3dtexturestate(DWORD state)
2118 switch (state)
2120 #define D3DSTATE_TO_STR(u) case u: return #u
2121 D3DSTATE_TO_STR(WINED3DTSS_COLOROP);
2122 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1);
2123 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2);
2124 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP);
2125 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1);
2126 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2);
2127 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00);
2128 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01);
2129 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10);
2130 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11);
2131 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX);
2132 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE);
2133 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET);
2134 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS);
2135 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0);
2136 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0);
2137 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG);
2138 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT);
2139 #undef D3DSTATE_TO_STR
2140 default:
2141 FIXME("Unrecognized %u texture state!\n", state);
2142 return "unrecognized";
2146 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2147 switch (d3dtop) {
2148 #define D3DTOP_TO_STR(u) case u: return #u
2149 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2150 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2151 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2152 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2153 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2154 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2155 D3DTOP_TO_STR(WINED3DTOP_ADD);
2156 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2157 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2158 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2159 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2160 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2161 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2162 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2163 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2164 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2165 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2166 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2167 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2168 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2169 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2170 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2171 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2172 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2173 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2174 D3DTOP_TO_STR(WINED3DTOP_LERP);
2175 #undef D3DTOP_TO_STR
2176 default:
2177 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2178 return "unrecognized";
2182 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2183 switch (tstype) {
2184 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2185 TSTYPE_TO_STR(WINED3DTS_VIEW);
2186 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2187 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2188 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2189 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2190 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2191 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2192 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2193 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2194 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2195 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2196 #undef TSTYPE_TO_STR
2197 default:
2198 if (tstype > 256 && tstype < 512) {
2199 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2200 return ("WINED3DTS_WORLDMATRIX > 0");
2202 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2203 return "unrecognized";
2207 const char *debug_d3dstate(DWORD state)
2209 if (STATE_IS_RENDER(state))
2210 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2211 if (STATE_IS_TEXTURESTAGE(state))
2213 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2214 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2215 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2216 texture_stage, debug_d3dtexturestate(texture_state));
2218 if (STATE_IS_SAMPLER(state))
2219 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2220 if (STATE_IS_PIXELSHADER(state))
2221 return "STATE_PIXELSHADER";
2222 if (STATE_IS_TRANSFORM(state))
2223 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2224 if (STATE_IS_STREAMSRC(state))
2225 return "STATE_STREAMSRC";
2226 if (STATE_IS_INDEXBUFFER(state))
2227 return "STATE_INDEXBUFFER";
2228 if (STATE_IS_VDECL(state))
2229 return "STATE_VDECL";
2230 if (STATE_IS_VSHADER(state))
2231 return "STATE_VSHADER";
2232 if (STATE_IS_VIEWPORT(state))
2233 return "STATE_VIEWPORT";
2234 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2235 return "STATE_VERTEXSHADERCONSTANT";
2236 if (STATE_IS_PIXELSHADERCONSTANT(state))
2237 return "STATE_PIXELSHADERCONSTANT";
2238 if (STATE_IS_ACTIVELIGHT(state))
2239 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2240 if (STATE_IS_SCISSORRECT(state))
2241 return "STATE_SCISSORRECT";
2242 if (STATE_IS_CLIPPLANE(state))
2243 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2244 if (STATE_IS_MATERIAL(state))
2245 return "STATE_MATERIAL";
2246 if (STATE_IS_FRONTFACE(state))
2247 return "STATE_FRONTFACE";
2248 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2249 return "STATE_POINTSPRITECOORDORIGIN";
2250 if (STATE_IS_BASEVERTEXINDEX(state))
2251 return "STATE_BASEVERTEXINDEX";
2252 if (STATE_IS_FRAMEBUFFER(state))
2253 return "STATE_FRAMEBUFFER";
2255 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2258 const char *debug_d3dpool(WINED3DPOOL pool)
2260 switch (pool)
2262 #define POOL_TO_STR(p) case p: return #p
2263 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2264 POOL_TO_STR(WINED3DPOOL_MANAGED);
2265 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2266 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2267 #undef POOL_TO_STR
2268 default:
2269 FIXME("Unrecognized %u WINED3DPOOL!\n", pool);
2270 return "unrecognized";
2274 const char *debug_fbostatus(GLenum status) {
2275 switch(status) {
2276 #define FBOSTATUS_TO_STR(u) case u: return #u
2277 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2278 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2279 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2280 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2281 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2282 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2283 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2284 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2285 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2286 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2287 #undef FBOSTATUS_TO_STR
2288 default:
2289 FIXME("Unrecognied FBO status 0x%08x\n", status);
2290 return "unrecognized";
2294 const char *debug_glerror(GLenum error) {
2295 switch(error) {
2296 #define GLERROR_TO_STR(u) case u: return #u
2297 GLERROR_TO_STR(GL_NO_ERROR);
2298 GLERROR_TO_STR(GL_INVALID_ENUM);
2299 GLERROR_TO_STR(GL_INVALID_VALUE);
2300 GLERROR_TO_STR(GL_INVALID_OPERATION);
2301 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2302 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2303 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2304 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2305 #undef GLERROR_TO_STR
2306 default:
2307 FIXME("Unrecognied GL error 0x%08x\n", error);
2308 return "unrecognized";
2312 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2313 switch(basis) {
2314 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2315 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2316 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2317 default: return "unrecognized";
2321 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2322 switch(degree) {
2323 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2324 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2325 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2326 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2327 default: return "unrecognized";
2331 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2333 switch(source)
2335 #define WINED3D_TO_STR(x) case x: return #x
2336 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2337 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2338 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2339 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2340 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2341 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2342 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2343 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2344 #undef WINED3D_TO_STR
2345 default:
2346 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2347 return "unrecognized";
2351 static const char *debug_complex_fixup(enum complex_fixup fixup)
2353 switch(fixup)
2355 #define WINED3D_TO_STR(x) case x: return #x
2356 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2357 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2358 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2359 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2360 #undef WINED3D_TO_STR
2361 default:
2362 FIXME("Unrecognized complex fixup %#x\n", fixup);
2363 return "unrecognized";
2367 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2369 if (is_complex_fixup(fixup))
2371 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2372 return;
2375 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2376 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2377 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2378 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2381 const char *debug_surflocation(DWORD flag) {
2382 char buf[128];
2384 buf[0] = 0;
2385 if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM"); /* 17 */
2386 if (flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE"); /* 19 */
2387 if (flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE"); /* 18 */
2388 if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX"); /* 18 */
2389 if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE"); /* 25 */
2390 if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED"); /* 22 */
2391 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2394 /*****************************************************************************
2395 * Useful functions mapping GL <-> D3D values
2397 GLenum StencilOp(DWORD op) {
2398 switch(op) {
2399 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2400 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2401 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2402 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2403 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2404 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2405 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2406 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2407 default:
2408 FIXME("Unrecognized stencil op %d\n", op);
2409 return GL_KEEP;
2413 GLenum CompareFunc(DWORD func) {
2414 switch ((WINED3DCMPFUNC)func) {
2415 case WINED3DCMP_NEVER : return GL_NEVER;
2416 case WINED3DCMP_LESS : return GL_LESS;
2417 case WINED3DCMP_EQUAL : return GL_EQUAL;
2418 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2419 case WINED3DCMP_GREATER : return GL_GREATER;
2420 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2421 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2422 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2423 default:
2424 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2425 return 0;
2429 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2430 WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
2432 if (op == WINED3DTOP_DISABLE) return FALSE;
2433 if (state->textures[stage]) return FALSE;
2435 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2436 && op != WINED3DTOP_SELECTARG2) return TRUE;
2437 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2438 && op != WINED3DTOP_SELECTARG1) return TRUE;
2439 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2440 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2442 return FALSE;
2445 /* Setup this textures matrix according to the texture flags*/
2446 /* GL locking is done by the caller (state handler) */
2447 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2448 enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2450 float mat[16];
2452 glMatrixMode(GL_TEXTURE);
2453 checkGLcall("glMatrixMode(GL_TEXTURE)");
2455 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2456 glLoadIdentity();
2457 checkGLcall("glLoadIdentity()");
2458 return;
2461 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2462 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2463 return;
2466 memcpy(mat, smat, 16 * sizeof(float));
2468 if (flags & WINED3DTTFF_PROJECTED) {
2469 if(!ffp_proj_control) {
2470 switch (flags & ~WINED3DTTFF_PROJECTED) {
2471 case WINED3DTTFF_COUNT2:
2472 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2473 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2474 break;
2475 case WINED3DTTFF_COUNT3:
2476 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2477 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2478 break;
2481 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2482 if(!calculatedCoords) {
2483 switch(vtx_fmt)
2485 case WINED3DFMT_R32_FLOAT:
2486 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2487 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2488 * the input value to the transformation will be 0, so the matrix value is irrelevant
2490 mat[12] = mat[4];
2491 mat[13] = mat[5];
2492 mat[14] = mat[6];
2493 mat[15] = mat[7];
2494 break;
2495 case WINED3DFMT_R32G32_FLOAT:
2496 /* See above, just 3rd and 4th coord
2498 mat[12] = mat[8];
2499 mat[13] = mat[9];
2500 mat[14] = mat[10];
2501 mat[15] = mat[11];
2502 break;
2503 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2504 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2506 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2507 * into a bad place. The division elimination below will apply to make sure the
2508 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2510 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2511 break;
2512 default:
2513 FIXME("Unexpected fixed function texture coord input\n");
2516 if(!ffp_proj_control) {
2517 switch (flags & ~WINED3DTTFF_PROJECTED) {
2518 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2519 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2520 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2521 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2522 * the 4th coord evaluates to 1.0 to eliminate that.
2524 * If the fixed function pipeline is used, the 4th value remains unused,
2525 * so there is no danger in doing this. With vertex shaders we have a
2526 * problem. Should an app hit that problem, the code here would have to
2527 * check for pixel shaders, and the shader has to undo the default gl divide.
2529 * A more serious problem occurs if the app passes 4 coordinates in, and the
2530 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2531 * or a replacement shader
2533 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2538 glLoadMatrixf(mat);
2539 checkGLcall("glLoadMatrixf(mat)");
2542 /* This small helper function is used to convert a bitmask into the number of masked bits */
2543 unsigned int count_bits(unsigned int mask)
2545 unsigned int count;
2546 for (count = 0; mask; ++count)
2548 mask &= mask - 1;
2550 return count;
2553 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2554 * The later function requires individual color components. */
2555 BOOL getColorBits(const struct wined3d_format *format,
2556 BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2558 TRACE("format %s.\n", debug_d3dformat(format->id));
2560 switch (format->id)
2562 case WINED3DFMT_B10G10R10A2_UNORM:
2563 case WINED3DFMT_R10G10B10A2_UNORM:
2564 case WINED3DFMT_B8G8R8X8_UNORM:
2565 case WINED3DFMT_B8G8R8_UNORM:
2566 case WINED3DFMT_B8G8R8A8_UNORM:
2567 case WINED3DFMT_R8G8B8A8_UNORM:
2568 case WINED3DFMT_B5G5R5X1_UNORM:
2569 case WINED3DFMT_B5G5R5A1_UNORM:
2570 case WINED3DFMT_B5G6R5_UNORM:
2571 case WINED3DFMT_B4G4R4X4_UNORM:
2572 case WINED3DFMT_B4G4R4A4_UNORM:
2573 case WINED3DFMT_B2G3R3_UNORM:
2574 case WINED3DFMT_P8_UINT_A8_UNORM:
2575 case WINED3DFMT_P8_UINT:
2576 break;
2577 default:
2578 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2579 return FALSE;
2582 *redSize = count_bits(format->red_mask);
2583 *greenSize = count_bits(format->green_mask);
2584 *blueSize = count_bits(format->blue_mask);
2585 *alphaSize = count_bits(format->alpha_mask);
2586 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2588 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2589 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2590 return TRUE;
2593 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2594 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
2596 TRACE("format %s.\n", debug_d3dformat(format->id));
2598 switch (format->id)
2600 case WINED3DFMT_D16_LOCKABLE:
2601 case WINED3DFMT_D16_UNORM:
2602 case WINED3DFMT_S1_UINT_D15_UNORM:
2603 case WINED3DFMT_X8D24_UNORM:
2604 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2605 case WINED3DFMT_D24_UNORM_S8_UINT:
2606 case WINED3DFMT_S8_UINT_D24_FLOAT:
2607 case WINED3DFMT_D32_UNORM:
2608 case WINED3DFMT_D32_FLOAT:
2609 case WINED3DFMT_INTZ:
2610 break;
2611 default:
2612 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2613 return FALSE;
2616 *depthSize = format->depth_size;
2617 *stencilSize = format->stencil_size;
2619 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2620 *depthSize, *stencilSize, debug_d3dformat(format->id));
2621 return TRUE;
2624 /* Note: It's the caller's responsibility to ensure values can be expressed
2625 * in the requested format. UNORM formats for example can only express values
2626 * in the range 0.0f -> 1.0f. */
2627 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const WINED3DCOLORVALUE *color)
2629 static const struct
2631 enum wined3d_format_id format_id;
2632 float r_mul;
2633 float g_mul;
2634 float b_mul;
2635 float a_mul;
2636 BYTE r_shift;
2637 BYTE g_shift;
2638 BYTE b_shift;
2639 BYTE a_shift;
2641 conv[] =
2643 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2644 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2645 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2646 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2647 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2648 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2649 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2650 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2651 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2652 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2653 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2654 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2655 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2656 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2658 const struct wined3d_format *format = surface->resource.format;
2659 unsigned int i;
2661 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2662 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2664 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2666 DWORD ret;
2668 if (format->id != conv[i].format_id) continue;
2670 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2671 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2672 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2673 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2675 TRACE("Returning 0x%08x.\n", ret);
2677 return ret;
2680 if (format->id == WINED3DFMT_P8_UINT)
2682 PALETTEENTRY *e;
2683 BYTE r, g, b, a;
2685 if (!surface->palette)
2687 WARN("Surface doesn't have a palette, returning 0.\n");
2688 return 0;
2691 r = (BYTE)((color->r * 255.0f) + 0.5f);
2692 g = (BYTE)((color->g * 255.0f) + 0.5f);
2693 b = (BYTE)((color->b * 255.0f) + 0.5f);
2694 a = (BYTE)((color->a * 255.0f) + 0.5f);
2696 e = &surface->palette->palents[a];
2697 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2698 return a;
2700 WARN("Alpha didn't match index, searching full palette.\n");
2702 for (i = 0; i < 256; ++i)
2704 e = &surface->palette->palents[i];
2705 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2706 return i;
2709 FIXME("Unable to convert color to palette index.\n");
2711 return 0;
2714 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2716 return 0;
2719 /* DirectDraw stuff */
2720 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2722 switch (depth)
2724 case 8: return WINED3DFMT_P8_UINT;
2725 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2726 case 16: return WINED3DFMT_B5G6R5_UNORM;
2727 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2728 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2729 default: return WINED3DFMT_UNKNOWN;
2733 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2734 WINED3DMATRIX temp;
2736 /* Now do the multiplication 'by hand'.
2737 I know that all this could be optimised, but this will be done later :-) */
2738 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);
2739 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);
2740 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);
2741 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);
2743 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);
2744 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);
2745 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);
2746 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);
2748 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);
2749 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);
2750 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);
2751 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);
2753 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);
2754 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);
2755 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);
2756 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);
2758 /* And copy the new matrix in the good storage.. */
2759 memcpy(dest, &temp, 16 * sizeof(float));
2762 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2763 DWORD size = 0;
2764 int i;
2765 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2767 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2768 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2769 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2770 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2771 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2772 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2773 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2774 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2775 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2776 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2777 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2778 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2779 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2780 default: ERR("Unexpected position mask\n");
2782 for (i = 0; i < numTextures; i++) {
2783 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2786 return size;
2789 void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_state *state,
2790 struct ffp_frag_settings *settings, BOOL ignore_textype)
2792 #define ARG1 0x01
2793 #define ARG2 0x02
2794 #define ARG0 0x04
2795 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2796 /* undefined */ 0,
2797 /* D3DTOP_DISABLE */ 0,
2798 /* D3DTOP_SELECTARG1 */ ARG1,
2799 /* D3DTOP_SELECTARG2 */ ARG2,
2800 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2801 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2802 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2803 /* D3DTOP_ADD */ ARG1 | ARG2,
2804 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2805 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2806 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2807 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2808 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2809 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2810 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2811 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2812 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2813 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2814 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2815 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2816 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2817 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2818 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2819 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2820 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2821 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2822 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2824 unsigned int i;
2825 DWORD ttff;
2826 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2827 const struct wined3d_surface *rt = state->fb->render_targets[0];
2828 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2830 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2832 const struct wined3d_texture *texture;
2834 settings->op[i].padding = 0;
2835 if (state->texture_states[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE)
2837 settings->op[i].cop = WINED3DTOP_DISABLE;
2838 settings->op[i].aop = WINED3DTOP_DISABLE;
2839 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2840 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2841 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2842 settings->op[i].dst = resultreg;
2843 settings->op[i].tex_type = tex_1d;
2844 settings->op[i].projected = proj_none;
2845 i++;
2846 break;
2849 if ((texture = state->textures[i]))
2851 settings->op[i].color_fixup = texture->resource.format->color_fixup;
2852 if (ignore_textype)
2854 settings->op[i].tex_type = tex_1d;
2856 else
2858 switch (texture->target)
2860 case GL_TEXTURE_1D:
2861 settings->op[i].tex_type = tex_1d;
2862 break;
2863 case GL_TEXTURE_2D:
2864 settings->op[i].tex_type = tex_2d;
2865 break;
2866 case GL_TEXTURE_3D:
2867 settings->op[i].tex_type = tex_3d;
2868 break;
2869 case GL_TEXTURE_CUBE_MAP_ARB:
2870 settings->op[i].tex_type = tex_cube;
2871 break;
2872 case GL_TEXTURE_RECTANGLE_ARB:
2873 settings->op[i].tex_type = tex_rect;
2874 break;
2877 } else {
2878 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2879 settings->op[i].tex_type = tex_1d;
2882 cop = state->texture_states[i][WINED3DTSS_COLOROP];
2883 aop = state->texture_states[i][WINED3DTSS_ALPHAOP];
2885 carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2886 carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2887 carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2889 if (is_invalid_op(state, i, cop, carg1, carg2, carg0))
2891 carg0 = ARG_UNUSED;
2892 carg2 = ARG_UNUSED;
2893 carg1 = WINED3DTA_CURRENT;
2894 cop = WINED3DTOP_SELECTARG1;
2897 if(cop == WINED3DTOP_DOTPRODUCT3) {
2898 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2899 * the color result to the alpha component of the destination
2901 aop = cop;
2902 aarg1 = carg1;
2903 aarg2 = carg2;
2904 aarg0 = carg0;
2906 else
2908 aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2909 aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2910 aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2913 if (!i && state->textures[0] && state->render_states[WINED3DRS_COLORKEYENABLE])
2915 GLenum texture_dimensions;
2917 texture = state->textures[0];
2918 texture_dimensions = texture->target;
2920 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2922 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
2924 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
2926 if (aop == WINED3DTOP_DISABLE)
2928 aarg1 = WINED3DTA_TEXTURE;
2929 aop = WINED3DTOP_SELECTARG1;
2931 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2933 if (state->render_states[WINED3DRS_ALPHABLENDENABLE])
2935 aarg2 = WINED3DTA_TEXTURE;
2936 aop = WINED3DTOP_MODULATE;
2938 else aarg1 = WINED3DTA_TEXTURE;
2940 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2942 if (state->render_states[WINED3DRS_ALPHABLENDENABLE])
2944 aarg1 = WINED3DTA_TEXTURE;
2945 aop = WINED3DTOP_MODULATE;
2947 else aarg2 = WINED3DTA_TEXTURE;
2953 if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0))
2955 aarg0 = ARG_UNUSED;
2956 aarg2 = ARG_UNUSED;
2957 aarg1 = WINED3DTA_CURRENT;
2958 aop = WINED3DTOP_SELECTARG1;
2961 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
2962 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
2964 ttff = state->texture_states[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2965 if (ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3))
2967 settings->op[i].projected = proj_count3;
2968 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2969 settings->op[i].projected = proj_count4;
2970 } else {
2971 settings->op[i].projected = proj_none;
2973 } else {
2974 settings->op[i].projected = proj_none;
2977 settings->op[i].cop = cop;
2978 settings->op[i].aop = aop;
2979 settings->op[i].carg0 = carg0;
2980 settings->op[i].carg1 = carg1;
2981 settings->op[i].carg2 = carg2;
2982 settings->op[i].aarg0 = aarg0;
2983 settings->op[i].aarg1 = aarg1;
2984 settings->op[i].aarg2 = aarg2;
2986 if (state->texture_states[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP)
2987 settings->op[i].dst = tempreg;
2988 else
2989 settings->op[i].dst = resultreg;
2992 /* Clear unsupported stages */
2993 for(; i < MAX_TEXTURES; i++) {
2994 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2997 if (!state->render_states[WINED3DRS_FOGENABLE])
2999 settings->fog = FOG_OFF;
3001 else if (state->render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
3003 if (use_vs(state) || state->vertex_declaration->position_transformed)
3005 settings->fog = FOG_LINEAR;
3007 else
3009 switch (state->render_states[WINED3DRS_FOGVERTEXMODE])
3011 case WINED3DFOG_NONE:
3012 case WINED3DFOG_LINEAR:
3013 settings->fog = FOG_LINEAR;
3014 break;
3015 case WINED3DFOG_EXP:
3016 settings->fog = FOG_EXP;
3017 break;
3018 case WINED3DFOG_EXP2:
3019 settings->fog = FOG_EXP2;
3020 break;
3024 else
3026 switch (state->render_states[WINED3DRS_FOGTABLEMODE])
3028 case WINED3DFOG_LINEAR:
3029 settings->fog = FOG_LINEAR;
3030 break;
3031 case WINED3DFOG_EXP:
3032 settings->fog = FOG_EXP;
3033 break;
3034 case WINED3DFOG_EXP2:
3035 settings->fog = FOG_EXP2;
3036 break;
3039 if (state->render_states[WINED3DRS_SRGBWRITEENABLE]
3040 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
3042 settings->sRGB_write = 1;
3043 } else {
3044 settings->sRGB_write = 0;
3046 if (device->vs_clipping || !use_vs(state) || !state->render_states[WINED3DRS_CLIPPING]
3047 || !state->render_states[WINED3DRS_CLIPPLANEENABLE])
3049 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3050 * the fixed function vertex pipeline is used(which always supports clipplanes), or
3051 * if no clipplane is enabled
3053 settings->emul_clipplanes = 0;
3054 } else {
3055 settings->emul_clipplanes = 1;
3059 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3060 const struct ffp_frag_settings *settings)
3062 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3063 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3066 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3068 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3069 * whereas desc points to an extended structure with implementation specific parts. */
3070 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3072 ERR("Failed to insert ffp frag shader.\n");
3076 /* Activates the texture dimension according to the bound D3D texture.
3077 * Does not care for the colorop or correct gl texture unit(when using nvrc)
3078 * Requires the caller to activate the correct unit before
3080 /* GL locking is done by the caller (state handler) */
3081 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3083 if (texture)
3085 switch (texture->target)
3087 case GL_TEXTURE_2D:
3088 glDisable(GL_TEXTURE_3D);
3089 checkGLcall("glDisable(GL_TEXTURE_3D)");
3090 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3092 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3093 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3095 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3097 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3098 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3100 glEnable(GL_TEXTURE_2D);
3101 checkGLcall("glEnable(GL_TEXTURE_2D)");
3102 break;
3103 case GL_TEXTURE_RECTANGLE_ARB:
3104 glDisable(GL_TEXTURE_2D);
3105 checkGLcall("glDisable(GL_TEXTURE_2D)");
3106 glDisable(GL_TEXTURE_3D);
3107 checkGLcall("glDisable(GL_TEXTURE_3D)");
3108 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3110 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3111 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3113 glEnable(GL_TEXTURE_RECTANGLE_ARB);
3114 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3115 break;
3116 case GL_TEXTURE_3D:
3117 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3119 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3120 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3122 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3124 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3125 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3127 glDisable(GL_TEXTURE_2D);
3128 checkGLcall("glDisable(GL_TEXTURE_2D)");
3129 glEnable(GL_TEXTURE_3D);
3130 checkGLcall("glEnable(GL_TEXTURE_3D)");
3131 break;
3132 case GL_TEXTURE_CUBE_MAP_ARB:
3133 glDisable(GL_TEXTURE_2D);
3134 checkGLcall("glDisable(GL_TEXTURE_2D)");
3135 glDisable(GL_TEXTURE_3D);
3136 checkGLcall("glDisable(GL_TEXTURE_3D)");
3137 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3139 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3140 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3142 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3143 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3144 break;
3146 } else {
3147 glEnable(GL_TEXTURE_2D);
3148 checkGLcall("glEnable(GL_TEXTURE_2D)");
3149 glDisable(GL_TEXTURE_3D);
3150 checkGLcall("glDisable(GL_TEXTURE_3D)");
3151 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3153 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3154 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3156 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3158 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3159 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3161 /* Binding textures is done by samplers. A dummy texture will be bound */
3165 /* GL locking is done by the caller (state handler) */
3166 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3168 DWORD sampler = state_id - STATE_SAMPLER(0);
3169 DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
3171 /* No need to enable / disable anything here for unused samplers. The
3172 * tex_colorop handler takes care. Also no action is needed with pixel
3173 * shaders, or if tex_colorop will take care of this business. */
3174 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
3175 return;
3176 if (sampler >= state->lowest_disabled_stage)
3177 return;
3178 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP)))
3179 return;
3181 texture_activate_dimensions(state->textures[sampler], context->gl_info);
3184 void *wined3d_rb_alloc(size_t size)
3186 return HeapAlloc(GetProcessHeap(), 0, size);
3189 void *wined3d_rb_realloc(void *ptr, size_t size)
3191 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3194 void wined3d_rb_free(void *ptr)
3196 HeapFree(GetProcessHeap(), 0, ptr);
3199 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3201 const struct ffp_frag_settings *ka = key;
3202 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3204 return memcmp(ka, kb, sizeof(*ka));
3207 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3209 wined3d_rb_alloc,
3210 wined3d_rb_realloc,
3211 wined3d_rb_free,
3212 ffp_frag_program_key_compare,
3215 UINT wined3d_log2i(UINT32 x)
3217 static const UINT l[] =
3219 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3220 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3221 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3222 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3223 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3224 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3225 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3226 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3227 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3228 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3229 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3230 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3231 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3232 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3233 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3234 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3236 UINT32 i;
3238 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3241 /* Set the shader type for this device, depending on the given capabilities
3242 * and the user preferences in wined3d_settings. */
3243 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3245 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3247 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3248 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3250 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3251 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3252 * shaders only on this card. */
3253 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3254 else *vs_selected = SHADER_GLSL;
3256 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3257 else *vs_selected = SHADER_NONE;
3259 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3260 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3261 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3262 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3263 else *ps_selected = SHADER_NONE;
3266 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3267 const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format *src_format,
3268 const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format *dst_format)
3270 static const struct blit_shader * const blitters[] =
3272 &arbfp_blit,
3273 &ffp_blit,
3274 &cpu_blit,
3276 unsigned int i;
3278 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3280 if (blitters[i]->blit_supported(gl_info, blit_op,
3281 src_rect, src_usage, src_pool, src_format,
3282 dst_rect, dst_usage, dst_pool, dst_format))
3283 return blitters[i];
3286 return NULL;
3289 void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
3291 const WINED3DVIEWPORT *vp = &state->viewport;
3293 SetRect(rect, vp->X, vp->Y, vp->X + vp->Width, vp->Y + vp->Height);
3295 if (state->render_states[WINED3DRS_SCISSORTESTENABLE])
3296 IntersectRect(rect, rect, &state->scissor_rect);