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