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 short 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},
139 struct wined3d_format_base_flags
141 enum wined3d_format_id id;
145 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
146 * still needs to use the correct block based calculation for e.g. the
148 static const struct wined3d_format_base_flags format_base_flags[] =
150 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
151 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
152 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
153 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
156 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
157 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
158 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
159 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
160 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
161 {WINED3DFMT_INTZ, WINED3DFMT_FLAG_FOURCC},
162 {WINED3DFMT_NULL, WINED3DFMT_FLAG_FOURCC},
163 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
164 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
165 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
166 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
171 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
172 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
173 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
174 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
175 {WINED3DFMT_NVDB, WINED3DFMT_FLAG_FOURCC},
176 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
177 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
178 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
179 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
181 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
182 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
184 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
185 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
186 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
189 struct wined3d_format_compression_info
191 enum wined3d_format_id id;
194 UINT block_byte_count;
197 static const struct wined3d_format_compression_info format_compression_info[] =
199 {WINED3DFMT_DXT1, 4, 4, 8},
200 {WINED3DFMT_DXT2, 4, 4, 16},
201 {WINED3DFMT_DXT3, 4, 4, 16},
202 {WINED3DFMT_DXT4, 4, 4, 16},
203 {WINED3DFMT_DXT5, 4, 4, 16},
204 {WINED3DFMT_ATI2N, 4, 4, 16},
207 struct wined3d_format_vertex_info
209 enum wined3d_format_id id;
210 enum wined3d_ffp_emit_idx emit_idx;
211 GLint component_count;
214 GLboolean gl_normalized;
215 unsigned int component_size;
218 static const struct wined3d_format_vertex_info format_vertex_info[] =
220 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
221 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
222 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
223 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
224 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
225 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
226 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
227 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
228 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
229 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
230 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
231 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
232 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
233 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
234 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
235 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
236 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
239 struct wined3d_format_texture_info
241 enum wined3d_format_id id;
243 GLint gl_srgb_internal;
244 GLint gl_rt_internal;
247 unsigned int conv_byte_count;
249 GL_SupportedExt extension;
250 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
253 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
255 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
256 * format+type combination to load it. Thus convert it to A8L8, then load it
257 * with A4L4 internal, but A8L8 format+type
260 const unsigned char *Source;
262 UINT outpitch = pitch * 2;
264 for(y = 0; y < height; y++) {
265 Source = src + y * pitch;
266 Dest = dst + y * outpitch;
267 for (x = 0; x < width; x++ ) {
268 unsigned char color = (*Source++);
269 /* A */ Dest[1] = (color & 0xf0) << 0;
270 /* L */ Dest[0] = (color & 0x0f) << 4;
276 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
281 for(y = 0; y < height; y++)
283 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
284 Source = (const WORD *)(src + y * pitch);
285 for (x = 0; x < width; x++ )
287 short color = (*Source++);
288 unsigned char l = ((color >> 10) & 0xfc);
289 short v = ((color >> 5) & 0x3e);
290 short u = ((color ) & 0x1f);
291 short v_conv = v + 16;
292 short u_conv = u + 16;
294 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
300 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
305 UINT outpitch = (pitch * 3)/2;
307 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
308 * fixed function and shaders without further conversion once the surface is
311 for(y = 0; y < height; y++) {
312 Source = (const WORD *)(src + y * pitch);
313 Dest = dst + y * outpitch;
314 for (x = 0; x < width; x++ ) {
315 short color = (*Source++);
316 unsigned char l = ((color >> 10) & 0xfc);
317 char v = ((color >> 5) & 0x3e);
318 char u = ((color ) & 0x1f);
320 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
321 * and doubles the positive range. Thus shift left only once, gl does the 2nd
322 * shift. GL reads a signed value and converts it into an unsigned value.
324 /* M */ Dest[2] = l << 1;
326 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
327 * from 5 bit values to 8 bit values.
329 /* V */ Dest[1] = v << 3;
330 /* U */ Dest[0] = u << 3;
336 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
341 UINT outpitch = (pitch * 3)/2;
343 for(y = 0; y < height; y++)
345 Source = (const short *)(src + y * pitch);
346 Dest = dst + y * outpitch;
347 for (x = 0; x < width; x++ )
349 LONG color = (*Source++);
350 /* B */ Dest[0] = 0xff;
351 /* G */ Dest[1] = (color >> 8) + 128; /* V */
352 /* R */ Dest[2] = (color) + 128; /* U */
358 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
364 /* Doesn't work correctly with the fixed function pipeline, but can work in
365 * shaders if the shader is adjusted. (There's no use for this format in gl's
366 * standard fixed function pipeline anyway).
368 for(y = 0; y < height; y++)
370 Source = (const DWORD *)(src + y * pitch);
371 Dest = dst + y * pitch;
372 for (x = 0; x < width; x++ )
374 LONG color = (*Source++);
375 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
376 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
377 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
383 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
389 /* This implementation works with the fixed function pipeline and shaders
390 * without further modification after converting the surface.
392 for(y = 0; y < height; y++)
394 Source = (const DWORD *)(src + y * pitch);
395 Dest = dst + y * pitch;
396 for (x = 0; x < width; x++ )
398 LONG color = (*Source++);
399 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
400 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
401 /* U */ Dest[0] = (color & 0xff); /* U */
402 /* I */ Dest[3] = 255; /* X */
408 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
414 for(y = 0; y < height; y++)
416 Source = (const DWORD *)(src + y * pitch);
417 Dest = dst + y * pitch;
418 for (x = 0; x < width; x++ )
420 LONG color = (*Source++);
421 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
422 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
423 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
424 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
430 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
434 unsigned short *Dest;
435 UINT outpitch = (pitch * 3)/2;
437 for(y = 0; y < height; y++)
439 Source = (const DWORD *)(src + y * pitch);
440 Dest = (unsigned short *) (dst + y * outpitch);
441 for (x = 0; x < width; x++ )
443 DWORD color = (*Source++);
444 /* B */ Dest[0] = 0xffff;
445 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
446 /* R */ Dest[2] = (color ) + 32768; /* U */
452 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
457 UINT outpitch = (pitch * 3)/2;
459 for(y = 0; y < height; y++)
461 Source = (const WORD *)(src + y * pitch);
462 Dest = (WORD *) (dst + y * outpitch);
463 for (x = 0; x < width; x++ )
465 WORD green = (*Source++);
466 WORD red = (*Source++);
469 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
470 * shader overwrites it anyway
478 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
483 UINT outpitch = (pitch * 3)/2;
485 for(y = 0; y < height; y++)
487 Source = (const float *)(src + y * pitch);
488 Dest = (float *) (dst + y * outpitch);
489 for (x = 0; x < width; x++ )
491 float green = (*Source++);
492 float red = (*Source++);
501 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
504 UINT outpitch = pitch * 2;
506 for (y = 0; y < height; ++y)
508 const WORD *source = (const WORD *)(src + y * pitch);
509 DWORD *dest = (DWORD *)(dst + y * outpitch);
511 for (x = 0; x < width; ++x)
513 /* The depth data is normalized, so needs to be scaled,
514 * the stencil data isn't. Scale depth data by
515 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
516 WORD d15 = source[x] >> 1;
517 DWORD d24 = (d15 << 9) + (d15 >> 6);
518 dest[x] = (d24 << 8) | (source[x] & 0x1);
523 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
527 for (y = 0; y < height; ++y)
529 const DWORD *source = (const DWORD *)(src + y * pitch);
530 DWORD *dest = (DWORD *)(dst + y * pitch);
532 for (x = 0; x < width; ++x)
534 /* Just need to clear out the X4 part. */
535 dest[x] = source[x] & ~0xf0;
540 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
543 UINT outpitch = pitch * 2;
545 for (y = 0; y < height; ++y)
547 const DWORD *source = (const DWORD *)(src + y * pitch);
548 float *dest_f = (float *)(dst + y * outpitch);
549 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
551 for (x = 0; x < width; ++x)
553 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
554 dest_s[x * 2 + 1] = source[x] & 0xff;
559 static const struct wined3d_format_texture_info format_texture_info[] =
561 /* format id internal srgbInternal rtInternal
566 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
567 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
568 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
569 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
572 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
573 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
574 WINED3DFMT_FLAG_FILTERING,
575 WINED3D_GL_EXT_NONE, NULL},
576 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
577 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
578 WINED3DFMT_FLAG_FILTERING,
579 APPLE_YCBCR_422, NULL},
580 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
581 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
582 WINED3DFMT_FLAG_FILTERING,
583 WINED3D_GL_EXT_NONE, NULL},
584 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
585 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
586 WINED3DFMT_FLAG_FILTERING,
587 APPLE_YCBCR_422, NULL},
588 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
589 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
590 WINED3DFMT_FLAG_FILTERING,
591 WINED3D_GL_EXT_NONE, NULL},
592 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
593 GL_RGBA, GL_UNSIGNED_BYTE, 0,
594 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
595 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
596 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
597 GL_RGBA, GL_UNSIGNED_BYTE, 0,
598 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
599 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
600 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
601 GL_RGBA, GL_UNSIGNED_BYTE, 0,
602 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
603 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
604 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
605 GL_RGBA, GL_UNSIGNED_BYTE, 0,
606 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
607 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
608 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
609 GL_RGBA, GL_UNSIGNED_BYTE, 0,
610 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
611 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
613 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
615 WINED3DFMT_FLAG_RENDERTARGET,
616 ARB_TEXTURE_FLOAT, NULL},
617 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
619 WINED3DFMT_FLAG_RENDERTARGET,
620 ARB_TEXTURE_RG, NULL},
621 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
622 GL_RGB, GL_FLOAT, 12,
623 WINED3DFMT_FLAG_RENDERTARGET,
624 ARB_TEXTURE_FLOAT, &convert_r32g32_float},
625 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
627 WINED3DFMT_FLAG_RENDERTARGET,
628 ARB_TEXTURE_RG, NULL},
629 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
630 GL_RGBA, GL_FLOAT, 0,
631 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
632 ARB_TEXTURE_FLOAT, NULL},
634 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
635 GL_RED, GL_HALF_FLOAT_ARB, 0,
636 WINED3DFMT_FLAG_RENDERTARGET,
637 ARB_TEXTURE_FLOAT, NULL},
638 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
639 GL_RED, GL_HALF_FLOAT_ARB, 0,
640 WINED3DFMT_FLAG_RENDERTARGET,
641 ARB_TEXTURE_RG, NULL},
642 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
643 GL_RGB, GL_HALF_FLOAT_ARB, 6,
644 WINED3DFMT_FLAG_RENDERTARGET,
645 ARB_TEXTURE_FLOAT, &convert_r16g16},
646 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
647 GL_RG, GL_HALF_FLOAT_ARB, 0,
648 WINED3DFMT_FLAG_RENDERTARGET,
649 ARB_TEXTURE_RG, NULL},
650 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
651 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
652 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
653 ARB_TEXTURE_FLOAT, NULL},
654 /* Palettized formats */
655 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
656 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
658 ARB_FRAGMENT_PROGRAM, NULL},
659 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
660 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
662 EXT_PALETTED_TEXTURE, NULL},
663 /* Standard ARGB formats */
664 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
665 GL_BGR, GL_UNSIGNED_BYTE, 0,
666 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
667 WINED3D_GL_EXT_NONE, NULL},
668 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
669 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
670 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
671 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
672 WINED3D_GL_EXT_NONE, NULL},
673 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
674 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
675 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
676 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
677 WINED3D_GL_EXT_NONE, NULL},
678 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
679 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
680 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
681 WINED3D_GL_EXT_NONE, NULL},
682 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
683 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
684 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
685 WINED3D_GL_EXT_NONE, NULL},
686 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
687 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
688 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
689 WINED3D_GL_EXT_NONE, NULL},
690 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
691 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
692 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
693 WINED3D_GL_EXT_NONE, NULL},
694 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
695 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
696 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
697 WINED3D_GL_EXT_NONE, NULL},
698 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
699 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
700 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
701 WINED3D_GL_EXT_NONE, NULL},
702 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
703 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
704 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
705 WINED3D_GL_EXT_NONE, NULL},
706 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
707 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
708 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
709 WINED3D_GL_EXT_NONE, NULL},
710 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
711 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
712 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
713 WINED3D_GL_EXT_NONE, NULL},
714 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
715 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
716 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
717 WINED3D_GL_EXT_NONE, NULL},
718 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
719 GL_RGB, GL_UNSIGNED_SHORT, 6,
720 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
721 WINED3D_GL_EXT_NONE, &convert_r16g16},
722 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
723 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
724 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
725 WINED3D_GL_EXT_NONE, NULL},
726 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
727 GL_RGBA, GL_UNSIGNED_SHORT, 0,
728 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
729 WINED3D_GL_EXT_NONE, NULL},
731 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
732 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
733 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
734 WINED3D_GL_EXT_NONE, NULL},
735 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
736 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
737 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
738 WINED3D_GL_EXT_NONE, NULL},
739 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
740 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
742 WINED3D_GL_EXT_NONE, &convert_l4a4_unorm},
743 /* Bump mapping stuff */
744 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
745 GL_BGR, GL_UNSIGNED_BYTE, 3,
746 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
747 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm},
748 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
749 GL_DSDT_NV, GL_BYTE, 0,
750 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
751 NV_TEXTURE_SHADER, NULL},
752 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
753 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
754 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
755 WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm},
756 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
757 GL_DSDT_MAG_NV, GL_BYTE, 3,
758 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
759 NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv},
760 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
761 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
762 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
763 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm},
764 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
765 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
766 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
767 NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv},
768 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
769 GL_BGRA, GL_UNSIGNED_BYTE, 4,
770 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
771 WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm},
772 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
774 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
775 NV_TEXTURE_SHADER, NULL},
776 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
777 GL_BGR, GL_UNSIGNED_SHORT, 6,
778 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
779 WINED3D_GL_EXT_NONE, &convert_r16g16_snorm},
780 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
781 GL_HILO_NV, GL_SHORT, 0,
782 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
783 NV_TEXTURE_SHADER, NULL},
784 /* Depth stencil formats */
785 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
786 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
787 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
788 ARB_DEPTH_TEXTURE, NULL},
789 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
790 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
791 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
792 ARB_DEPTH_TEXTURE, NULL},
793 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
794 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
795 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
796 ARB_DEPTH_TEXTURE, NULL},
797 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
798 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
799 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
800 EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm},
801 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
802 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
803 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
804 ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm},
805 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
806 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
807 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
808 | WINED3DFMT_FLAG_SHADOW,
809 ARB_DEPTH_TEXTURE, NULL},
810 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
811 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
812 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
813 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
814 EXT_PACKED_DEPTH_STENCIL, NULL},
815 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
816 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
817 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
818 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
819 ARB_FRAMEBUFFER_OBJECT, NULL},
820 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
821 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
822 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
823 | WINED3DFMT_FLAG_SHADOW,
824 ARB_DEPTH_TEXTURE, NULL},
825 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
826 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
827 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
828 ARB_DEPTH_TEXTURE, NULL},
829 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
830 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
831 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
832 EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm},
833 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
834 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
835 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
836 ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm},
837 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
838 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
839 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
840 | WINED3DFMT_FLAG_SHADOW,
841 ARB_DEPTH_TEXTURE, NULL},
842 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
843 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
844 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
845 WINED3D_GL_EXT_NONE, NULL},
846 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
847 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
848 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
849 ARB_DEPTH_BUFFER_FLOAT, NULL},
850 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
851 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
852 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
853 ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float},
854 /* Vendor-specific formats */
855 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
856 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
857 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
858 ATI_TEXTURE_COMPRESSION_3DC, NULL},
859 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2, GL_COMPRESSED_RED_GREEN_RGTC2, 0,
860 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
861 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
862 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
863 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
864 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
865 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
866 | WINED3DFMT_FLAG_STENCIL,
867 EXT_PACKED_DEPTH_STENCIL, NULL},
868 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
869 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
870 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
871 | WINED3DFMT_FLAG_STENCIL,
872 ARB_FRAMEBUFFER_OBJECT, NULL},
873 {WINED3DFMT_NULL, GL_RGBA8, GL_RGBA8, 0,
874 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
875 WINED3DFMT_FLAG_RENDERTARGET,
876 ARB_FRAMEBUFFER_OBJECT, NULL},
879 static inline int getFmtIdx(enum wined3d_format_id format_id)
881 /* First check if the format is at the position of its value.
882 * This will catch the argb formats before the loop is entered. */
883 if (format_id < (sizeof(formats) / sizeof(*formats))
884 && formats[format_id].id == format_id)
892 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
894 if (formats[i].id == format_id) return i;
900 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
902 UINT format_count = sizeof(formats) / sizeof(*formats);
905 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
906 if (!gl_info->formats)
908 ERR("Failed to allocate memory.\n");
912 for (i = 0; i < format_count; ++i)
914 struct wined3d_format *format = &gl_info->formats[i];
915 format->id = formats[i].id;
916 format->red_mask = formats[i].redMask;
917 format->green_mask = formats[i].greenMask;
918 format->blue_mask = formats[i].blueMask;
919 format->alpha_mask = formats[i].alphaMask;
920 format->byte_count = formats[i].bpp;
921 format->depth_size = formats[i].depthSize;
922 format->stencil_size = formats[i].stencilSize;
925 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
927 int fmt_idx = getFmtIdx(format_base_flags[i].id);
931 ERR("Format %s (%#x) not found.\n",
932 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
933 HeapFree(GetProcessHeap(), 0, gl_info->formats);
937 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
943 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
947 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
949 struct wined3d_format *format;
950 int fmt_idx = getFmtIdx(format_compression_info[i].id);
954 ERR("Format %s (%#x) not found.\n",
955 debug_d3dformat(format_compression_info[i].id), format_compression_info[i].id);
959 format = &gl_info->formats[fmt_idx];
960 format->block_width = format_compression_info[i].block_width;
961 format->block_height = format_compression_info[i].block_height;
962 format->block_byte_count = format_compression_info[i].block_byte_count;
963 format->flags |= WINED3DFMT_FLAG_COMPRESSED;
969 /* Context activation is done by the caller. */
970 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
972 /* Check if the default internal format is supported as a frame buffer
973 * target, otherwise fall back to the render target internal.
975 * Try to stick to the standard format if possible, this limits precision differences. */
984 glGenTextures(1, &tex);
985 glBindTexture(GL_TEXTURE_2D, tex);
987 glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
988 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
989 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
991 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
993 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
994 checkGLcall("Framebuffer format check");
996 if (status == GL_FRAMEBUFFER_COMPLETE)
998 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
999 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1000 format->rtInternal = format->glInternal;
1004 if (!format->rtInternal)
1006 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1008 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1009 " and no fallback specified.\n", debug_d3dformat(format->id));
1010 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1014 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1016 format->rtInternal = format->glInternal;
1020 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1021 debug_d3dformat(format->id));
1023 while(glGetError());
1025 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1027 glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1028 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1029 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1031 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1033 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1034 checkGLcall("Framebuffer format check");
1036 if (status == GL_FRAMEBUFFER_COMPLETE)
1038 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1039 debug_d3dformat(format->id));
1043 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1044 debug_d3dformat(format->id));
1045 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1050 if (status == GL_FRAMEBUFFER_COMPLETE && format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1054 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1055 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1057 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1058 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1059 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1060 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1061 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1062 checkGLcall("RB attachment");
1066 glClear(GL_COLOR_BUFFER_BIT);
1067 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1069 while(glGetError());
1070 TRACE("Format doesn't support post-pixelshader blending.\n");
1071 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1074 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1075 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1077 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1078 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1079 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1080 checkGLcall("RB cleanup");
1084 if (format->glInternal != format->glGammaInternal)
1086 glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1087 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1089 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1090 checkGLcall("Framebuffer format check");
1092 if (status == GL_FRAMEBUFFER_COMPLETE)
1094 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1095 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1099 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1103 glDeleteTextures(1, &tex);
1108 /* Context activation is done by the caller. */
1109 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1114 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1118 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1119 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1124 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1126 struct wined3d_format *format = &gl_info->formats[i];
1128 if (!format->glInternal) continue;
1130 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1132 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1133 debug_d3dformat(format->id));
1137 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1139 TRACE("Skipping format %s because it's a compressed format.\n",
1140 debug_d3dformat(format->id));
1144 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1146 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1147 check_fbo_compat(gl_info, format);
1151 format->rtInternal = format->glInternal;
1155 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1159 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1165 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1169 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1171 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1172 struct wined3d_format *format;
1176 ERR("Format %s (%#x) not found.\n",
1177 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1181 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1183 format = &gl_info->formats[fmt_idx];
1185 /* ARB_texture_rg defines floating point formats, but only if
1186 * ARB_texture_float is also supported. */
1187 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1188 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1191 format->glInternal = format_texture_info[i].gl_internal;
1192 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1193 format->rtInternal = format_texture_info[i].gl_rt_internal;
1194 format->glFormat = format_texture_info[i].gl_format;
1195 format->glType = format_texture_info[i].gl_type;
1196 format->color_fixup = COLOR_FIXUP_IDENTITY;
1197 format->flags |= format_texture_info[i].flags;
1198 format->heightscale = 1.0f;
1200 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1201 if (!gl_info->supported[EXT_TEXTURE_SRGB]
1202 && format->glGammaInternal != format->glInternal)
1204 format->glGammaInternal = format->glInternal;
1205 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1208 /* Texture conversion stuff */
1209 format->convert = format_texture_info[i].convert;
1210 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1216 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1218 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1220 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1222 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1224 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1228 /* A context is provided by the caller */
1229 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1231 static const DWORD data[] = {0x00000000, 0xffffffff};
1232 GLuint tex, fbo, buffer;
1233 DWORD readback[16 * 1];
1236 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1237 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1238 * falling back to software. If this changes in the future this code will get fooled and
1239 * apps might hit the software path due to incorrectly advertised caps.
1241 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1242 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1243 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1247 while(glGetError());
1249 glGenTextures(1, &buffer);
1250 glBindTexture(GL_TEXTURE_2D, buffer);
1251 memset(readback, 0x7e, sizeof(readback));
1252 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1253 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1254 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1255 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1256 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1257 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1259 glGenTextures(1, &tex);
1260 glBindTexture(GL_TEXTURE_2D, tex);
1261 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1264 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1265 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1266 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1267 glEnable(GL_TEXTURE_2D);
1269 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1270 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1271 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1272 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1274 glViewport(0, 0, 16, 1);
1275 glDisable(GL_LIGHTING);
1276 glMatrixMode(GL_MODELVIEW);
1278 glMatrixMode(GL_PROJECTION);
1281 glClearColor(0, 1, 0, 0);
1282 glClear(GL_COLOR_BUFFER_BIT);
1284 glBegin(GL_TRIANGLE_STRIP);
1285 glTexCoord2f(0.0, 0.0);
1286 glVertex2f(-1.0f, -1.0f);
1287 glTexCoord2f(1.0, 0.0);
1288 glVertex2f(1.0f, -1.0f);
1289 glTexCoord2f(0.0, 1.0);
1290 glVertex2f(-1.0f, 1.0f);
1291 glTexCoord2f(1.0, 1.0);
1292 glVertex2f(1.0f, 1.0f);
1295 glBindTexture(GL_TEXTURE_2D, buffer);
1296 memset(readback, 0x7f, sizeof(readback));
1297 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1298 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1299 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1301 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1302 readback[6], readback[9]);
1307 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1308 readback[6], readback[9]);
1312 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1313 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1314 glDeleteTextures(1, &tex);
1315 glDeleteTextures(1, &buffer);
1319 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1326 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1328 struct wined3d_format *format;
1329 unsigned int fmt_idx, i;
1330 static const enum wined3d_format_id fmts16[] =
1332 WINED3DFMT_R16_FLOAT,
1333 WINED3DFMT_R16G16_FLOAT,
1334 WINED3DFMT_R16G16B16A16_FLOAT,
1338 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1340 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1341 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1343 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1346 else if (gl_info->limits.glsl_varyings > 44)
1348 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1353 TRACE("Assuming no float16 blending\n");
1359 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1361 fmt_idx = getFmtIdx(fmts16[i]);
1362 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1368 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1370 fmt_idx = getFmtIdx(fmts16[i]);
1371 format = &gl_info->formats[fmt_idx];
1372 if (!format->glInternal) continue; /* Not supported by GL */
1374 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1377 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1378 format->flags |= WINED3DFMT_FLAG_FILTERING;
1382 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1387 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1391 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1392 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1393 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1395 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1396 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1397 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1399 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1400 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1401 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1403 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1404 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1405 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1407 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1408 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1409 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1411 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1412 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1413 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1414 * the only driver that implements it(fglrx) has a buggy implementation.
1416 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1417 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1418 * conversion for this format.
1420 if (!gl_info->supported[NV_TEXTURE_SHADER])
1422 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1423 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1424 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1425 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1426 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1427 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1431 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1432 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1433 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1435 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1436 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1437 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1440 if (!gl_info->supported[NV_TEXTURE_SHADER])
1442 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1445 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1446 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1447 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1448 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1449 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1450 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1451 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1452 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1453 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1457 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1458 * are converted at surface loading time, but they do not need any modification in
1459 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1460 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1464 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1466 idx = getFmtIdx(WINED3DFMT_ATI2N);
1467 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1468 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1470 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1472 idx = getFmtIdx(WINED3DFMT_ATI2N);
1473 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1474 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1477 if (!gl_info->supported[APPLE_YCBCR_422])
1479 idx = getFmtIdx(WINED3DFMT_YUY2);
1480 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1482 idx = getFmtIdx(WINED3DFMT_UYVY);
1483 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1486 idx = getFmtIdx(WINED3DFMT_YV12);
1487 gl_info->formats[idx].heightscale = 1.5f;
1488 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1490 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1492 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1493 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1496 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1498 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1499 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1502 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1504 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1505 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1506 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1507 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1509 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1510 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1514 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1518 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1520 struct wined3d_format *format;
1521 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1525 ERR("Format %s (%#x) not found.\n",
1526 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1530 format = &gl_info->formats[fmt_idx];
1531 format->emit_idx = format_vertex_info[i].emit_idx;
1532 format->component_count = format_vertex_info[i].component_count;
1533 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1534 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1535 format->gl_normalized = format_vertex_info[i].gl_normalized;
1536 format->component_size = format_vertex_info[i].component_size;
1542 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1544 if (!init_format_base_info(gl_info)) return FALSE;
1546 if (!init_format_compression_info(gl_info))
1548 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1549 gl_info->formats = NULL;
1556 /* Context activation is done by the caller. */
1557 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1559 if (!init_format_base_info(gl_info)) return FALSE;
1561 if (!init_format_compression_info(gl_info)) goto fail;
1562 if (!init_format_texture_info(gl_info)) goto fail;
1563 if (!init_format_vertex_info(gl_info)) goto fail;
1565 apply_format_fixups(gl_info);
1566 init_format_fbo_compat_info(gl_info);
1567 init_format_filter_info(gl_info, vendor);
1572 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1573 gl_info->formats = NULL;
1577 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1578 enum wined3d_format_id format_id)
1580 int idx = getFmtIdx(format_id);
1584 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1585 debug_d3dformat(format_id), format_id);
1586 /* Get the caller a valid pointer */
1587 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1590 return &gl_info->formats[idx];
1593 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1597 if (format->id == WINED3DFMT_UNKNOWN)
1601 else if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1603 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1604 UINT row_count = (height + format->block_height - 1) / format->block_height;
1605 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1609 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1612 if (format->heightscale != 0.0f) size *= format->heightscale;
1617 /*****************************************************************************
1618 * Trace formatting of useful values
1620 const char *debug_d3dformat(enum wined3d_format_id format_id)
1624 #define FMT_TO_STR(format_id) case format_id: return #format_id
1625 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1626 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1627 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1628 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1629 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1630 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1631 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1632 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1633 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1634 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1635 FMT_TO_STR(WINED3DFMT_P8_UINT);
1636 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1637 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1638 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1639 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1640 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1641 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1642 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1643 FMT_TO_STR(WINED3DFMT_UYVY);
1644 FMT_TO_STR(WINED3DFMT_YUY2);
1645 FMT_TO_STR(WINED3DFMT_YV12);
1646 FMT_TO_STR(WINED3DFMT_DXT1);
1647 FMT_TO_STR(WINED3DFMT_DXT2);
1648 FMT_TO_STR(WINED3DFMT_DXT3);
1649 FMT_TO_STR(WINED3DFMT_DXT4);
1650 FMT_TO_STR(WINED3DFMT_DXT5);
1651 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1652 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1653 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1654 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1655 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1656 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1657 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1658 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1659 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1660 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1661 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1662 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1663 FMT_TO_STR(WINED3DFMT_ATI2N);
1664 FMT_TO_STR(WINED3DFMT_NVDB);
1665 FMT_TO_STR(WINED3DFMT_NVHU);
1666 FMT_TO_STR(WINED3DFMT_NVHS);
1667 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1668 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1669 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1670 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1671 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1672 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1673 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1674 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1675 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1676 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1677 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1678 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1679 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1680 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1681 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1682 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1683 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1684 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1685 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1686 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1687 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1688 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1689 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1690 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1691 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1692 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1693 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1694 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1695 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1696 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1697 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1698 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1699 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1700 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1701 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1702 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1703 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1704 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1705 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1706 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1707 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1708 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1709 FMT_TO_STR(WINED3DFMT_R32_UINT);
1710 FMT_TO_STR(WINED3DFMT_R32_SINT);
1711 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1712 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1713 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1714 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1715 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1716 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1717 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1718 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1719 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1720 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1721 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1722 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1723 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1724 FMT_TO_STR(WINED3DFMT_R16_UINT);
1725 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1726 FMT_TO_STR(WINED3DFMT_R16_SINT);
1727 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1728 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1729 FMT_TO_STR(WINED3DFMT_R8_UINT);
1730 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1731 FMT_TO_STR(WINED3DFMT_R8_SINT);
1732 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1733 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1734 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1735 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1736 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1737 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1738 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1739 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1740 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1741 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1742 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1743 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1744 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1745 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1746 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1747 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1748 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1749 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1750 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1751 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1752 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1753 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1754 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1755 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1756 FMT_TO_STR(WINED3DFMT_INTZ);
1757 FMT_TO_STR(WINED3DFMT_NULL);
1762 fourcc[0] = (char)(format_id);
1763 fourcc[1] = (char)(format_id >> 8);
1764 fourcc[2] = (char)(format_id >> 16);
1765 fourcc[3] = (char)(format_id >> 24);
1767 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1768 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1770 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1772 return "unrecognized";
1776 const char *debug_d3ddevicetype(WINED3DDEVTYPE devtype)
1780 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1781 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1782 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1783 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1784 #undef DEVTYPE_TO_STR
1786 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1787 return "unrecognized";
1791 const char *debug_d3dusage(DWORD usage)
1796 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1797 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1798 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1799 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1800 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1801 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1802 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1803 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1804 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1805 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1806 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1807 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1808 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1809 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1810 #undef WINED3DUSAGE_TO_STR
1811 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1813 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1816 const char *debug_d3dusagequery(DWORD usagequery)
1821 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1822 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1823 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1824 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1825 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1826 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1827 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1828 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1829 #undef WINED3DUSAGEQUERY_TO_STR
1830 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1832 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1835 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1837 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1838 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1839 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1840 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1841 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1842 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1843 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1844 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1845 #undef WINED3DDECLMETHOD_TO_STR
1847 FIXME("Unrecognized %u declaration method!\n", method);
1848 return "unrecognized";
1852 const char* debug_d3ddeclusage(BYTE usage) {
1854 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1855 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1856 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1857 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1858 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1859 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1860 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1861 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1862 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1863 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1864 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1865 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1866 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1867 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1868 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1869 #undef WINED3DDECLUSAGE_TO_STR
1871 FIXME("Unrecognized %u declaration usage!\n", usage);
1872 return "unrecognized";
1876 const char *debug_d3dresourcetype(WINED3DRESOURCETYPE res)
1880 #define RES_TO_STR(res) case res: return #res
1881 RES_TO_STR(WINED3DRTYPE_SURFACE);
1882 RES_TO_STR(WINED3DRTYPE_VOLUME);
1883 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1884 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1885 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1886 RES_TO_STR(WINED3DRTYPE_BUFFER);
1889 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1890 return "unrecognized";
1894 const char *debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType)
1896 switch (PrimitiveType)
1898 #define PRIM_TO_STR(prim) case prim: return #prim
1899 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1900 PRIM_TO_STR(WINED3DPT_POINTLIST);
1901 PRIM_TO_STR(WINED3DPT_LINELIST);
1902 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1903 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1904 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1905 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1906 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1907 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1908 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1909 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1912 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1913 return "unrecognized";
1917 const char *debug_d3drenderstate(WINED3DRENDERSTATETYPE state)
1921 #define D3DSTATE_TO_STR(u) case u: return #u
1922 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS);
1923 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE);
1924 D3DSTATE_TO_STR(WINED3DRS_WRAPU);
1925 D3DSTATE_TO_STR(WINED3DRS_WRAPV);
1926 D3DSTATE_TO_STR(WINED3DRS_ZENABLE);
1927 D3DSTATE_TO_STR(WINED3DRS_FILLMODE);
1928 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE);
1929 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN);
1930 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE);
1931 D3DSTATE_TO_STR(WINED3DRS_ROP2);
1932 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK);
1933 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE);
1934 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE);
1935 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL);
1936 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND);
1937 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND);
1938 D3DSTATE_TO_STR(WINED3DRS_CULLMODE);
1939 D3DSTATE_TO_STR(WINED3DRS_ZFUNC);
1940 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF);
1941 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC);
1942 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE);
1943 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE);
1944 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE);
1945 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE);
1946 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE);
1947 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL);
1948 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX);
1949 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA);
1950 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR);
1951 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE);
1952 D3DSTATE_TO_STR(WINED3DRS_FOGSTART);
1953 D3DSTATE_TO_STR(WINED3DRS_FOGEND);
1954 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY);
1955 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE);
1956 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS);
1957 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE);
1958 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS);
1959 D3DSTATE_TO_STR(WINED3DRS_ZBIAS);
1960 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE);
1961 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY);
1962 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH);
1963 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1964 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE);
1965 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL);
1966 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL);
1967 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS);
1968 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC);
1969 D3DSTATE_TO_STR(WINED3DRS_STENCILREF);
1970 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK);
1971 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK);
1972 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR);
1973 D3DSTATE_TO_STR(WINED3DRS_WRAP0);
1974 D3DSTATE_TO_STR(WINED3DRS_WRAP1);
1975 D3DSTATE_TO_STR(WINED3DRS_WRAP2);
1976 D3DSTATE_TO_STR(WINED3DRS_WRAP3);
1977 D3DSTATE_TO_STR(WINED3DRS_WRAP4);
1978 D3DSTATE_TO_STR(WINED3DRS_WRAP5);
1979 D3DSTATE_TO_STR(WINED3DRS_WRAP6);
1980 D3DSTATE_TO_STR(WINED3DRS_WRAP7);
1981 D3DSTATE_TO_STR(WINED3DRS_CLIPPING);
1982 D3DSTATE_TO_STR(WINED3DRS_LIGHTING);
1983 D3DSTATE_TO_STR(WINED3DRS_EXTENTS);
1984 D3DSTATE_TO_STR(WINED3DRS_AMBIENT);
1985 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE);
1986 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX);
1987 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER);
1988 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS);
1989 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE);
1990 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE);
1991 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE);
1992 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE);
1993 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE);
1994 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND);
1995 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE);
1996 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING);
1997 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE);
1998 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN);
1999 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE);
2000 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE);
2001 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A);
2002 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B);
2003 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C);
2004 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS);
2005 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK);
2006 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE);
2007 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS);
2008 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN);
2009 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX);
2010 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE);
2011 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE);
2012 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR);
2013 D3DSTATE_TO_STR(WINED3DRS_BLENDOP);
2014 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE);
2015 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE);
2016 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE);
2017 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS);
2018 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE);
2019 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL);
2020 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL);
2021 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X);
2022 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y);
2023 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z);
2024 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W);
2025 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
2026 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE);
2027 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL);
2028 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL);
2029 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS);
2030 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC);
2031 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1);
2032 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2);
2033 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3);
2034 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR);
2035 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE);
2036 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS);
2037 D3DSTATE_TO_STR(WINED3DRS_WRAP8);
2038 D3DSTATE_TO_STR(WINED3DRS_WRAP9);
2039 D3DSTATE_TO_STR(WINED3DRS_WRAP10);
2040 D3DSTATE_TO_STR(WINED3DRS_WRAP11);
2041 D3DSTATE_TO_STR(WINED3DRS_WRAP12);
2042 D3DSTATE_TO_STR(WINED3DRS_WRAP13);
2043 D3DSTATE_TO_STR(WINED3DRS_WRAP14);
2044 D3DSTATE_TO_STR(WINED3DRS_WRAP15);
2045 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE);
2046 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA);
2047 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA);
2048 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA);
2049 #undef D3DSTATE_TO_STR
2051 FIXME("Unrecognized %u render state!\n", state);
2052 return "unrecognized";
2056 const char *debug_d3dsamplerstate(DWORD state)
2060 #define D3DSTATE_TO_STR(u) case u: return #u
2061 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR);
2062 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU);
2063 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV);
2064 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW);
2065 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER);
2066 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER);
2067 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER);
2068 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
2069 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL);
2070 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
2071 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE);
2072 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX);
2073 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET);
2074 #undef D3DSTATE_TO_STR
2076 FIXME("Unrecognized %u sampler state!\n", state);
2077 return "unrecognized";
2081 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2082 switch (filter_type) {
2083 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2084 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2085 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2086 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2087 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2088 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2089 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2090 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2091 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2092 #undef D3DTEXTUREFILTERTYPE_TO_STR
2094 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2095 return "unrecognized";
2099 const char *debug_d3dtexturestate(DWORD state)
2103 #define D3DSTATE_TO_STR(u) case u: return #u
2104 D3DSTATE_TO_STR(WINED3DTSS_COLOROP);
2105 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1);
2106 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2);
2107 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP);
2108 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1);
2109 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2);
2110 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00);
2111 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01);
2112 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10);
2113 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11);
2114 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX);
2115 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE);
2116 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET);
2117 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS);
2118 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0);
2119 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0);
2120 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG);
2121 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT);
2122 #undef D3DSTATE_TO_STR
2124 FIXME("Unrecognized %u texture state!\n", state);
2125 return "unrecognized";
2129 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2131 #define D3DTOP_TO_STR(u) case u: return #u
2132 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2133 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2134 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2135 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2136 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2137 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2138 D3DTOP_TO_STR(WINED3DTOP_ADD);
2139 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2140 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2141 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2142 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2143 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2144 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2145 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2146 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2147 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2148 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2149 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2150 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2151 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2152 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2153 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2154 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2155 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2156 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2157 D3DTOP_TO_STR(WINED3DTOP_LERP);
2158 #undef D3DTOP_TO_STR
2160 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2161 return "unrecognized";
2165 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2167 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2168 TSTYPE_TO_STR(WINED3DTS_VIEW);
2169 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2170 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2171 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2172 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2173 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2174 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2175 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2176 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2177 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2178 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2179 #undef TSTYPE_TO_STR
2181 if (tstype > 256 && tstype < 512) {
2182 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2183 return ("WINED3DTS_WORLDMATRIX > 0");
2185 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2186 return "unrecognized";
2190 const char *debug_d3dstate(DWORD state)
2192 if (STATE_IS_RENDER(state))
2193 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2194 if (STATE_IS_TEXTURESTAGE(state))
2196 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2197 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2198 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2199 texture_stage, debug_d3dtexturestate(texture_state));
2201 if (STATE_IS_SAMPLER(state))
2202 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2203 if (STATE_IS_PIXELSHADER(state))
2204 return "STATE_PIXELSHADER";
2205 if (STATE_IS_TRANSFORM(state))
2206 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2207 if (STATE_IS_STREAMSRC(state))
2208 return "STATE_STREAMSRC";
2209 if (STATE_IS_INDEXBUFFER(state))
2210 return "STATE_INDEXBUFFER";
2211 if (STATE_IS_VDECL(state))
2212 return "STATE_VDECL";
2213 if (STATE_IS_VSHADER(state))
2214 return "STATE_VSHADER";
2215 if (STATE_IS_VIEWPORT(state))
2216 return "STATE_VIEWPORT";
2217 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2218 return "STATE_VERTEXSHADERCONSTANT";
2219 if (STATE_IS_PIXELSHADERCONSTANT(state))
2220 return "STATE_PIXELSHADERCONSTANT";
2221 if (STATE_IS_ACTIVELIGHT(state))
2222 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2223 if (STATE_IS_SCISSORRECT(state))
2224 return "STATE_SCISSORRECT";
2225 if (STATE_IS_CLIPPLANE(state))
2226 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2227 if (STATE_IS_MATERIAL(state))
2228 return "STATE_MATERIAL";
2229 if (STATE_IS_FRONTFACE(state))
2230 return "STATE_FRONTFACE";
2231 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2232 return "STATE_POINTSPRITECOORDORIGIN";
2234 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2237 const char *debug_d3dpool(WINED3DPOOL pool)
2241 #define POOL_TO_STR(p) case p: return #p
2242 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2243 POOL_TO_STR(WINED3DPOOL_MANAGED);
2244 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2245 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2248 FIXME("Unrecognized %u WINED3DPOOL!\n", pool);
2249 return "unrecognized";
2253 const char *debug_fbostatus(GLenum status) {
2255 #define FBOSTATUS_TO_STR(u) case u: return #u
2256 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2257 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2258 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2259 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2260 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2261 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2262 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2263 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2264 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2265 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2266 #undef FBOSTATUS_TO_STR
2268 FIXME("Unrecognied FBO status 0x%08x\n", status);
2269 return "unrecognized";
2273 const char *debug_glerror(GLenum error) {
2275 #define GLERROR_TO_STR(u) case u: return #u
2276 GLERROR_TO_STR(GL_NO_ERROR);
2277 GLERROR_TO_STR(GL_INVALID_ENUM);
2278 GLERROR_TO_STR(GL_INVALID_VALUE);
2279 GLERROR_TO_STR(GL_INVALID_OPERATION);
2280 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2281 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2282 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2283 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2284 #undef GLERROR_TO_STR
2286 FIXME("Unrecognied GL error 0x%08x\n", error);
2287 return "unrecognized";
2291 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2293 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2294 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2295 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2296 default: return "unrecognized";
2300 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2302 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2303 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2304 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2305 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2306 default: return "unrecognized";
2310 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2314 #define WINED3D_TO_STR(x) case x: return #x
2315 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2316 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2317 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2318 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2319 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2320 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2321 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2322 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2323 #undef WINED3D_TO_STR
2325 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2326 return "unrecognized";
2330 static const char *debug_complex_fixup(enum complex_fixup fixup)
2334 #define WINED3D_TO_STR(x) case x: return #x
2335 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2336 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2337 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2338 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2339 #undef WINED3D_TO_STR
2341 FIXME("Unrecognized complex fixup %#x\n", fixup);
2342 return "unrecognized";
2346 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2348 if (is_complex_fixup(fixup))
2350 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2354 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2355 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2356 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2357 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2360 const char *debug_surflocation(DWORD flag) {
2364 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2365 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2366 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2367 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2368 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2371 /*****************************************************************************
2372 * Useful functions mapping GL <-> D3D values
2374 GLenum StencilOp(DWORD op) {
2376 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2377 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2378 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2379 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2380 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2381 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2382 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2383 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2385 FIXME("Unrecognized stencil op %d\n", op);
2390 GLenum CompareFunc(DWORD func) {
2391 switch ((WINED3DCMPFUNC)func) {
2392 case WINED3DCMP_NEVER : return GL_NEVER;
2393 case WINED3DCMP_LESS : return GL_LESS;
2394 case WINED3DCMP_EQUAL : return GL_EQUAL;
2395 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2396 case WINED3DCMP_GREATER : return GL_GREATER;
2397 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2398 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2399 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2401 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2406 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2407 WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
2409 if (op == WINED3DTOP_DISABLE) return FALSE;
2410 if (state->textures[stage]) return FALSE;
2412 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2413 && op != WINED3DTOP_SELECTARG2) return TRUE;
2414 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2415 && op != WINED3DTOP_SELECTARG1) return TRUE;
2416 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2417 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2422 /* Setup this textures matrix according to the texture flags*/
2423 /* GL locking is done by the caller (state handler) */
2424 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2425 enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2429 glMatrixMode(GL_TEXTURE);
2430 checkGLcall("glMatrixMode(GL_TEXTURE)");
2432 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2434 checkGLcall("glLoadIdentity()");
2438 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2439 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2443 memcpy(mat, smat, 16 * sizeof(float));
2445 if (flags & WINED3DTTFF_PROJECTED) {
2446 if(!ffp_proj_control) {
2447 switch (flags & ~WINED3DTTFF_PROJECTED) {
2448 case WINED3DTTFF_COUNT2:
2449 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2450 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2452 case WINED3DTTFF_COUNT3:
2453 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2454 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2458 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2459 if(!calculatedCoords) {
2462 case WINED3DFMT_R32_FLOAT:
2463 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2464 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2465 * the input value to the transformation will be 0, so the matrix value is irrelevant
2472 case WINED3DFMT_R32G32_FLOAT:
2473 /* See above, just 3rd and 4th coord
2480 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2481 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2483 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2484 * into a bad place. The division elimination below will apply to make sure the
2485 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2487 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2490 FIXME("Unexpected fixed function texture coord input\n");
2493 if(!ffp_proj_control) {
2494 switch (flags & ~WINED3DTTFF_PROJECTED) {
2495 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2496 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2497 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2498 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2499 * the 4th coord evaluates to 1.0 to eliminate that.
2501 * If the fixed function pipeline is used, the 4th value remains unused,
2502 * so there is no danger in doing this. With vertex shaders we have a
2503 * problem. Should an app hit that problem, the code here would have to
2504 * check for pixel shaders, and the shader has to undo the default gl divide.
2506 * A more serious problem occurs if the app passes 4 coordinates in, and the
2507 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2508 * or a replacement shader
2510 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2516 checkGLcall("glLoadMatrixf(mat)");
2519 /* This small helper function is used to convert a bitmask into the number of masked bits */
2520 unsigned int count_bits(unsigned int mask)
2523 for (count = 0; mask; ++count)
2530 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2531 * The later function requires individual color components. */
2532 BOOL getColorBits(const struct wined3d_format *format,
2533 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2535 TRACE("format %s.\n", debug_d3dformat(format->id));
2539 case WINED3DFMT_B10G10R10A2_UNORM:
2540 case WINED3DFMT_R10G10B10A2_UNORM:
2541 case WINED3DFMT_B8G8R8X8_UNORM:
2542 case WINED3DFMT_B8G8R8_UNORM:
2543 case WINED3DFMT_B8G8R8A8_UNORM:
2544 case WINED3DFMT_R8G8B8A8_UNORM:
2545 case WINED3DFMT_B5G5R5X1_UNORM:
2546 case WINED3DFMT_B5G5R5A1_UNORM:
2547 case WINED3DFMT_B5G6R5_UNORM:
2548 case WINED3DFMT_B4G4R4X4_UNORM:
2549 case WINED3DFMT_B4G4R4A4_UNORM:
2550 case WINED3DFMT_B2G3R3_UNORM:
2551 case WINED3DFMT_P8_UINT_A8_UNORM:
2552 case WINED3DFMT_P8_UINT:
2555 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2559 *redSize = count_bits(format->red_mask);
2560 *greenSize = count_bits(format->green_mask);
2561 *blueSize = count_bits(format->blue_mask);
2562 *alphaSize = count_bits(format->alpha_mask);
2563 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2565 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2566 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2570 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2571 BOOL getDepthStencilBits(const struct wined3d_format *format, short *depthSize, short *stencilSize)
2573 TRACE("format %s.\n", debug_d3dformat(format->id));
2577 case WINED3DFMT_D16_LOCKABLE:
2578 case WINED3DFMT_D16_UNORM:
2579 case WINED3DFMT_S1_UINT_D15_UNORM:
2580 case WINED3DFMT_X8D24_UNORM:
2581 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2582 case WINED3DFMT_D24_UNORM_S8_UINT:
2583 case WINED3DFMT_S8_UINT_D24_FLOAT:
2584 case WINED3DFMT_D32_UNORM:
2585 case WINED3DFMT_D32_FLOAT:
2586 case WINED3DFMT_INTZ:
2589 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2593 *depthSize = format->depth_size;
2594 *stencilSize = format->stencil_size;
2596 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2597 *depthSize, *stencilSize, debug_d3dformat(format->id));
2601 /* Note: It's the caller's responsibility to ensure values can be expressed
2602 * in the requested format. UNORM formats for example can only express values
2603 * in the range 0.0f -> 1.0f. */
2604 DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, const WINED3DCOLORVALUE *color)
2608 enum wined3d_format_id format_id;
2620 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2621 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2622 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2623 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2624 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2625 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2626 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2627 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2628 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2629 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2630 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2631 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2632 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2633 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2637 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2638 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2640 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2644 if (format->id != conv[i].format_id) continue;
2646 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2647 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2648 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2649 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2651 TRACE("Returning 0x%08x.\n", ret);
2656 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2661 /* DirectDraw stuff */
2662 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2666 case 8: return WINED3DFMT_P8_UINT;
2667 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2668 case 16: return WINED3DFMT_B5G6R5_UNORM;
2669 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2670 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2671 default: return WINED3DFMT_UNKNOWN;
2675 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2678 /* Now do the multiplication 'by hand'.
2679 I know that all this could be optimised, but this will be done later :-) */
2680 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);
2681 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);
2682 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);
2683 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);
2685 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);
2686 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);
2687 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);
2688 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);
2690 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);
2691 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);
2692 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);
2693 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);
2695 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);
2696 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);
2697 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);
2698 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);
2700 /* And copy the new matrix in the good storage.. */
2701 memcpy(dest, &temp, 16 * sizeof(float));
2704 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2707 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2709 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2710 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2711 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2712 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2713 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2714 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2715 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2716 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2717 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2718 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2719 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2720 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2721 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2722 default: ERR("Unexpected position mask\n");
2724 for (i = 0; i < numTextures; i++) {
2725 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2731 void gen_ffp_frag_op(struct wined3d_stateblock *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype)
2736 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2738 /* D3DTOP_DISABLE */ 0,
2739 /* D3DTOP_SELECTARG1 */ ARG1,
2740 /* D3DTOP_SELECTARG2 */ ARG2,
2741 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2742 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2743 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2744 /* D3DTOP_ADD */ ARG1 | ARG2,
2745 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2746 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2747 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2748 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2749 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2750 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2751 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2752 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2753 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2754 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2755 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2756 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2757 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2758 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2759 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2760 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2761 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2762 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2763 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2767 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2768 IWineD3DDeviceImpl *device = stateblock->device;
2769 IWineD3DSurfaceImpl *rt = device->render_targets[0];
2770 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2772 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2774 IWineD3DBaseTextureImpl *texture;
2775 settings->op[i].padding = 0;
2776 if (stateblock->state.texture_states[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE)
2778 settings->op[i].cop = WINED3DTOP_DISABLE;
2779 settings->op[i].aop = WINED3DTOP_DISABLE;
2780 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2781 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2782 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2783 settings->op[i].dst = resultreg;
2784 settings->op[i].tex_type = tex_1d;
2785 settings->op[i].projected = proj_none;
2790 if ((texture = stateblock->state.textures[i]))
2792 settings->op[i].color_fixup = texture->resource.format->color_fixup;
2795 settings->op[i].tex_type = tex_1d;
2799 switch (texture->baseTexture.target)
2802 settings->op[i].tex_type = tex_1d;
2805 settings->op[i].tex_type = tex_2d;
2808 settings->op[i].tex_type = tex_3d;
2810 case GL_TEXTURE_CUBE_MAP_ARB:
2811 settings->op[i].tex_type = tex_cube;
2813 case GL_TEXTURE_RECTANGLE_ARB:
2814 settings->op[i].tex_type = tex_rect;
2819 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2820 settings->op[i].tex_type = tex_1d;
2823 cop = stateblock->state.texture_states[i][WINED3DTSS_COLOROP];
2824 aop = stateblock->state.texture_states[i][WINED3DTSS_ALPHAOP];
2826 carg1 = (args[cop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2827 carg2 = (args[cop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2828 carg0 = (args[cop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2830 if (is_invalid_op(&stateblock->state, i, cop, carg1, carg2, carg0))
2834 carg1 = WINED3DTA_CURRENT;
2835 cop = WINED3DTOP_SELECTARG1;
2838 if(cop == WINED3DTOP_DOTPRODUCT3) {
2839 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2840 * the color result to the alpha component of the destination
2849 aarg1 = (args[aop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2850 aarg2 = (args[aop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2851 aarg0 = (args[aop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2854 if (!i && stateblock->state.textures[0] && stateblock->state.render_states[WINED3DRS_COLORKEYENABLE])
2856 IWineD3DBaseTextureImpl *texture = stateblock->state.textures[0];
2857 GLenum texture_dimensions = texture->baseTexture.target;
2859 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2861 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
2863 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
2865 if (aop == WINED3DTOP_DISABLE)
2867 aarg1 = WINED3DTA_TEXTURE;
2868 aop = WINED3DTOP_SELECTARG1;
2870 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2872 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2874 aarg2 = WINED3DTA_TEXTURE;
2875 aop = WINED3DTOP_MODULATE;
2877 else aarg1 = WINED3DTA_TEXTURE;
2879 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2881 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2883 aarg1 = WINED3DTA_TEXTURE;
2884 aop = WINED3DTOP_MODULATE;
2886 else aarg2 = WINED3DTA_TEXTURE;
2892 if (is_invalid_op(&stateblock->state, i, aop, aarg1, aarg2, aarg0))
2896 aarg1 = WINED3DTA_CURRENT;
2897 aop = WINED3DTOP_SELECTARG1;
2900 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
2901 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
2903 ttff = stateblock->state.texture_states[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2904 if (ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3))
2906 settings->op[i].projected = proj_count3;
2907 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2908 settings->op[i].projected = proj_count4;
2910 settings->op[i].projected = proj_none;
2913 settings->op[i].projected = proj_none;
2916 settings->op[i].cop = cop;
2917 settings->op[i].aop = aop;
2918 settings->op[i].carg0 = carg0;
2919 settings->op[i].carg1 = carg1;
2920 settings->op[i].carg2 = carg2;
2921 settings->op[i].aarg0 = aarg0;
2922 settings->op[i].aarg1 = aarg1;
2923 settings->op[i].aarg2 = aarg2;
2925 if (stateblock->state.texture_states[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP)
2927 settings->op[i].dst = tempreg;
2929 settings->op[i].dst = resultreg;
2933 /* Clear unsupported stages */
2934 for(; i < MAX_TEXTURES; i++) {
2935 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2938 if (!stateblock->state.render_states[WINED3DRS_FOGENABLE])
2940 settings->fog = FOG_OFF;
2942 else if (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
2944 if (use_vs(&stateblock->state) || stateblock->state.vertex_declaration->position_transformed)
2946 settings->fog = FOG_LINEAR;
2950 switch (stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE])
2952 case WINED3DFOG_NONE:
2953 case WINED3DFOG_LINEAR:
2954 settings->fog = FOG_LINEAR;
2956 case WINED3DFOG_EXP:
2957 settings->fog = FOG_EXP;
2959 case WINED3DFOG_EXP2:
2960 settings->fog = FOG_EXP2;
2967 switch (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE])
2969 case WINED3DFOG_LINEAR:
2970 settings->fog = FOG_LINEAR;
2972 case WINED3DFOG_EXP:
2973 settings->fog = FOG_EXP;
2975 case WINED3DFOG_EXP2:
2976 settings->fog = FOG_EXP2;
2980 if (stateblock->state.render_states[WINED3DRS_SRGBWRITEENABLE]
2981 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
2983 settings->sRGB_write = 1;
2985 settings->sRGB_write = 0;
2987 if (device->vs_clipping || !use_vs(&stateblock->state) || !stateblock->state.render_states[WINED3DRS_CLIPPING]
2988 || !stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE])
2990 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2991 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2992 * if no clipplane is enabled
2994 settings->emul_clipplanes = 0;
2996 settings->emul_clipplanes = 1;
3000 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3001 const struct ffp_frag_settings *settings)
3003 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3004 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3007 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3009 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3010 * whereas desc points to an extended structure with implementation specific parts. */
3011 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3013 ERR("Failed to insert ffp frag shader.\n");
3017 /* Activates the texture dimension according to the bound D3D texture.
3018 * Does not care for the colorop or correct gl texture unit(when using nvrc)
3019 * Requires the caller to activate the correct unit before
3021 /* GL locking is done by the caller (state handler) */
3022 void texture_activate_dimensions(IWineD3DBaseTextureImpl *texture, const struct wined3d_gl_info *gl_info)
3026 switch (texture->baseTexture.target)
3029 glDisable(GL_TEXTURE_3D);
3030 checkGLcall("glDisable(GL_TEXTURE_3D)");
3031 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3033 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3034 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3036 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3038 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3039 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3041 glEnable(GL_TEXTURE_2D);
3042 checkGLcall("glEnable(GL_TEXTURE_2D)");
3044 case GL_TEXTURE_RECTANGLE_ARB:
3045 glDisable(GL_TEXTURE_2D);
3046 checkGLcall("glDisable(GL_TEXTURE_2D)");
3047 glDisable(GL_TEXTURE_3D);
3048 checkGLcall("glDisable(GL_TEXTURE_3D)");
3049 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3051 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3052 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3054 glEnable(GL_TEXTURE_RECTANGLE_ARB);
3055 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3058 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3060 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3061 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3063 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3065 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3066 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3068 glDisable(GL_TEXTURE_2D);
3069 checkGLcall("glDisable(GL_TEXTURE_2D)");
3070 glEnable(GL_TEXTURE_3D);
3071 checkGLcall("glEnable(GL_TEXTURE_3D)");
3073 case GL_TEXTURE_CUBE_MAP_ARB:
3074 glDisable(GL_TEXTURE_2D);
3075 checkGLcall("glDisable(GL_TEXTURE_2D)");
3076 glDisable(GL_TEXTURE_3D);
3077 checkGLcall("glDisable(GL_TEXTURE_3D)");
3078 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3080 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3081 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3083 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3084 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3088 glEnable(GL_TEXTURE_2D);
3089 checkGLcall("glEnable(GL_TEXTURE_2D)");
3090 glDisable(GL_TEXTURE_3D);
3091 checkGLcall("glDisable(GL_TEXTURE_3D)");
3092 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3094 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3095 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3097 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3099 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3100 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3102 /* Binding textures is done by samplers. A dummy texture will be bound */
3106 /* GL locking is done by the caller (state handler) */
3107 void sampler_texdim(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3109 DWORD sampler = state - STATE_SAMPLER(0);
3110 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3112 /* No need to enable / disable anything here for unused samplers. The tex_colorop
3113 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3114 * will take care of this business
3116 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3117 if (sampler >= stateblock->state.lowest_disabled_stage) return;
3118 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3120 texture_activate_dimensions(stateblock->state.textures[sampler], context->gl_info);
3123 void *wined3d_rb_alloc(size_t size)
3125 return HeapAlloc(GetProcessHeap(), 0, size);
3128 void *wined3d_rb_realloc(void *ptr, size_t size)
3130 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3133 void wined3d_rb_free(void *ptr)
3135 HeapFree(GetProcessHeap(), 0, ptr);
3138 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3140 const struct ffp_frag_settings *ka = key;
3141 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3143 return memcmp(ka, kb, sizeof(*ka));
3146 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3151 ffp_frag_program_key_compare,
3154 UINT wined3d_log2i(UINT32 x)
3156 static const UINT l[] =
3158 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3159 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3160 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3161 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3162 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3163 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3164 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3165 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3166 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3167 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3168 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3169 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3170 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3171 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3172 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3173 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3177 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3180 /* Set the shader type for this device, depending on the given capabilities
3181 * and the user preferences in wined3d_settings. */
3182 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3184 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3186 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3187 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3189 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3190 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3191 * shaders only on this card. */
3192 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3193 else *vs_selected = SHADER_GLSL;
3195 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3196 else *vs_selected = SHADER_NONE;
3198 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3199 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3200 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3201 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3202 else *ps_selected = SHADER_NONE;
3205 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
3206 const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format *src_format,
3207 const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format *dst_format)
3209 static const struct blit_shader * const blitters[] =
3217 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3219 if (blitters[i]->blit_supported(gl_info, blit_op,
3220 src_rect, src_usage, src_pool, src_format,
3221 dst_rect, dst_usage, dst_pool, dst_format))