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
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;
37 BYTE depthSize, stencilSize;
40 /*****************************************************************************
43 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
44 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
45 * high masks do not fit into the 32 bit values needed for ddraw. It is only
46 * used for ddraw mostly, and to figure out if the format has alpha at all, so
47 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
48 * formats are not usable in 2D rendering because ddraw doesn't support them.
50 static const struct StaticPixelFormatDesc formats[] =
52 /* format id alphamask redmask greenmask bluemask bpp depth stencil */
53 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
55 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
56 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
57 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
58 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
59 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
60 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
61 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
62 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
63 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
64 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
65 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
67 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
68 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
69 {WINED3DFMT_R32G32B32_FLOAT, 0x0, 0x0, 0x0, 0x0, 12, 0, 0},
70 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0},
72 {WINED3DFMT_R8G8_SNORM_Cx, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
74 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
75 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
76 {WINED3DFMT_R16G16_SINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
77 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
78 {WINED3DFMT_R16G16B16A16_SINT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
79 /* Palettized formats */
80 {WINED3DFMT_P8_UINT_A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
81 {WINED3DFMT_P8_UINT, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
82 /* Standard ARGB formats. */
83 {WINED3DFMT_B8G8R8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0},
84 {WINED3DFMT_B8G8R8A8_UNORM, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
85 {WINED3DFMT_B8G8R8X8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
86 {WINED3DFMT_B5G6R5_UNORM, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0},
87 {WINED3DFMT_B5G5R5X1_UNORM, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
88 {WINED3DFMT_B5G5R5A1_UNORM, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
89 {WINED3DFMT_B4G4R4A4_UNORM, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
90 {WINED3DFMT_B2G3R3_UNORM, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0},
91 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0},
92 {WINED3DFMT_B2G3R3A8_UNORM, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0},
93 {WINED3DFMT_B4G4R4X4_UNORM, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
94 {WINED3DFMT_R10G10B10A2_UNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
95 {WINED3DFMT_R10G10B10A2_UINT, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
96 {WINED3DFMT_R10G10B10A2_SNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
97 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
98 {WINED3DFMT_R8G8B8A8_UINT, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
99 {WINED3DFMT_R8G8B8X8_UNORM, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
100 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0},
101 {WINED3DFMT_B10G10R10A2_UNORM, 0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0},
102 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0},
104 {WINED3DFMT_L8_UNORM, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
105 {WINED3DFMT_L8A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
106 {WINED3DFMT_L4A4_UNORM, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0},
107 {WINED3DFMT_L16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
108 /* Bump mapping stuff */
109 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
110 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
111 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
112 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
113 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
114 {WINED3DFMT_R10G11B11_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
115 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0},
116 /* Depth stencil formats */
117 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
118 {WINED3DFMT_D32_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
119 {WINED3DFMT_S1_UINT_D15_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 15, 1},
120 {WINED3DFMT_D24_UNORM_S8_UINT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
121 {WINED3DFMT_X8D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 0},
122 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 4},
123 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
124 {WINED3DFMT_D32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
125 {WINED3DFMT_S8_UINT_D24_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
126 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
127 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
128 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
129 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
130 /* Vendor-specific formats */
131 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
132 {WINED3DFMT_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;
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
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_block_info
194 enum wined3d_format_id id;
197 UINT block_byte_count;
200 static const struct wined3d_format_block_info format_block_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},
208 {WINED3DFMT_YUY2, 2, 1, 4},
209 {WINED3DFMT_UYVY, 2, 1, 4},
212 struct wined3d_format_vertex_info
214 enum wined3d_format_id id;
215 enum wined3d_ffp_emit_idx emit_idx;
216 GLint component_count;
219 GLboolean gl_normalized;
220 unsigned int component_size;
223 static const struct wined3d_format_vertex_info format_vertex_info[] =
225 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
226 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
227 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
228 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
229 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
230 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
231 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
232 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
233 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
234 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
235 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
236 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
237 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
238 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
239 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
240 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
241 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
244 struct wined3d_format_texture_info
246 enum wined3d_format_id id;
248 GLint gl_srgb_internal;
249 GLint gl_rt_internal;
252 unsigned int conv_byte_count;
254 enum wined3d_gl_extension extension;
255 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
258 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
260 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
261 * format+type combination to load it. Thus convert it to A8L8, then load it
262 * with A4L4 internal, but A8L8 format+type
265 const unsigned char *Source;
267 UINT outpitch = pitch * 2;
269 for(y = 0; y < height; y++) {
270 Source = src + y * pitch;
271 Dest = dst + y * outpitch;
272 for (x = 0; x < width; x++ ) {
273 unsigned char color = (*Source++);
274 /* A */ Dest[1] = (color & 0xf0) << 0;
275 /* L */ Dest[0] = (color & 0x0f) << 4;
281 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
286 for(y = 0; y < height; y++)
288 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
289 Source = (const WORD *)(src + y * pitch);
290 for (x = 0; x < width; x++ )
292 short color = (*Source++);
293 unsigned char l = ((color >> 10) & 0xfc);
294 short v = ((color >> 5) & 0x3e);
295 short u = ((color ) & 0x1f);
296 short v_conv = v + 16;
297 short u_conv = u + 16;
299 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
305 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
310 UINT outpitch = (pitch * 3)/2;
312 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
313 * fixed function and shaders without further conversion once the surface is
316 for(y = 0; y < height; y++) {
317 Source = (const WORD *)(src + y * pitch);
318 Dest = dst + y * outpitch;
319 for (x = 0; x < width; x++ ) {
320 short color = (*Source++);
321 unsigned char l = ((color >> 10) & 0xfc);
322 char v = ((color >> 5) & 0x3e);
323 char u = ((color ) & 0x1f);
325 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
326 * and doubles the positive range. Thus shift left only once, gl does the 2nd
327 * shift. GL reads a signed value and converts it into an unsigned value.
329 /* M */ Dest[2] = l << 1;
331 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
332 * from 5 bit values to 8 bit values.
334 /* V */ Dest[1] = v << 3;
335 /* U */ Dest[0] = u << 3;
341 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
346 UINT outpitch = (pitch * 3)/2;
348 for(y = 0; y < height; y++)
350 Source = (const short *)(src + y * pitch);
351 Dest = dst + y * outpitch;
352 for (x = 0; x < width; x++ )
354 const short color = (*Source++);
355 /* B */ Dest[0] = 0xff;
356 /* G */ Dest[1] = (color >> 8) + 128; /* V */
357 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
363 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
369 /* Doesn't work correctly with the fixed function pipeline, but can work in
370 * shaders if the shader is adjusted. (There's no use for this format in gl's
371 * standard fixed function pipeline anyway).
373 for(y = 0; y < height; y++)
375 Source = (const DWORD *)(src + y * pitch);
376 Dest = dst + y * pitch;
377 for (x = 0; x < width; x++ )
379 LONG color = (*Source++);
380 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
381 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
382 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
388 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
394 /* This implementation works with the fixed function pipeline and shaders
395 * without further modification after converting the surface.
397 for(y = 0; y < height; y++)
399 Source = (const DWORD *)(src + y * pitch);
400 Dest = dst + y * pitch;
401 for (x = 0; x < width; x++ )
403 LONG color = (*Source++);
404 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
405 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
406 /* U */ Dest[0] = (color & 0xff); /* U */
407 /* I */ Dest[3] = 255; /* X */
413 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
419 for(y = 0; y < height; y++)
421 Source = (const DWORD *)(src + y * pitch);
422 Dest = dst + y * pitch;
423 for (x = 0; x < width; x++ )
425 LONG color = (*Source++);
426 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
427 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
428 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
429 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
435 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
439 unsigned short *Dest;
440 UINT outpitch = (pitch * 3)/2;
442 for(y = 0; y < height; y++)
444 Source = (const DWORD *)(src + y * pitch);
445 Dest = (unsigned short *) (dst + y * outpitch);
446 for (x = 0; x < width; x++ )
448 const DWORD color = (*Source++);
449 /* B */ Dest[0] = 0xffff;
450 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
451 /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */
457 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
462 UINT outpitch = (pitch * 3)/2;
464 for(y = 0; y < height; y++)
466 Source = (const WORD *)(src + y * pitch);
467 Dest = (WORD *) (dst + y * outpitch);
468 for (x = 0; x < width; x++ )
470 WORD green = (*Source++);
471 WORD red = (*Source++);
474 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
475 * shader overwrites it anyway
483 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
488 UINT outpitch = (pitch * 3)/2;
490 for(y = 0; y < height; y++)
492 Source = (const float *)(src + y * pitch);
493 Dest = (float *) (dst + y * outpitch);
494 for (x = 0; x < width; x++ )
496 float green = (*Source++);
497 float red = (*Source++);
506 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
509 UINT outpitch = pitch * 2;
511 for (y = 0; y < height; ++y)
513 const WORD *source = (const WORD *)(src + y * pitch);
514 DWORD *dest = (DWORD *)(dst + y * outpitch);
516 for (x = 0; x < width; ++x)
518 /* The depth data is normalized, so needs to be scaled,
519 * the stencil data isn't. Scale depth data by
520 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
521 WORD d15 = source[x] >> 1;
522 DWORD d24 = (d15 << 9) + (d15 >> 6);
523 dest[x] = (d24 << 8) | (source[x] & 0x1);
528 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
532 for (y = 0; y < height; ++y)
534 const DWORD *source = (const DWORD *)(src + y * pitch);
535 DWORD *dest = (DWORD *)(dst + y * pitch);
537 for (x = 0; x < width; ++x)
539 /* Just need to clear out the X4 part. */
540 dest[x] = source[x] & ~0xf0;
545 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
548 UINT outpitch = pitch * 2;
550 for (y = 0; y < height; ++y)
552 const DWORD *source = (const DWORD *)(src + y * pitch);
553 float *dest_f = (float *)(dst + y * outpitch);
554 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
556 for (x = 0; x < width; ++x)
558 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
559 dest_s[x * 2 + 1] = source[x] & 0xff;
564 static const struct wined3d_format_texture_info format_texture_info[] =
566 /* format id internal srgbInternal rtInternal
571 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
572 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
573 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
574 * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
577 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
578 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
579 WINED3DFMT_FLAG_FILTERING,
580 WINED3D_GL_EXT_NONE, NULL},
581 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
582 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
583 WINED3DFMT_FLAG_FILTERING,
584 APPLE_YCBCR_422, NULL},
585 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
586 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
587 WINED3DFMT_FLAG_FILTERING,
588 WINED3D_GL_EXT_NONE, NULL},
589 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
590 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
591 WINED3DFMT_FLAG_FILTERING,
592 APPLE_YCBCR_422, NULL},
593 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
594 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
595 WINED3DFMT_FLAG_FILTERING,
596 WINED3D_GL_EXT_NONE, NULL},
597 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
598 GL_RGBA, GL_UNSIGNED_BYTE, 0,
599 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
600 | WINED3DFMT_FLAG_COMPRESSED,
601 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
602 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
603 GL_RGBA, GL_UNSIGNED_BYTE, 0,
604 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
605 | WINED3DFMT_FLAG_COMPRESSED,
606 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
607 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
608 GL_RGBA, GL_UNSIGNED_BYTE, 0,
609 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
610 | WINED3DFMT_FLAG_COMPRESSED,
611 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
612 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
613 GL_RGBA, GL_UNSIGNED_BYTE, 0,
614 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
615 | WINED3DFMT_FLAG_COMPRESSED,
616 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
617 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
618 GL_RGBA, GL_UNSIGNED_BYTE, 0,
619 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
620 | WINED3DFMT_FLAG_COMPRESSED,
621 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
623 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
625 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
626 ARB_TEXTURE_FLOAT, NULL},
627 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
629 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
630 ARB_TEXTURE_RG, NULL},
631 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
632 GL_RGB, GL_FLOAT, 12,
633 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
634 ARB_TEXTURE_FLOAT, convert_r32g32_float},
635 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
637 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
638 ARB_TEXTURE_RG, NULL},
639 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
640 GL_RGBA, GL_FLOAT, 0,
641 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
642 ARB_TEXTURE_FLOAT, NULL},
644 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
645 GL_RED, GL_HALF_FLOAT_ARB, 0,
646 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
647 ARB_TEXTURE_FLOAT, NULL},
648 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
649 GL_RED, GL_HALF_FLOAT_ARB, 0,
650 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
651 ARB_TEXTURE_RG, NULL},
652 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
653 GL_RGB, GL_HALF_FLOAT_ARB, 6,
654 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
655 ARB_TEXTURE_FLOAT, convert_r16g16},
656 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
657 GL_RG, GL_HALF_FLOAT_ARB, 0,
658 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
659 ARB_TEXTURE_RG, NULL},
660 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
661 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
662 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
663 ARB_TEXTURE_FLOAT, NULL},
664 /* Palettized formats */
665 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
666 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
668 ARB_FRAGMENT_PROGRAM, NULL},
669 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
670 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
672 EXT_PALETTED_TEXTURE, NULL},
673 /* Standard ARGB formats */
674 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
675 GL_BGR, GL_UNSIGNED_BYTE, 0,
676 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
677 WINED3D_GL_EXT_NONE, NULL},
678 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
679 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
680 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
681 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE | WINED3DFMT_FLAG_VTF,
682 WINED3D_GL_EXT_NONE, NULL},
683 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
684 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
685 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
686 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
687 WINED3D_GL_EXT_NONE, NULL},
688 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
689 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
690 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
691 WINED3D_GL_EXT_NONE, NULL},
692 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
693 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
694 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
695 WINED3D_GL_EXT_NONE, NULL},
696 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
697 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
698 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
699 WINED3D_GL_EXT_NONE, NULL},
700 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
701 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
702 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
703 WINED3D_GL_EXT_NONE, NULL},
704 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
705 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
706 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
707 WINED3D_GL_EXT_NONE, NULL},
708 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
709 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
710 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
711 WINED3D_GL_EXT_NONE, NULL},
712 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
713 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
714 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
715 WINED3D_GL_EXT_NONE, NULL},
716 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
717 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
718 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
719 WINED3D_GL_EXT_NONE, NULL},
720 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
721 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
722 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
723 WINED3D_GL_EXT_NONE, NULL},
724 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
725 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
726 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
727 WINED3D_GL_EXT_NONE, NULL},
728 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
729 GL_RGB, GL_UNSIGNED_SHORT, 6,
730 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
731 WINED3D_GL_EXT_NONE, convert_r16g16},
732 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
733 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
734 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
735 WINED3D_GL_EXT_NONE, NULL},
736 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
737 GL_RGBA, GL_UNSIGNED_SHORT, 0,
738 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
739 WINED3D_GL_EXT_NONE, NULL},
741 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
742 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
743 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
744 WINED3D_GL_EXT_NONE, NULL},
745 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
746 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
747 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
748 WINED3D_GL_EXT_NONE, NULL},
749 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
750 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
751 WINED3DFMT_FLAG_FILTERING,
752 WINED3D_GL_EXT_NONE, convert_l4a4_unorm},
753 /* Bump mapping stuff */
754 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
755 GL_BGR, GL_UNSIGNED_BYTE, 3,
756 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
757 WINED3D_GL_EXT_NONE, convert_r8g8_snorm},
758 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
759 GL_DSDT_NV, GL_BYTE, 0,
760 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
761 NV_TEXTURE_SHADER, NULL},
762 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
763 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
764 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
765 WINED3D_GL_EXT_NONE, convert_r5g5_snorm_l6_unorm},
766 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
767 GL_DSDT_MAG_NV, GL_BYTE, 3,
768 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
769 NV_TEXTURE_SHADER, convert_r5g5_snorm_l6_unorm_nv},
770 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
771 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
772 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
773 WINED3D_GL_EXT_NONE, convert_r8g8_snorm_l8x8_unorm},
774 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
775 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
776 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
777 NV_TEXTURE_SHADER, convert_r8g8_snorm_l8x8_unorm_nv},
778 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
779 GL_BGRA, GL_UNSIGNED_BYTE, 4,
780 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
781 WINED3D_GL_EXT_NONE, convert_r8g8b8a8_snorm},
782 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
784 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
785 NV_TEXTURE_SHADER, NULL},
786 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
787 GL_BGR, GL_UNSIGNED_SHORT, 6,
788 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
789 WINED3D_GL_EXT_NONE, convert_r16g16_snorm},
790 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
791 GL_HILO_NV, GL_SHORT, 0,
792 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
793 NV_TEXTURE_SHADER, NULL},
794 /* Depth stencil formats */
795 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
796 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
797 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
798 ARB_DEPTH_TEXTURE, NULL},
799 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
800 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
801 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
802 ARB_DEPTH_TEXTURE, NULL},
803 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
804 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
805 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
806 ARB_DEPTH_TEXTURE, NULL},
807 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
808 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
809 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
810 EXT_PACKED_DEPTH_STENCIL, convert_s1_uint_d15_unorm},
811 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
812 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
813 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
814 ARB_FRAMEBUFFER_OBJECT, convert_s1_uint_d15_unorm},
815 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
816 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
817 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
818 | WINED3DFMT_FLAG_SHADOW,
819 ARB_DEPTH_TEXTURE, NULL},
820 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
821 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
822 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
823 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
824 EXT_PACKED_DEPTH_STENCIL, NULL},
825 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
826 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
827 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
828 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
829 ARB_FRAMEBUFFER_OBJECT, NULL},
830 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
831 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
832 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
833 | WINED3DFMT_FLAG_SHADOW,
834 ARB_DEPTH_TEXTURE, NULL},
835 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
836 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
837 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
838 ARB_DEPTH_TEXTURE, NULL},
839 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
840 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
841 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
842 EXT_PACKED_DEPTH_STENCIL, convert_s4x4_uint_d24_unorm},
843 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
844 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
845 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
846 ARB_FRAMEBUFFER_OBJECT, convert_s4x4_uint_d24_unorm},
847 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
848 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
849 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
850 | WINED3DFMT_FLAG_SHADOW,
851 ARB_DEPTH_TEXTURE, NULL},
852 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
853 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
854 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
855 WINED3D_GL_EXT_NONE, NULL},
856 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
857 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
858 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
859 ARB_DEPTH_BUFFER_FLOAT, NULL},
860 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
861 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
862 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
863 ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float},
864 /* Vendor-specific formats */
865 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
866 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
867 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_COMPRESSED,
868 ATI_TEXTURE_COMPRESSION_3DC, NULL},
869 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2, GL_COMPRESSED_RED_GREEN_RGTC2, 0,
870 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
871 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_COMPRESSED,
872 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
873 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
874 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
875 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
876 | WINED3DFMT_FLAG_STENCIL,
877 EXT_PACKED_DEPTH_STENCIL, NULL},
878 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
879 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
880 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
881 | WINED3DFMT_FLAG_STENCIL,
882 ARB_FRAMEBUFFER_OBJECT, NULL},
883 {WINED3DFMT_NULL, GL_RGBA8, GL_RGBA8, 0,
884 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
885 WINED3DFMT_FLAG_RENDERTARGET,
886 ARB_FRAMEBUFFER_OBJECT, NULL},
889 static inline int getFmtIdx(enum wined3d_format_id format_id)
891 /* First check if the format is at the position of its value.
892 * This will catch the argb formats before the loop is entered. */
893 if (format_id < (sizeof(formats) / sizeof(*formats))
894 && formats[format_id].id == format_id)
902 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
904 if (formats[i].id == format_id) return i;
910 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
912 UINT format_count = sizeof(formats) / sizeof(*formats);
915 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
916 if (!gl_info->formats)
918 ERR("Failed to allocate memory.\n");
922 for (i = 0; i < format_count; ++i)
924 struct wined3d_format *format = &gl_info->formats[i];
925 format->id = formats[i].id;
926 format->red_mask = formats[i].redMask;
927 format->green_mask = formats[i].greenMask;
928 format->blue_mask = formats[i].blueMask;
929 format->alpha_mask = formats[i].alphaMask;
930 format->byte_count = formats[i].bpp;
931 format->depth_size = formats[i].depthSize;
932 format->stencil_size = formats[i].stencilSize;
933 format->block_width = 1;
934 format->block_height = 1;
935 format->block_byte_count = formats[i].bpp;
938 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
940 int fmt_idx = getFmtIdx(format_base_flags[i].id);
944 ERR("Format %s (%#x) not found.\n",
945 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
946 HeapFree(GetProcessHeap(), 0, gl_info->formats);
950 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
956 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
960 for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i)
962 struct wined3d_format *format;
963 int fmt_idx = getFmtIdx(format_block_info[i].id);
967 ERR("Format %s (%#x) not found.\n",
968 debug_d3dformat(format_block_info[i].id), format_block_info[i].id);
972 format = &gl_info->formats[fmt_idx];
973 format->block_width = format_block_info[i].block_width;
974 format->block_height = format_block_info[i].block_height;
975 format->block_byte_count = format_block_info[i].block_byte_count;
976 format->flags |= WINED3DFMT_FLAG_BLOCKS;
982 /* Context activation is done by the caller. */
983 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
985 /* Check if the default internal format is supported as a frame buffer
986 * target, otherwise fall back to the render target internal.
988 * Try to stick to the standard format if possible, this limits precision differences. */
997 glGenTextures(1, &tex);
998 glBindTexture(GL_TEXTURE_2D, tex);
1000 glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1001 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1002 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1004 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1006 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1007 checkGLcall("Framebuffer format check");
1009 if (status == GL_FRAMEBUFFER_COMPLETE)
1011 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1012 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1013 format->rtInternal = format->glInternal;
1017 if (!format->rtInternal)
1019 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1021 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1022 " and no fallback specified.\n", debug_d3dformat(format->id));
1023 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1027 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1029 format->rtInternal = format->glInternal;
1033 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1034 debug_d3dformat(format->id));
1036 while(glGetError());
1038 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1040 glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1041 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1042 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1044 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1046 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1047 checkGLcall("Framebuffer format check");
1049 if (status == GL_FRAMEBUFFER_COMPLETE)
1051 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1052 debug_d3dformat(format->id));
1056 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1057 debug_d3dformat(format->id));
1058 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1063 if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1064 || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING)))
1067 DWORD readback[16 * 16], color;
1071 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1072 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1074 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1075 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1076 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1077 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1078 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1079 checkGLcall("RB attachment");
1083 glClearColor(0, 0, 0, 1);
1084 glClear(GL_COLOR_BUFFER_BIT);
1085 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1087 while(glGetError());
1088 TRACE("Format doesn't support post-pixelshader blending.\n");
1089 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1092 glViewport(0, 0, 16, 16);
1093 glDisable(GL_LIGHTING);
1094 glMatrixMode(GL_MODELVIEW);
1096 glMatrixMode(GL_PROJECTION);
1099 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1101 /* Draw a full-black quad */
1102 glBegin(GL_TRIANGLE_STRIP);
1103 glColor4ub(0x00, 0x00, 0x00, 0xff);
1104 glVertex3f(-1.0f, -1.0f, 0.0f);
1105 glColor4ub(0x00, 0x00, 0x00, 0xff);
1106 glVertex3f(1.0f, -1.0f, 0.0f);
1107 glColor4ub(0x00, 0x00, 0x00, 0xff);
1108 glVertex3f(-1.0f, 1.0f, 0.0f);
1109 glColor4ub(0x00, 0x00, 0x00, 0xff);
1110 glVertex3f(1.0f, 1.0f, 0.0f);
1113 /* Draw a half-transparent red quad */
1114 glBegin(GL_TRIANGLE_STRIP);
1115 glColor4ub(0xff, 0x00, 0x00, 0x80);
1116 glVertex3f(-1.0f, -1.0f, 0.0f);
1117 glColor4ub(0xff, 0x00, 0x00, 0x80);
1118 glVertex3f(1.0f, -1.0f, 0.0f);
1119 glColor4ub(0xff, 0x00, 0x00, 0x80);
1120 glVertex3f(-1.0f, 1.0f, 0.0f);
1121 glColor4ub(0xff, 0x00, 0x00, 0x80);
1122 glVertex3f(1.0f, 1.0f, 0.0f);
1125 glGenTextures(1, &tex2);
1126 glBindTexture(GL_TEXTURE_2D, tex2);
1128 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, 16, 16, 0);
1129 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1130 checkGLcall("Post-pixelshader blending check");
1132 color = readback[7 * 16 + 7];
1134 r = (color & 0x00ff0000) >> 16;
1136 if (format->red_mask && (r < 0x7b || r > 0x84))
1138 /* If the alpha component is more than 1 bit */
1139 else if ((format->alpha_mask & (format->alpha_mask - 1)) && (a < 0x9f || a > 0xdf))
1143 TRACE("Format doesn't support post-pixelshader blending.\n");
1144 TRACE("Color output: %#x\n", color);
1145 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1148 glBindTexture(GL_TEXTURE_2D, tex);
1149 glDeleteTextures(1, &tex2);
1151 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1152 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1154 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1155 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1156 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1157 checkGLcall("RB cleanup");
1161 if (format->glInternal != format->glGammaInternal)
1163 glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1164 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1166 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1167 checkGLcall("Framebuffer format check");
1169 if (status == GL_FRAMEBUFFER_COMPLETE)
1171 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1172 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1176 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1179 else if (status == GL_FRAMEBUFFER_COMPLETE)
1180 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1182 glDeleteTextures(1, &tex);
1187 /* Context activation is done by the caller. */
1188 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1193 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1197 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1198 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1199 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1200 glReadBuffer(GL_COLOR_ATTACHMENT0);
1205 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1207 struct wined3d_format *format = &gl_info->formats[i];
1209 if (!format->glInternal) continue;
1211 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1213 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1214 debug_d3dformat(format->id));
1218 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1220 TRACE("Skipping format %s because it's a compressed format.\n",
1221 debug_d3dformat(format->id));
1225 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1227 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1228 check_fbo_compat(gl_info, format);
1232 format->rtInternal = format->glInternal;
1236 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1240 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1246 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1250 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1252 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1253 struct wined3d_format *format;
1257 ERR("Format %s (%#x) not found.\n",
1258 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1262 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1264 format = &gl_info->formats[fmt_idx];
1266 /* ARB_texture_rg defines floating point formats, but only if
1267 * ARB_texture_float is also supported. */
1268 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1269 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1272 format->glInternal = format_texture_info[i].gl_internal;
1273 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1274 format->rtInternal = format_texture_info[i].gl_rt_internal;
1275 format->glFormat = format_texture_info[i].gl_format;
1276 format->glType = format_texture_info[i].gl_type;
1277 format->color_fixup = COLOR_FIXUP_IDENTITY;
1278 format->flags |= format_texture_info[i].flags;
1279 format->heightscale = 1.0f;
1281 if (format->glGammaInternal != format->glInternal)
1283 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1284 if (!gl_info->supported[EXT_TEXTURE_SRGB])
1286 format->glGammaInternal = format->glInternal;
1287 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1289 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1291 format->glInternal = format->glGammaInternal;
1295 /* Texture conversion stuff */
1296 format->convert = format_texture_info[i].convert;
1297 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1303 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1305 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1307 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1309 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1311 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1315 /* A context is provided by the caller */
1316 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1318 static const DWORD data[] = {0x00000000, 0xffffffff};
1319 GLuint tex, fbo, buffer;
1320 DWORD readback[16 * 1];
1323 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1324 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1325 * falling back to software. If this changes in the future this code will get fooled and
1326 * apps might hit the software path due to incorrectly advertised caps.
1328 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1329 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1330 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1334 while(glGetError());
1336 glGenTextures(1, &buffer);
1337 glBindTexture(GL_TEXTURE_2D, buffer);
1338 memset(readback, 0x7e, sizeof(readback));
1339 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1340 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1341 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1342 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1343 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1344 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1346 glGenTextures(1, &tex);
1347 glBindTexture(GL_TEXTURE_2D, tex);
1348 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1349 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1350 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1351 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1352 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1353 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1354 glEnable(GL_TEXTURE_2D);
1356 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1357 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1358 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1359 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1361 glViewport(0, 0, 16, 1);
1362 glDisable(GL_LIGHTING);
1363 glMatrixMode(GL_MODELVIEW);
1365 glMatrixMode(GL_PROJECTION);
1368 glClearColor(0, 1, 0, 0);
1369 glClear(GL_COLOR_BUFFER_BIT);
1371 glBegin(GL_TRIANGLE_STRIP);
1372 glTexCoord2f(0.0, 0.0);
1373 glVertex2f(-1.0f, -1.0f);
1374 glTexCoord2f(1.0, 0.0);
1375 glVertex2f(1.0f, -1.0f);
1376 glTexCoord2f(0.0, 1.0);
1377 glVertex2f(-1.0f, 1.0f);
1378 glTexCoord2f(1.0, 1.0);
1379 glVertex2f(1.0f, 1.0f);
1382 glBindTexture(GL_TEXTURE_2D, buffer);
1383 memset(readback, 0x7f, sizeof(readback));
1384 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1385 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1386 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1388 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1389 readback[6], readback[9]);
1394 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1395 readback[6], readback[9]);
1399 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1400 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1401 glDeleteTextures(1, &tex);
1402 glDeleteTextures(1, &buffer);
1406 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1413 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1415 struct wined3d_format *format;
1416 unsigned int fmt_idx, i;
1417 static const enum wined3d_format_id fmts16[] =
1419 WINED3DFMT_R16_FLOAT,
1420 WINED3DFMT_R16G16_FLOAT,
1421 WINED3DFMT_R16G16B16A16_FLOAT,
1425 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1427 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1428 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1430 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1433 else if (gl_info->limits.glsl_varyings > 44)
1435 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1440 TRACE("Assuming no float16 blending\n");
1446 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1448 fmt_idx = getFmtIdx(fmts16[i]);
1449 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1455 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1457 fmt_idx = getFmtIdx(fmts16[i]);
1458 format = &gl_info->formats[fmt_idx];
1459 if (!format->glInternal) continue; /* Not supported by GL */
1461 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1464 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1465 format->flags |= WINED3DFMT_FLAG_FILTERING;
1469 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1474 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1478 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1479 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1480 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1482 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1483 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1484 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1486 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1487 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1488 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1490 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1491 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1492 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1494 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1495 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1496 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1498 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1499 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1500 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1501 * the only driver that implements it(fglrx) has a buggy implementation.
1503 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1504 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1505 * conversion for this format.
1507 if (!gl_info->supported[NV_TEXTURE_SHADER])
1509 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1510 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1511 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1512 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1513 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1514 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1518 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1519 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1520 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1522 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1523 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1524 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1527 if (!gl_info->supported[NV_TEXTURE_SHADER])
1529 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1532 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1533 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1534 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1535 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1536 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1537 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1538 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1539 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1540 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1544 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1545 * are converted at surface loading time, but they do not need any modification in
1546 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1547 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1551 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1553 idx = getFmtIdx(WINED3DFMT_ATI2N);
1554 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1555 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1557 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1559 idx = getFmtIdx(WINED3DFMT_ATI2N);
1560 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1561 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1564 if (!gl_info->supported[APPLE_YCBCR_422])
1566 idx = getFmtIdx(WINED3DFMT_YUY2);
1567 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1569 idx = getFmtIdx(WINED3DFMT_UYVY);
1570 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1573 idx = getFmtIdx(WINED3DFMT_YV12);
1574 gl_info->formats[idx].heightscale = 1.5f;
1575 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1577 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1579 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1580 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1583 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1585 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1586 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1589 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1591 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1592 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1593 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1594 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1596 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1597 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1601 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1605 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1607 struct wined3d_format *format;
1608 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1612 ERR("Format %s (%#x) not found.\n",
1613 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1617 format = &gl_info->formats[fmt_idx];
1618 format->emit_idx = format_vertex_info[i].emit_idx;
1619 format->component_count = format_vertex_info[i].component_count;
1620 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1621 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1622 format->gl_normalized = format_vertex_info[i].gl_normalized;
1623 format->component_size = format_vertex_info[i].component_size;
1629 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1631 if (!init_format_base_info(gl_info)) return FALSE;
1633 if (!init_format_block_info(gl_info))
1635 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1636 gl_info->formats = NULL;
1643 /* Context activation is done by the caller. */
1644 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1646 if (!init_format_base_info(gl_info)) return FALSE;
1648 if (!init_format_block_info(gl_info)) goto fail;
1649 if (!init_format_texture_info(gl_info)) goto fail;
1650 if (!init_format_vertex_info(gl_info)) goto fail;
1652 apply_format_fixups(gl_info);
1653 init_format_fbo_compat_info(gl_info);
1654 init_format_filter_info(gl_info, vendor);
1659 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1660 gl_info->formats = NULL;
1664 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1665 enum wined3d_format_id format_id)
1667 int idx = getFmtIdx(format_id);
1671 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1672 debug_d3dformat(format_id), format_id);
1673 /* Get the caller a valid pointer */
1674 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1677 return &gl_info->formats[idx];
1680 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1684 if (format->id == WINED3DFMT_UNKNOWN)
1688 else if (format->flags & WINED3DFMT_FLAG_BLOCKS)
1690 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1691 UINT row_count = (height + format->block_height - 1) / format->block_height;
1692 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1696 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1699 if (format->heightscale != 0.0f)
1701 /* The D3D format requirements make sure that the resulting format is an integer again */
1702 size = (UINT) (size * format->heightscale);
1708 /*****************************************************************************
1709 * Trace formatting of useful values
1711 const char *debug_d3dformat(enum wined3d_format_id format_id)
1715 #define FMT_TO_STR(format_id) case format_id: return #format_id
1716 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1717 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1718 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1719 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1720 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1721 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1722 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1723 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1724 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1725 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1726 FMT_TO_STR(WINED3DFMT_P8_UINT);
1727 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1728 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1729 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1730 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1731 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1732 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1733 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1734 FMT_TO_STR(WINED3DFMT_UYVY);
1735 FMT_TO_STR(WINED3DFMT_YUY2);
1736 FMT_TO_STR(WINED3DFMT_YV12);
1737 FMT_TO_STR(WINED3DFMT_DXT1);
1738 FMT_TO_STR(WINED3DFMT_DXT2);
1739 FMT_TO_STR(WINED3DFMT_DXT3);
1740 FMT_TO_STR(WINED3DFMT_DXT4);
1741 FMT_TO_STR(WINED3DFMT_DXT5);
1742 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1743 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1744 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1745 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1746 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1747 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1748 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1749 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1750 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1751 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1752 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1753 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1754 FMT_TO_STR(WINED3DFMT_ATI2N);
1755 FMT_TO_STR(WINED3DFMT_NVDB);
1756 FMT_TO_STR(WINED3DFMT_NVHU);
1757 FMT_TO_STR(WINED3DFMT_NVHS);
1758 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1759 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1760 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1761 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1762 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1763 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1764 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1765 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1766 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1767 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1768 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1769 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1770 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1771 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1772 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1773 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1774 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1775 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1776 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1777 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1778 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1779 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1780 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1781 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1782 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1783 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1784 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1785 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1786 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1787 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1788 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1789 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1790 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1791 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1792 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1793 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1794 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1795 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1796 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1797 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1798 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1799 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1800 FMT_TO_STR(WINED3DFMT_R32_UINT);
1801 FMT_TO_STR(WINED3DFMT_R32_SINT);
1802 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1803 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1804 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1805 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1806 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1807 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1808 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1809 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1810 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1811 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1812 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1813 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1814 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1815 FMT_TO_STR(WINED3DFMT_R16_UINT);
1816 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1817 FMT_TO_STR(WINED3DFMT_R16_SINT);
1818 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1819 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1820 FMT_TO_STR(WINED3DFMT_R8_UINT);
1821 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1822 FMT_TO_STR(WINED3DFMT_R8_SINT);
1823 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1824 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1825 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1826 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1827 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1828 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1829 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1830 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1831 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1832 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1833 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1834 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1835 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1836 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1837 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1838 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1839 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1840 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1841 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1842 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1843 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1844 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1845 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1846 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1847 FMT_TO_STR(WINED3DFMT_INTZ);
1848 FMT_TO_STR(WINED3DFMT_NULL);
1849 FMT_TO_STR(WINED3DFMT_R16);
1850 FMT_TO_STR(WINED3DFMT_AL16);
1855 fourcc[0] = (char)(format_id);
1856 fourcc[1] = (char)(format_id >> 8);
1857 fourcc[2] = (char)(format_id >> 16);
1858 fourcc[3] = (char)(format_id >> 24);
1860 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1861 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1863 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1865 return "unrecognized";
1869 const char *debug_d3ddevicetype(WINED3DDEVTYPE devtype)
1873 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1874 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1875 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1876 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1877 #undef DEVTYPE_TO_STR
1879 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1880 return "unrecognized";
1884 const char *debug_d3dusage(DWORD usage)
1889 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1890 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1891 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1892 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1893 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1894 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1895 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1896 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1897 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1898 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1899 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1900 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1901 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1902 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1903 #undef WINED3DUSAGE_TO_STR
1904 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1906 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1909 const char *debug_d3dusagequery(DWORD usagequery)
1914 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1915 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1916 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1917 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1918 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1919 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1920 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1921 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1922 #undef WINED3DUSAGEQUERY_TO_STR
1923 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1925 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1928 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1930 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1931 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1932 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1933 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1934 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1935 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1936 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1937 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1938 #undef WINED3DDECLMETHOD_TO_STR
1940 FIXME("Unrecognized %u declaration method!\n", method);
1941 return "unrecognized";
1945 const char* debug_d3ddeclusage(BYTE usage) {
1947 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1948 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1949 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1950 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1951 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1952 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1953 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1954 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1955 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1956 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1957 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1958 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1959 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1960 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1961 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1962 #undef WINED3DDECLUSAGE_TO_STR
1964 FIXME("Unrecognized %u declaration usage!\n", usage);
1965 return "unrecognized";
1969 const char *debug_d3dresourcetype(WINED3DRESOURCETYPE res)
1973 #define RES_TO_STR(res) case res: return #res
1974 RES_TO_STR(WINED3DRTYPE_SURFACE);
1975 RES_TO_STR(WINED3DRTYPE_VOLUME);
1976 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1977 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1978 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1979 RES_TO_STR(WINED3DRTYPE_BUFFER);
1982 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1983 return "unrecognized";
1987 const char *debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType)
1989 switch (PrimitiveType)
1991 #define PRIM_TO_STR(prim) case prim: return #prim
1992 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1993 PRIM_TO_STR(WINED3DPT_POINTLIST);
1994 PRIM_TO_STR(WINED3DPT_LINELIST);
1995 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1996 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1997 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1998 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1999 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
2000 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
2001 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
2002 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
2005 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
2006 return "unrecognized";
2010 const char *debug_d3drenderstate(WINED3DRENDERSTATETYPE state)
2014 #define D3DSTATE_TO_STR(u) case u: return #u
2015 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS);
2016 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE);
2017 D3DSTATE_TO_STR(WINED3DRS_WRAPU);
2018 D3DSTATE_TO_STR(WINED3DRS_WRAPV);
2019 D3DSTATE_TO_STR(WINED3DRS_ZENABLE);
2020 D3DSTATE_TO_STR(WINED3DRS_FILLMODE);
2021 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE);
2022 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN);
2023 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE);
2024 D3DSTATE_TO_STR(WINED3DRS_ROP2);
2025 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK);
2026 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE);
2027 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE);
2028 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL);
2029 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND);
2030 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND);
2031 D3DSTATE_TO_STR(WINED3DRS_CULLMODE);
2032 D3DSTATE_TO_STR(WINED3DRS_ZFUNC);
2033 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF);
2034 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC);
2035 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE);
2036 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE);
2037 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE);
2038 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE);
2039 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE);
2040 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL);
2041 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX);
2042 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA);
2043 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR);
2044 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE);
2045 D3DSTATE_TO_STR(WINED3DRS_FOGSTART);
2046 D3DSTATE_TO_STR(WINED3DRS_FOGEND);
2047 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY);
2048 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE);
2049 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS);
2050 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE);
2051 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS);
2052 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE);
2053 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY);
2054 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH);
2055 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
2056 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE);
2057 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL);
2058 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL);
2059 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS);
2060 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC);
2061 D3DSTATE_TO_STR(WINED3DRS_STENCILREF);
2062 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK);
2063 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK);
2064 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR);
2065 D3DSTATE_TO_STR(WINED3DRS_WRAP0);
2066 D3DSTATE_TO_STR(WINED3DRS_WRAP1);
2067 D3DSTATE_TO_STR(WINED3DRS_WRAP2);
2068 D3DSTATE_TO_STR(WINED3DRS_WRAP3);
2069 D3DSTATE_TO_STR(WINED3DRS_WRAP4);
2070 D3DSTATE_TO_STR(WINED3DRS_WRAP5);
2071 D3DSTATE_TO_STR(WINED3DRS_WRAP6);
2072 D3DSTATE_TO_STR(WINED3DRS_WRAP7);
2073 D3DSTATE_TO_STR(WINED3DRS_CLIPPING);
2074 D3DSTATE_TO_STR(WINED3DRS_LIGHTING);
2075 D3DSTATE_TO_STR(WINED3DRS_EXTENTS);
2076 D3DSTATE_TO_STR(WINED3DRS_AMBIENT);
2077 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE);
2078 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX);
2079 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER);
2080 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS);
2081 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE);
2082 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE);
2083 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE);
2084 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE);
2085 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE);
2086 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND);
2087 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE);
2088 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING);
2089 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE);
2090 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN);
2091 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE);
2092 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE);
2093 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A);
2094 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B);
2095 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C);
2096 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS);
2097 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK);
2098 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE);
2099 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS);
2100 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN);
2101 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX);
2102 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE);
2103 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE);
2104 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR);
2105 D3DSTATE_TO_STR(WINED3DRS_BLENDOP);
2106 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE);
2107 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE);
2108 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE);
2109 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS);
2110 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE);
2111 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL);
2112 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL);
2113 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X);
2114 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y);
2115 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z);
2116 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W);
2117 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
2118 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE);
2119 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL);
2120 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL);
2121 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS);
2122 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC);
2123 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1);
2124 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2);
2125 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3);
2126 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR);
2127 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE);
2128 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS);
2129 D3DSTATE_TO_STR(WINED3DRS_WRAP8);
2130 D3DSTATE_TO_STR(WINED3DRS_WRAP9);
2131 D3DSTATE_TO_STR(WINED3DRS_WRAP10);
2132 D3DSTATE_TO_STR(WINED3DRS_WRAP11);
2133 D3DSTATE_TO_STR(WINED3DRS_WRAP12);
2134 D3DSTATE_TO_STR(WINED3DRS_WRAP13);
2135 D3DSTATE_TO_STR(WINED3DRS_WRAP14);
2136 D3DSTATE_TO_STR(WINED3DRS_WRAP15);
2137 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE);
2138 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA);
2139 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA);
2140 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA);
2141 #undef D3DSTATE_TO_STR
2143 FIXME("Unrecognized %u render state!\n", state);
2144 return "unrecognized";
2148 const char *debug_d3dsamplerstate(DWORD state)
2152 #define D3DSTATE_TO_STR(u) case u: return #u
2153 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR);
2154 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU);
2155 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV);
2156 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW);
2157 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER);
2158 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER);
2159 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER);
2160 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
2161 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL);
2162 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
2163 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE);
2164 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX);
2165 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET);
2166 #undef D3DSTATE_TO_STR
2168 FIXME("Unrecognized %u sampler state!\n", state);
2169 return "unrecognized";
2173 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2174 switch (filter_type) {
2175 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2176 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2177 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2178 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2179 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2180 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2181 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2182 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2183 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2184 #undef D3DTEXTUREFILTERTYPE_TO_STR
2186 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2187 return "unrecognized";
2191 const char *debug_d3dtexturestate(DWORD state)
2195 #define D3DSTATE_TO_STR(u) case u: return #u
2196 D3DSTATE_TO_STR(WINED3DTSS_COLOROP);
2197 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1);
2198 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2);
2199 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP);
2200 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1);
2201 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2);
2202 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00);
2203 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01);
2204 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10);
2205 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11);
2206 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX);
2207 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE);
2208 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET);
2209 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS);
2210 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0);
2211 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0);
2212 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG);
2213 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT);
2214 #undef D3DSTATE_TO_STR
2216 FIXME("Unrecognized %u texture state!\n", state);
2217 return "unrecognized";
2221 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2223 #define D3DTOP_TO_STR(u) case u: return #u
2224 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2225 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2226 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2227 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2228 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2229 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2230 D3DTOP_TO_STR(WINED3DTOP_ADD);
2231 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2232 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2233 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2234 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2235 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2236 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2237 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2238 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2239 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2240 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2241 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2242 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2243 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2244 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2245 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2246 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2247 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2248 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2249 D3DTOP_TO_STR(WINED3DTOP_LERP);
2250 #undef D3DTOP_TO_STR
2252 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2253 return "unrecognized";
2257 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2259 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2260 TSTYPE_TO_STR(WINED3DTS_VIEW);
2261 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2262 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2263 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2264 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2265 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2266 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2267 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2268 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2269 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2270 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2271 #undef TSTYPE_TO_STR
2273 if (tstype > 256 && tstype < 512) {
2274 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2275 return ("WINED3DTS_WORLDMATRIX > 0");
2277 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2278 return "unrecognized";
2282 const char *debug_d3dstate(DWORD state)
2284 if (STATE_IS_RENDER(state))
2285 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2286 if (STATE_IS_TEXTURESTAGE(state))
2288 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2289 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2290 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2291 texture_stage, debug_d3dtexturestate(texture_state));
2293 if (STATE_IS_SAMPLER(state))
2294 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2295 if (STATE_IS_PIXELSHADER(state))
2296 return "STATE_PIXELSHADER";
2297 if (STATE_IS_TRANSFORM(state))
2298 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2299 if (STATE_IS_STREAMSRC(state))
2300 return "STATE_STREAMSRC";
2301 if (STATE_IS_INDEXBUFFER(state))
2302 return "STATE_INDEXBUFFER";
2303 if (STATE_IS_VDECL(state))
2304 return "STATE_VDECL";
2305 if (STATE_IS_VSHADER(state))
2306 return "STATE_VSHADER";
2307 if (STATE_IS_VIEWPORT(state))
2308 return "STATE_VIEWPORT";
2309 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2310 return "STATE_VERTEXSHADERCONSTANT";
2311 if (STATE_IS_PIXELSHADERCONSTANT(state))
2312 return "STATE_PIXELSHADERCONSTANT";
2313 if (STATE_IS_ACTIVELIGHT(state))
2314 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2315 if (STATE_IS_SCISSORRECT(state))
2316 return "STATE_SCISSORRECT";
2317 if (STATE_IS_CLIPPLANE(state))
2318 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2319 if (STATE_IS_MATERIAL(state))
2320 return "STATE_MATERIAL";
2321 if (STATE_IS_FRONTFACE(state))
2322 return "STATE_FRONTFACE";
2323 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2324 return "STATE_POINTSPRITECOORDORIGIN";
2325 if (STATE_IS_BASEVERTEXINDEX(state))
2326 return "STATE_BASEVERTEXINDEX";
2327 if (STATE_IS_FRAMEBUFFER(state))
2328 return "STATE_FRAMEBUFFER";
2330 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2333 const char *debug_d3dpool(WINED3DPOOL pool)
2337 #define POOL_TO_STR(p) case p: return #p
2338 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2339 POOL_TO_STR(WINED3DPOOL_MANAGED);
2340 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2341 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2344 FIXME("Unrecognized %u WINED3DPOOL!\n", pool);
2345 return "unrecognized";
2349 const char *debug_fbostatus(GLenum status) {
2351 #define FBOSTATUS_TO_STR(u) case u: return #u
2352 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2353 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2354 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2355 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2356 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2357 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2358 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2359 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2360 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2361 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2362 #undef FBOSTATUS_TO_STR
2364 FIXME("Unrecognied FBO status 0x%08x\n", status);
2365 return "unrecognized";
2369 const char *debug_glerror(GLenum error) {
2371 #define GLERROR_TO_STR(u) case u: return #u
2372 GLERROR_TO_STR(GL_NO_ERROR);
2373 GLERROR_TO_STR(GL_INVALID_ENUM);
2374 GLERROR_TO_STR(GL_INVALID_VALUE);
2375 GLERROR_TO_STR(GL_INVALID_OPERATION);
2376 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2377 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2378 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2379 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2380 #undef GLERROR_TO_STR
2382 FIXME("Unrecognied GL error 0x%08x\n", error);
2383 return "unrecognized";
2387 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2389 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2390 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2391 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2392 default: return "unrecognized";
2396 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2398 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2399 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2400 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2401 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2402 default: return "unrecognized";
2406 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2410 #define WINED3D_TO_STR(x) case x: return #x
2411 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2412 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2413 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2414 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2415 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2416 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2417 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2418 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2419 #undef WINED3D_TO_STR
2421 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2422 return "unrecognized";
2426 static const char *debug_complex_fixup(enum complex_fixup fixup)
2430 #define WINED3D_TO_STR(x) case x: return #x
2431 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2432 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2433 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2434 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2435 #undef WINED3D_TO_STR
2437 FIXME("Unrecognized complex fixup %#x\n", fixup);
2438 return "unrecognized";
2442 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2444 if (is_complex_fixup(fixup))
2446 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2450 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2451 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2452 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2453 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2456 const char *debug_surflocation(DWORD flag) {
2460 if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM"); /* 17 */
2461 if (flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE"); /* 19 */
2462 if (flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE"); /* 18 */
2463 if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX"); /* 18 */
2464 if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE"); /* 25 */
2465 if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED"); /* 22 */
2466 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2469 /*****************************************************************************
2470 * Useful functions mapping GL <-> D3D values
2472 GLenum StencilOp(DWORD op) {
2474 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2475 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2476 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2477 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2478 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2479 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2480 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2481 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2483 FIXME("Unrecognized stencil op %d\n", op);
2488 GLenum CompareFunc(DWORD func) {
2489 switch ((WINED3DCMPFUNC)func) {
2490 case WINED3DCMP_NEVER : return GL_NEVER;
2491 case WINED3DCMP_LESS : return GL_LESS;
2492 case WINED3DCMP_EQUAL : return GL_EQUAL;
2493 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2494 case WINED3DCMP_GREATER : return GL_GREATER;
2495 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2496 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2497 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2499 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2504 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2505 WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
2507 if (op == WINED3DTOP_DISABLE) return FALSE;
2508 if (state->textures[stage]) return FALSE;
2510 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2511 && op != WINED3DTOP_SELECTARG2) return TRUE;
2512 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2513 && op != WINED3DTOP_SELECTARG1) return TRUE;
2514 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2515 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2520 /* Setup this textures matrix according to the texture flags*/
2521 /* GL locking is done by the caller (state handler) */
2522 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2523 enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2527 glMatrixMode(GL_TEXTURE);
2528 checkGLcall("glMatrixMode(GL_TEXTURE)");
2530 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2532 checkGLcall("glLoadIdentity()");
2536 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2537 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2541 memcpy(mat, smat, 16 * sizeof(float));
2543 if (flags & WINED3DTTFF_PROJECTED) {
2544 if(!ffp_proj_control) {
2545 switch (flags & ~WINED3DTTFF_PROJECTED) {
2546 case WINED3DTTFF_COUNT2:
2547 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2548 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2550 case WINED3DTTFF_COUNT3:
2551 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2552 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2556 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2557 if(!calculatedCoords) {
2560 case WINED3DFMT_R32_FLOAT:
2561 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2562 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2563 * the input value to the transformation will be 0, so the matrix value is irrelevant
2570 case WINED3DFMT_R32G32_FLOAT:
2571 /* See above, just 3rd and 4th coord
2578 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2579 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2581 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2582 * into a bad place. The division elimination below will apply to make sure the
2583 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2585 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2588 FIXME("Unexpected fixed function texture coord input\n");
2591 if(!ffp_proj_control) {
2592 switch (flags & ~WINED3DTTFF_PROJECTED) {
2593 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2594 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2595 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2596 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2597 * the 4th coord evaluates to 1.0 to eliminate that.
2599 * If the fixed function pipeline is used, the 4th value remains unused,
2600 * so there is no danger in doing this. With vertex shaders we have a
2601 * problem. Should an app hit that problem, the code here would have to
2602 * check for pixel shaders, and the shader has to undo the default gl divide.
2604 * A more serious problem occurs if the app passes 4 coordinates in, and the
2605 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2606 * or a replacement shader
2608 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2614 checkGLcall("glLoadMatrixf(mat)");
2617 /* This small helper function is used to convert a bitmask into the number of masked bits */
2618 unsigned int count_bits(unsigned int mask)
2621 for (count = 0; mask; ++count)
2628 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2629 * The later function requires individual color components. */
2630 BOOL getColorBits(const struct wined3d_format *format,
2631 BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2633 TRACE("format %s.\n", debug_d3dformat(format->id));
2637 case WINED3DFMT_B10G10R10A2_UNORM:
2638 case WINED3DFMT_R10G10B10A2_UNORM:
2639 case WINED3DFMT_B8G8R8X8_UNORM:
2640 case WINED3DFMT_B8G8R8_UNORM:
2641 case WINED3DFMT_B8G8R8A8_UNORM:
2642 case WINED3DFMT_R8G8B8A8_UNORM:
2643 case WINED3DFMT_B5G5R5X1_UNORM:
2644 case WINED3DFMT_B5G5R5A1_UNORM:
2645 case WINED3DFMT_B5G6R5_UNORM:
2646 case WINED3DFMT_B4G4R4X4_UNORM:
2647 case WINED3DFMT_B4G4R4A4_UNORM:
2648 case WINED3DFMT_B2G3R3_UNORM:
2649 case WINED3DFMT_P8_UINT_A8_UNORM:
2650 case WINED3DFMT_P8_UINT:
2653 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2657 *redSize = count_bits(format->red_mask);
2658 *greenSize = count_bits(format->green_mask);
2659 *blueSize = count_bits(format->blue_mask);
2660 *alphaSize = count_bits(format->alpha_mask);
2661 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2663 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2664 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2668 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2669 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
2671 TRACE("format %s.\n", debug_d3dformat(format->id));
2675 case WINED3DFMT_D16_LOCKABLE:
2676 case WINED3DFMT_D16_UNORM:
2677 case WINED3DFMT_S1_UINT_D15_UNORM:
2678 case WINED3DFMT_X8D24_UNORM:
2679 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2680 case WINED3DFMT_D24_UNORM_S8_UINT:
2681 case WINED3DFMT_S8_UINT_D24_FLOAT:
2682 case WINED3DFMT_D32_UNORM:
2683 case WINED3DFMT_D32_FLOAT:
2684 case WINED3DFMT_INTZ:
2687 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2691 *depthSize = format->depth_size;
2692 *stencilSize = format->stencil_size;
2694 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2695 *depthSize, *stencilSize, debug_d3dformat(format->id));
2699 /* Note: It's the caller's responsibility to ensure values can be expressed
2700 * in the requested format. UNORM formats for example can only express values
2701 * in the range 0.0f -> 1.0f. */
2702 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const WINED3DCOLORVALUE *color)
2706 enum wined3d_format_id format_id;
2718 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2719 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2720 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2721 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2722 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2723 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2724 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2725 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2726 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2727 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2728 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2729 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2730 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2731 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2733 const struct wined3d_format *format = surface->resource.format;
2736 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2737 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2739 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2743 if (format->id != conv[i].format_id) continue;
2745 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2746 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2747 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2748 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2750 TRACE("Returning 0x%08x.\n", ret);
2755 if (format->id == WINED3DFMT_P8_UINT)
2760 if (!surface->palette)
2762 WARN("Surface doesn't have a palette, returning 0.\n");
2766 r = (BYTE)((color->r * 255.0f) + 0.5f);
2767 g = (BYTE)((color->g * 255.0f) + 0.5f);
2768 b = (BYTE)((color->b * 255.0f) + 0.5f);
2769 a = (BYTE)((color->a * 255.0f) + 0.5f);
2771 e = &surface->palette->palents[a];
2772 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2775 WARN("Alpha didn't match index, searching full palette.\n");
2777 for (i = 0; i < 256; ++i)
2779 e = &surface->palette->palents[i];
2780 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2784 FIXME("Unable to convert color to palette index.\n");
2789 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2794 /* DirectDraw stuff */
2795 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2799 case 8: return WINED3DFMT_P8_UINT;
2800 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2801 case 16: return WINED3DFMT_B5G6R5_UNORM;
2802 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2803 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2804 default: return WINED3DFMT_UNKNOWN;
2808 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2811 /* Now do the multiplication 'by hand'.
2812 I know that all this could be optimised, but this will be done later :-) */
2813 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);
2814 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);
2815 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);
2816 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);
2818 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);
2819 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);
2820 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);
2821 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);
2823 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);
2824 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);
2825 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);
2826 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);
2828 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);
2829 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);
2830 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);
2831 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);
2833 /* And copy the new matrix in the good storage.. */
2834 memcpy(dest, &temp, 16 * sizeof(float));
2837 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2840 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2842 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2843 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2844 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2845 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2846 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2847 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2848 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2849 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2850 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2851 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2852 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2853 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2854 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2855 default: ERR("Unexpected position mask\n");
2857 for (i = 0; i < numTextures; i++) {
2858 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2864 void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_state *state,
2865 struct ffp_frag_settings *settings, BOOL ignore_textype)
2870 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2872 /* D3DTOP_DISABLE */ 0,
2873 /* D3DTOP_SELECTARG1 */ ARG1,
2874 /* D3DTOP_SELECTARG2 */ ARG2,
2875 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2876 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2877 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2878 /* D3DTOP_ADD */ ARG1 | ARG2,
2879 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2880 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2881 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2882 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2883 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2884 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2885 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2886 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2887 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2888 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2889 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2890 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2891 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2892 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2893 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2894 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2895 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2896 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2897 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2901 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2902 const struct wined3d_surface *rt = state->fb->render_targets[0];
2903 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2905 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2907 const struct wined3d_texture *texture;
2909 settings->op[i].padding = 0;
2910 if (state->texture_states[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE)
2912 settings->op[i].cop = WINED3DTOP_DISABLE;
2913 settings->op[i].aop = WINED3DTOP_DISABLE;
2914 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2915 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2916 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2917 settings->op[i].dst = resultreg;
2918 settings->op[i].tex_type = tex_1d;
2919 settings->op[i].projected = proj_none;
2924 if ((texture = state->textures[i]))
2926 settings->op[i].color_fixup = texture->resource.format->color_fixup;
2929 settings->op[i].tex_type = tex_1d;
2933 switch (texture->target)
2936 settings->op[i].tex_type = tex_1d;
2939 settings->op[i].tex_type = tex_2d;
2942 settings->op[i].tex_type = tex_3d;
2944 case GL_TEXTURE_CUBE_MAP_ARB:
2945 settings->op[i].tex_type = tex_cube;
2947 case GL_TEXTURE_RECTANGLE_ARB:
2948 settings->op[i].tex_type = tex_rect;
2953 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2954 settings->op[i].tex_type = tex_1d;
2957 cop = state->texture_states[i][WINED3DTSS_COLOROP];
2958 aop = state->texture_states[i][WINED3DTSS_ALPHAOP];
2960 carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2961 carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2962 carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2964 if (is_invalid_op(state, i, cop, carg1, carg2, carg0))
2968 carg1 = WINED3DTA_CURRENT;
2969 cop = WINED3DTOP_SELECTARG1;
2972 if(cop == WINED3DTOP_DOTPRODUCT3) {
2973 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2974 * the color result to the alpha component of the destination
2983 aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2984 aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2985 aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2988 if (!i && state->textures[0] && state->render_states[WINED3DRS_COLORKEYENABLE])
2990 GLenum texture_dimensions;
2992 texture = state->textures[0];
2993 texture_dimensions = texture->target;
2995 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2997 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
2999 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
3001 if (aop == WINED3DTOP_DISABLE)
3003 aarg1 = WINED3DTA_TEXTURE;
3004 aop = WINED3DTOP_SELECTARG1;
3006 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
3008 if (state->render_states[WINED3DRS_ALPHABLENDENABLE])
3010 aarg2 = WINED3DTA_TEXTURE;
3011 aop = WINED3DTOP_MODULATE;
3013 else aarg1 = WINED3DTA_TEXTURE;
3015 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
3017 if (state->render_states[WINED3DRS_ALPHABLENDENABLE])
3019 aarg1 = WINED3DTA_TEXTURE;
3020 aop = WINED3DTOP_MODULATE;
3022 else aarg2 = WINED3DTA_TEXTURE;
3028 if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0))
3032 aarg1 = WINED3DTA_CURRENT;
3033 aop = WINED3DTOP_SELECTARG1;
3036 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
3037 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
3039 ttff = state->texture_states[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
3040 if (ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3))
3042 settings->op[i].projected = proj_count3;
3043 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
3044 settings->op[i].projected = proj_count4;
3046 settings->op[i].projected = proj_none;
3049 settings->op[i].projected = proj_none;
3052 settings->op[i].cop = cop;
3053 settings->op[i].aop = aop;
3054 settings->op[i].carg0 = carg0;
3055 settings->op[i].carg1 = carg1;
3056 settings->op[i].carg2 = carg2;
3057 settings->op[i].aarg0 = aarg0;
3058 settings->op[i].aarg1 = aarg1;
3059 settings->op[i].aarg2 = aarg2;
3061 if (state->texture_states[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP)
3062 settings->op[i].dst = tempreg;
3064 settings->op[i].dst = resultreg;
3067 /* Clear unsupported stages */
3068 for(; i < MAX_TEXTURES; i++) {
3069 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
3072 if (!state->render_states[WINED3DRS_FOGENABLE])
3074 settings->fog = FOG_OFF;
3076 else if (state->render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
3078 if (use_vs(state) || state->vertex_declaration->position_transformed)
3080 settings->fog = FOG_LINEAR;
3084 switch (state->render_states[WINED3DRS_FOGVERTEXMODE])
3086 case WINED3DFOG_NONE:
3087 case WINED3DFOG_LINEAR:
3088 settings->fog = FOG_LINEAR;
3090 case WINED3DFOG_EXP:
3091 settings->fog = FOG_EXP;
3093 case WINED3DFOG_EXP2:
3094 settings->fog = FOG_EXP2;
3101 switch (state->render_states[WINED3DRS_FOGTABLEMODE])
3103 case WINED3DFOG_LINEAR:
3104 settings->fog = FOG_LINEAR;
3106 case WINED3DFOG_EXP:
3107 settings->fog = FOG_EXP;
3109 case WINED3DFOG_EXP2:
3110 settings->fog = FOG_EXP2;
3114 if (state->render_states[WINED3DRS_SRGBWRITEENABLE]
3115 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
3117 settings->sRGB_write = 1;
3119 settings->sRGB_write = 0;
3121 if (device->vs_clipping || !use_vs(state) || !state->render_states[WINED3DRS_CLIPPING]
3122 || !state->render_states[WINED3DRS_CLIPPLANEENABLE])
3124 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3125 * the fixed function vertex pipeline is used(which always supports clipplanes), or
3126 * if no clipplane is enabled
3128 settings->emul_clipplanes = 0;
3130 settings->emul_clipplanes = 1;
3134 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3135 const struct ffp_frag_settings *settings)
3137 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3138 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3141 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3143 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3144 * whereas desc points to an extended structure with implementation specific parts. */
3145 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3147 ERR("Failed to insert ffp frag shader.\n");
3151 /* Activates the texture dimension according to the bound D3D texture.
3152 * Does not care for the colorop or correct gl texture unit(when using nvrc)
3153 * Requires the caller to activate the correct unit before
3155 /* GL locking is done by the caller (state handler) */
3156 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3160 switch (texture->target)
3163 glDisable(GL_TEXTURE_3D);
3164 checkGLcall("glDisable(GL_TEXTURE_3D)");
3165 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3167 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3168 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3170 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3172 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3173 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3175 glEnable(GL_TEXTURE_2D);
3176 checkGLcall("glEnable(GL_TEXTURE_2D)");
3178 case GL_TEXTURE_RECTANGLE_ARB:
3179 glDisable(GL_TEXTURE_2D);
3180 checkGLcall("glDisable(GL_TEXTURE_2D)");
3181 glDisable(GL_TEXTURE_3D);
3182 checkGLcall("glDisable(GL_TEXTURE_3D)");
3183 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3185 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3186 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3188 glEnable(GL_TEXTURE_RECTANGLE_ARB);
3189 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3192 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3194 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3195 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3197 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3199 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3200 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3202 glDisable(GL_TEXTURE_2D);
3203 checkGLcall("glDisable(GL_TEXTURE_2D)");
3204 glEnable(GL_TEXTURE_3D);
3205 checkGLcall("glEnable(GL_TEXTURE_3D)");
3207 case GL_TEXTURE_CUBE_MAP_ARB:
3208 glDisable(GL_TEXTURE_2D);
3209 checkGLcall("glDisable(GL_TEXTURE_2D)");
3210 glDisable(GL_TEXTURE_3D);
3211 checkGLcall("glDisable(GL_TEXTURE_3D)");
3212 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3214 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3215 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3217 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3218 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3222 glEnable(GL_TEXTURE_2D);
3223 checkGLcall("glEnable(GL_TEXTURE_2D)");
3224 glDisable(GL_TEXTURE_3D);
3225 checkGLcall("glDisable(GL_TEXTURE_3D)");
3226 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3228 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3229 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3231 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3233 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3234 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3236 /* Binding textures is done by samplers. A dummy texture will be bound */
3240 /* GL locking is done by the caller (state handler) */
3241 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3243 DWORD sampler = state_id - STATE_SAMPLER(0);
3244 DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
3246 /* No need to enable / disable anything here for unused samplers. The
3247 * tex_colorop handler takes care. Also no action is needed with pixel
3248 * shaders, or if tex_colorop will take care of this business. */
3249 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
3251 if (sampler >= state->lowest_disabled_stage)
3253 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP)))
3256 texture_activate_dimensions(state->textures[sampler], context->gl_info);
3259 void *wined3d_rb_alloc(size_t size)
3261 return HeapAlloc(GetProcessHeap(), 0, size);
3264 void *wined3d_rb_realloc(void *ptr, size_t size)
3266 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3269 void wined3d_rb_free(void *ptr)
3271 HeapFree(GetProcessHeap(), 0, ptr);
3274 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3276 const struct ffp_frag_settings *ka = key;
3277 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3279 return memcmp(ka, kb, sizeof(*ka));
3282 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3287 ffp_frag_program_key_compare,
3290 UINT wined3d_log2i(UINT32 x)
3292 static const UINT l[] =
3294 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3295 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3296 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3297 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3298 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3299 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3300 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3301 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3302 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3303 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3304 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3305 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3306 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3307 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3308 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3309 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3313 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3316 /* Set the shader type for this device, depending on the given capabilities
3317 * and the user preferences in wined3d_settings. */
3318 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3320 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3322 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3323 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3325 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3326 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3327 * shaders only on this card. */
3328 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3329 else *vs_selected = SHADER_GLSL;
3331 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3332 else *vs_selected = SHADER_NONE;
3334 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3335 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3336 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3337 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3338 else *ps_selected = SHADER_NONE;
3341 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3342 const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format *src_format,
3343 const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format *dst_format)
3345 static const struct blit_shader * const blitters[] =
3353 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3355 if (blitters[i]->blit_supported(gl_info, blit_op,
3356 src_rect, src_usage, src_pool, src_format,
3357 dst_rect, dst_usage, dst_pool, dst_format))
3364 void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
3366 const WINED3DVIEWPORT *vp = &state->viewport;
3368 SetRect(rect, vp->X, vp->Y, vp->X + vp->Width, vp->Y + vp->Height);
3370 if (state->render_states[WINED3DRS_SCISSORTESTENABLE])
3371 IntersectRect(rect, rect, &state->scissor_rect);