2 * Utility functions for the WineD3D Library
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2008 Henri Verbeet
9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
10 * Copyright 2009-2010 Henri Verbeet for CodeWeavers
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wined3d_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
32 struct StaticPixelFormatDesc
34 enum wined3d_format_id id;
35 DWORD alphaMask, redMask, greenMask, blueMask;
37 short depthSize, stencilSize;
40 /*****************************************************************************
43 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
44 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
45 * high masks do not fit into the 32 bit values needed for ddraw. It is only
46 * used for ddraw mostly, and to figure out if the format has alpha at all, so
47 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
48 * formats are not usable in 2D rendering because ddraw doesn't support them.
50 static const struct StaticPixelFormatDesc formats[] =
52 /* format id alphamask redmask greenmask bluemask bpp depth stencil */
53 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
55 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
56 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
57 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
58 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
59 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
60 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
61 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
62 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
63 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
64 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
65 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
67 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
68 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
69 {WINED3DFMT_R32G32B32_FLOAT, 0x0, 0x0, 0x0, 0x0, 12, 0, 0},
70 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0},
72 {WINED3DFMT_R8G8_SNORM_Cx, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
74 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
75 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
76 {WINED3DFMT_R16G16_SINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
77 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
78 {WINED3DFMT_R16G16B16A16_SINT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
79 /* Palettized formats */
80 {WINED3DFMT_P8_UINT_A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
81 {WINED3DFMT_P8_UINT, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
82 /* Standard ARGB formats. */
83 {WINED3DFMT_B8G8R8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0},
84 {WINED3DFMT_B8G8R8A8_UNORM, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
85 {WINED3DFMT_B8G8R8X8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
86 {WINED3DFMT_B5G6R5_UNORM, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0},
87 {WINED3DFMT_B5G5R5X1_UNORM, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
88 {WINED3DFMT_B5G5R5A1_UNORM, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
89 {WINED3DFMT_B4G4R4A4_UNORM, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
90 {WINED3DFMT_B2G3R3_UNORM, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0},
91 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0},
92 {WINED3DFMT_B2G3R3A8_UNORM, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0},
93 {WINED3DFMT_B4G4R4X4_UNORM, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
94 {WINED3DFMT_R10G10B10A2_UNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
95 {WINED3DFMT_R10G10B10A2_UINT, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
96 {WINED3DFMT_R10G10B10A2_SNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
97 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
98 {WINED3DFMT_R8G8B8A8_UINT, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
99 {WINED3DFMT_R8G8B8X8_UNORM, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
100 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0},
101 {WINED3DFMT_B10G10R10A2_UNORM, 0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0},
102 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0},
104 {WINED3DFMT_L8_UNORM, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
105 {WINED3DFMT_L8A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
106 {WINED3DFMT_L4A4_UNORM, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0},
107 {WINED3DFMT_L16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
108 /* Bump mapping stuff */
109 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
110 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
111 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
112 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
113 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
114 {WINED3DFMT_R10G11B11_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
115 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0},
116 /* Depth stencil formats */
117 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
118 {WINED3DFMT_D32_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
119 {WINED3DFMT_S1_UINT_D15_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 15, 1},
120 {WINED3DFMT_D24_UNORM_S8_UINT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
121 {WINED3DFMT_X8D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 0},
122 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 4},
123 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
124 {WINED3DFMT_D32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
125 {WINED3DFMT_S8_UINT_D24_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
126 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
127 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
128 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
129 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
130 /* Vendor-specific formats */
131 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
132 {WINED3DFMT_NVDB, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
133 {WINED3DFMT_INTZ, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
134 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
135 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
136 {WINED3DFMT_NULL, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
139 struct wined3d_format_base_flags
141 enum wined3d_format_id id;
145 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
146 * still needs to use the correct block based calculation for e.g. the
148 static const struct wined3d_format_base_flags format_base_flags[] =
150 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
151 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
152 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
153 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
156 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
157 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
158 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
159 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
160 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
161 {WINED3DFMT_INTZ, WINED3DFMT_FLAG_FOURCC},
162 {WINED3DFMT_NULL, WINED3DFMT_FLAG_FOURCC},
163 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
164 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
165 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
166 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
171 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
172 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
173 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
174 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
175 {WINED3DFMT_NVDB, WINED3DFMT_FLAG_FOURCC},
176 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
177 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
178 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
179 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
181 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
182 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
184 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
185 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
186 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
189 struct wined3d_format_compression_info
191 enum wined3d_format_id id;
194 UINT block_byte_count;
197 static const struct wined3d_format_compression_info format_compression_info[] =
199 {WINED3DFMT_DXT1, 4, 4, 8},
200 {WINED3DFMT_DXT2, 4, 4, 16},
201 {WINED3DFMT_DXT3, 4, 4, 16},
202 {WINED3DFMT_DXT4, 4, 4, 16},
203 {WINED3DFMT_DXT5, 4, 4, 16},
204 {WINED3DFMT_ATI2N, 4, 4, 16},
207 struct wined3d_format_vertex_info
209 enum wined3d_format_id id;
210 enum wined3d_ffp_emit_idx emit_idx;
211 GLint component_count;
214 GLboolean gl_normalized;
215 unsigned int component_size;
218 static const struct wined3d_format_vertex_info format_vertex_info[] =
220 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
221 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
222 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
223 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
224 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
225 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
226 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
227 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
228 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
229 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
230 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
231 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
232 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
233 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
234 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
235 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
236 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
239 struct wined3d_format_texture_info
241 enum wined3d_format_id id;
243 GLint gl_srgb_internal;
244 GLint gl_rt_internal;
247 unsigned int conv_byte_count;
249 GL_SupportedExt extension;
250 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
253 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
255 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
256 * format+type combination to load it. Thus convert it to A8L8, then load it
257 * with A4L4 internal, but A8L8 format+type
260 const unsigned char *Source;
262 UINT outpitch = pitch * 2;
264 for(y = 0; y < height; y++) {
265 Source = src + y * pitch;
266 Dest = dst + y * outpitch;
267 for (x = 0; x < width; x++ ) {
268 unsigned char color = (*Source++);
269 /* A */ Dest[1] = (color & 0xf0) << 0;
270 /* L */ Dest[0] = (color & 0x0f) << 4;
276 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
281 for(y = 0; y < height; y++)
283 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
284 Source = (const WORD *)(src + y * pitch);
285 for (x = 0; x < width; x++ )
287 short color = (*Source++);
288 unsigned char l = ((color >> 10) & 0xfc);
289 short v = ((color >> 5) & 0x3e);
290 short u = ((color ) & 0x1f);
291 short v_conv = v + 16;
292 short u_conv = u + 16;
294 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
300 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
305 UINT outpitch = (pitch * 3)/2;
307 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
308 * fixed function and shaders without further conversion once the surface is
311 for(y = 0; y < height; y++) {
312 Source = (const WORD *)(src + y * pitch);
313 Dest = dst + y * outpitch;
314 for (x = 0; x < width; x++ ) {
315 short color = (*Source++);
316 unsigned char l = ((color >> 10) & 0xfc);
317 char v = ((color >> 5) & 0x3e);
318 char u = ((color ) & 0x1f);
320 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
321 * and doubles the positive range. Thus shift left only once, gl does the 2nd
322 * shift. GL reads a signed value and converts it into an unsigned value.
324 /* M */ Dest[2] = l << 1;
326 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
327 * from 5 bit values to 8 bit values.
329 /* V */ Dest[1] = v << 3;
330 /* U */ Dest[0] = u << 3;
336 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
341 UINT outpitch = (pitch * 3)/2;
343 for(y = 0; y < height; y++)
345 Source = (const short *)(src + y * pitch);
346 Dest = dst + y * outpitch;
347 for (x = 0; x < width; x++ )
349 LONG color = (*Source++);
350 /* B */ Dest[0] = 0xff;
351 /* G */ Dest[1] = (color >> 8) + 128; /* V */
352 /* R */ Dest[2] = (color) + 128; /* U */
358 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
364 /* Doesn't work correctly with the fixed function pipeline, but can work in
365 * shaders if the shader is adjusted. (There's no use for this format in gl's
366 * standard fixed function pipeline anyway).
368 for(y = 0; y < height; y++)
370 Source = (const DWORD *)(src + y * pitch);
371 Dest = dst + y * pitch;
372 for (x = 0; x < width; x++ )
374 LONG color = (*Source++);
375 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
376 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
377 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
383 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
389 /* This implementation works with the fixed function pipeline and shaders
390 * without further modification after converting the surface.
392 for(y = 0; y < height; y++)
394 Source = (const DWORD *)(src + y * pitch);
395 Dest = dst + y * pitch;
396 for (x = 0; x < width; x++ )
398 LONG color = (*Source++);
399 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
400 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
401 /* U */ Dest[0] = (color & 0xff); /* U */
402 /* I */ Dest[3] = 255; /* X */
408 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
414 for(y = 0; y < height; y++)
416 Source = (const DWORD *)(src + y * pitch);
417 Dest = dst + y * pitch;
418 for (x = 0; x < width; x++ )
420 LONG color = (*Source++);
421 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
422 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
423 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
424 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
430 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
434 unsigned short *Dest;
435 UINT outpitch = (pitch * 3)/2;
437 for(y = 0; y < height; y++)
439 Source = (const DWORD *)(src + y * pitch);
440 Dest = (unsigned short *) (dst + y * outpitch);
441 for (x = 0; x < width; x++ )
443 DWORD color = (*Source++);
444 /* B */ Dest[0] = 0xffff;
445 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
446 /* R */ Dest[2] = (color ) + 32768; /* U */
452 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
457 UINT outpitch = (pitch * 3)/2;
459 for(y = 0; y < height; y++)
461 Source = (const WORD *)(src + y * pitch);
462 Dest = (WORD *) (dst + y * outpitch);
463 for (x = 0; x < width; x++ )
465 WORD green = (*Source++);
466 WORD red = (*Source++);
469 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
470 * shader overwrites it anyway
478 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
483 UINT outpitch = (pitch * 3)/2;
485 for(y = 0; y < height; y++)
487 Source = (const float *)(src + y * pitch);
488 Dest = (float *) (dst + y * outpitch);
489 for (x = 0; x < width; x++ )
491 float green = (*Source++);
492 float red = (*Source++);
501 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
504 UINT outpitch = pitch * 2;
506 for (y = 0; y < height; ++y)
508 const WORD *source = (const WORD *)(src + y * pitch);
509 DWORD *dest = (DWORD *)(dst + y * outpitch);
511 for (x = 0; x < width; ++x)
513 /* The depth data is normalized, so needs to be scaled,
514 * the stencil data isn't. Scale depth data by
515 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
516 WORD d15 = source[x] >> 1;
517 DWORD d24 = (d15 << 9) + (d15 >> 6);
518 dest[x] = (d24 << 8) | (source[x] & 0x1);
523 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
527 for (y = 0; y < height; ++y)
529 const DWORD *source = (const DWORD *)(src + y * pitch);
530 DWORD *dest = (DWORD *)(dst + y * pitch);
532 for (x = 0; x < width; ++x)
534 /* Just need to clear out the X4 part. */
535 dest[x] = source[x] & ~0xf0;
540 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
543 UINT outpitch = pitch * 2;
545 for (y = 0; y < height; ++y)
547 const DWORD *source = (const DWORD *)(src + y * pitch);
548 float *dest_f = (float *)(dst + y * outpitch);
549 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
551 for (x = 0; x < width; ++x)
553 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
554 dest_s[x * 2 + 1] = source[x] & 0xff;
559 static const struct wined3d_format_texture_info format_texture_info[] =
561 /* format id internal srgbInternal rtInternal
566 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
567 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
568 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
569 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
572 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
573 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
574 WINED3DFMT_FLAG_FILTERING,
575 WINED3D_GL_EXT_NONE, NULL},
576 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
577 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
578 WINED3DFMT_FLAG_FILTERING,
579 APPLE_YCBCR_422, NULL},
580 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
581 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
582 WINED3DFMT_FLAG_FILTERING,
583 WINED3D_GL_EXT_NONE, NULL},
584 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
585 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
586 WINED3DFMT_FLAG_FILTERING,
587 APPLE_YCBCR_422, NULL},
588 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
589 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
590 WINED3DFMT_FLAG_FILTERING,
591 WINED3D_GL_EXT_NONE, NULL},
592 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
593 GL_RGBA, GL_UNSIGNED_BYTE, 0,
594 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
595 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
596 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
597 GL_RGBA, GL_UNSIGNED_BYTE, 0,
598 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
599 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
600 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
601 GL_RGBA, GL_UNSIGNED_BYTE, 0,
602 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
603 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
604 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
605 GL_RGBA, GL_UNSIGNED_BYTE, 0,
606 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
607 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
608 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
609 GL_RGBA, GL_UNSIGNED_BYTE, 0,
610 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
611 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
613 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
615 WINED3DFMT_FLAG_RENDERTARGET,
616 ARB_TEXTURE_FLOAT, NULL},
617 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
619 WINED3DFMT_FLAG_RENDERTARGET,
620 ARB_TEXTURE_RG, NULL},
621 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
622 GL_RGB, GL_FLOAT, 12,
623 WINED3DFMT_FLAG_RENDERTARGET,
624 ARB_TEXTURE_FLOAT, &convert_r32g32_float},
625 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
627 WINED3DFMT_FLAG_RENDERTARGET,
628 ARB_TEXTURE_RG, NULL},
629 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
630 GL_RGBA, GL_FLOAT, 0,
631 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
632 ARB_TEXTURE_FLOAT, NULL},
634 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
635 GL_RED, GL_HALF_FLOAT_ARB, 0,
636 WINED3DFMT_FLAG_RENDERTARGET,
637 ARB_TEXTURE_FLOAT, NULL},
638 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
639 GL_RED, GL_HALF_FLOAT_ARB, 0,
640 WINED3DFMT_FLAG_RENDERTARGET,
641 ARB_TEXTURE_RG, NULL},
642 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
643 GL_RGB, GL_HALF_FLOAT_ARB, 6,
644 WINED3DFMT_FLAG_RENDERTARGET,
645 ARB_TEXTURE_FLOAT, &convert_r16g16},
646 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
647 GL_RG, GL_HALF_FLOAT_ARB, 0,
648 WINED3DFMT_FLAG_RENDERTARGET,
649 ARB_TEXTURE_RG, NULL},
650 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
651 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
652 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
653 ARB_TEXTURE_FLOAT, NULL},
654 /* Palettized formats */
655 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
656 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
658 ARB_FRAGMENT_PROGRAM, NULL},
659 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
660 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
662 EXT_PALETTED_TEXTURE, NULL},
663 /* Standard ARGB formats */
664 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
665 GL_BGR, GL_UNSIGNED_BYTE, 0,
666 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
667 WINED3D_GL_EXT_NONE, NULL},
668 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
669 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
670 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
671 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
672 WINED3D_GL_EXT_NONE, NULL},
673 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
674 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
675 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
676 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
677 WINED3D_GL_EXT_NONE, NULL},
678 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
679 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
680 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
681 WINED3D_GL_EXT_NONE, NULL},
682 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
683 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
684 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
685 WINED3D_GL_EXT_NONE, NULL},
686 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
687 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
688 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
689 WINED3D_GL_EXT_NONE, NULL},
690 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
691 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
692 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
693 WINED3D_GL_EXT_NONE, NULL},
694 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
695 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
696 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
697 WINED3D_GL_EXT_NONE, NULL},
698 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
699 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
700 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
701 WINED3D_GL_EXT_NONE, NULL},
702 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
703 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
704 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
705 WINED3D_GL_EXT_NONE, NULL},
706 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
707 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
708 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
709 WINED3D_GL_EXT_NONE, NULL},
710 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
711 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
712 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
713 WINED3D_GL_EXT_NONE, NULL},
714 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
715 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
716 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
717 WINED3D_GL_EXT_NONE, NULL},
718 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
719 GL_RGB, GL_UNSIGNED_SHORT, 6,
720 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
721 WINED3D_GL_EXT_NONE, &convert_r16g16},
722 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
723 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
724 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
725 WINED3D_GL_EXT_NONE, NULL},
726 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
727 GL_RGBA, GL_UNSIGNED_SHORT, 0,
728 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
729 WINED3D_GL_EXT_NONE, NULL},
731 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
732 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
733 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
734 WINED3D_GL_EXT_NONE, NULL},
735 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
736 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
737 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
738 WINED3D_GL_EXT_NONE, NULL},
739 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
740 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
742 WINED3D_GL_EXT_NONE, &convert_l4a4_unorm},
743 /* Bump mapping stuff */
744 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
745 GL_BGR, GL_UNSIGNED_BYTE, 3,
746 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
747 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm},
748 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
749 GL_DSDT_NV, GL_BYTE, 0,
750 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
751 NV_TEXTURE_SHADER, NULL},
752 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
753 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
754 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
755 WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm},
756 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
757 GL_DSDT_MAG_NV, GL_BYTE, 3,
758 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
759 NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv},
760 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
761 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
762 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
763 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm},
764 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
765 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
766 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
767 NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv},
768 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
769 GL_BGRA, GL_UNSIGNED_BYTE, 4,
770 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
771 WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm},
772 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
774 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
775 NV_TEXTURE_SHADER, NULL},
776 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
777 GL_BGR, GL_UNSIGNED_SHORT, 6,
778 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
779 WINED3D_GL_EXT_NONE, &convert_r16g16_snorm},
780 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
781 GL_HILO_NV, GL_SHORT, 0,
782 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
783 NV_TEXTURE_SHADER, NULL},
784 /* Depth stencil formats */
785 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
786 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
787 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
788 ARB_DEPTH_TEXTURE, NULL},
789 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
790 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
791 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
792 ARB_DEPTH_TEXTURE, NULL},
793 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
794 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
795 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
796 ARB_DEPTH_TEXTURE, NULL},
797 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
798 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
799 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
800 EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm},
801 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
802 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
803 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
804 ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm},
805 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
806 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
807 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
808 | WINED3DFMT_FLAG_SHADOW,
809 ARB_DEPTH_TEXTURE, NULL},
810 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
811 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
812 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
813 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
814 EXT_PACKED_DEPTH_STENCIL, NULL},
815 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
816 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
817 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
818 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
819 ARB_FRAMEBUFFER_OBJECT, NULL},
820 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
821 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
822 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
823 | WINED3DFMT_FLAG_SHADOW,
824 ARB_DEPTH_TEXTURE, NULL},
825 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
826 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
827 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
828 ARB_DEPTH_TEXTURE, NULL},
829 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
830 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
831 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
832 EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm},
833 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
834 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
835 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
836 ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm},
837 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
838 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
839 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
840 | WINED3DFMT_FLAG_SHADOW,
841 ARB_DEPTH_TEXTURE, NULL},
842 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
843 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
844 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
845 WINED3D_GL_EXT_NONE, NULL},
846 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
847 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
848 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
849 ARB_DEPTH_BUFFER_FLOAT, NULL},
850 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
851 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
852 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
853 ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float},
854 /* Vendor-specific formats */
855 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
856 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
857 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
858 ATI_TEXTURE_COMPRESSION_3DC, NULL},
859 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2, GL_COMPRESSED_RED_GREEN_RGTC2, 0,
860 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
861 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
862 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
863 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
864 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
865 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
866 | WINED3DFMT_FLAG_STENCIL,
867 EXT_PACKED_DEPTH_STENCIL, NULL},
868 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
869 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
870 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
871 | WINED3DFMT_FLAG_STENCIL,
872 ARB_FRAMEBUFFER_OBJECT, NULL},
873 {WINED3DFMT_NULL, GL_RGBA8, GL_RGBA8, 0,
874 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
875 WINED3DFMT_FLAG_RENDERTARGET,
876 ARB_FRAMEBUFFER_OBJECT, NULL},
879 static inline int getFmtIdx(enum wined3d_format_id format_id)
881 /* First check if the format is at the position of its value.
882 * This will catch the argb formats before the loop is entered. */
883 if (format_id < (sizeof(formats) / sizeof(*formats))
884 && formats[format_id].id == format_id)
892 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
894 if (formats[i].id == format_id) return i;
900 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
902 UINT format_count = sizeof(formats) / sizeof(*formats);
905 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
906 if (!gl_info->formats)
908 ERR("Failed to allocate memory.\n");
912 for (i = 0; i < format_count; ++i)
914 struct wined3d_format *format = &gl_info->formats[i];
915 format->id = formats[i].id;
916 format->red_mask = formats[i].redMask;
917 format->green_mask = formats[i].greenMask;
918 format->blue_mask = formats[i].blueMask;
919 format->alpha_mask = formats[i].alphaMask;
920 format->byte_count = formats[i].bpp;
921 format->depth_size = formats[i].depthSize;
922 format->stencil_size = formats[i].stencilSize;
925 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
927 int fmt_idx = getFmtIdx(format_base_flags[i].id);
931 ERR("Format %s (%#x) not found.\n",
932 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
933 HeapFree(GetProcessHeap(), 0, gl_info->formats);
937 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
943 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
947 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
949 struct wined3d_format *format;
950 int fmt_idx = getFmtIdx(format_compression_info[i].id);
954 ERR("Format %s (%#x) not found.\n",
955 debug_d3dformat(format_compression_info[i].id), format_compression_info[i].id);
959 format = &gl_info->formats[fmt_idx];
960 format->block_width = format_compression_info[i].block_width;
961 format->block_height = format_compression_info[i].block_height;
962 format->block_byte_count = format_compression_info[i].block_byte_count;
963 format->flags |= WINED3DFMT_FLAG_COMPRESSED;
969 /* Context activation is done by the caller. */
970 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
972 /* Check if the default internal format is supported as a frame buffer
973 * target, otherwise fall back to the render target internal.
975 * Try to stick to the standard format if possible, this limits precision differences. */
984 glGenTextures(1, &tex);
985 glBindTexture(GL_TEXTURE_2D, tex);
987 glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
988 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
989 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
991 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
993 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
994 checkGLcall("Framebuffer format check");
996 if (status == GL_FRAMEBUFFER_COMPLETE)
998 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
999 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1000 format->rtInternal = format->glInternal;
1004 if (!format->rtInternal)
1006 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1008 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1009 " and no fallback specified.\n", debug_d3dformat(format->id));
1010 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1014 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1016 format->rtInternal = format->glInternal;
1020 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1021 debug_d3dformat(format->id));
1023 while(glGetError());
1025 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1027 glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1028 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1029 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1031 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1033 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1034 checkGLcall("Framebuffer format check");
1036 if (status == GL_FRAMEBUFFER_COMPLETE)
1038 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1039 debug_d3dformat(format->id));
1043 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1044 debug_d3dformat(format->id));
1045 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1050 if (status == GL_FRAMEBUFFER_COMPLETE && format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1054 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1055 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1057 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1058 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1059 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1060 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1061 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1062 checkGLcall("RB attachment");
1066 glClear(GL_COLOR_BUFFER_BIT);
1067 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1069 while(glGetError());
1070 TRACE("Format doesn't support post-pixelshader blending.\n");
1071 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1074 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1075 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1077 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1078 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1079 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1080 checkGLcall("RB cleanup");
1084 if (format->glInternal != format->glGammaInternal)
1086 glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1087 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1089 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1090 checkGLcall("Framebuffer format check");
1092 if (status == GL_FRAMEBUFFER_COMPLETE)
1094 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1095 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1099 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1103 glDeleteTextures(1, &tex);
1108 /* Context activation is done by the caller. */
1109 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1114 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1118 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1119 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1124 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1126 struct wined3d_format *format = &gl_info->formats[i];
1128 if (!format->glInternal) continue;
1130 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1132 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1133 debug_d3dformat(format->id));
1137 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1139 TRACE("Skipping format %s because it's a compressed format.\n",
1140 debug_d3dformat(format->id));
1144 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1146 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1147 check_fbo_compat(gl_info, format);
1151 format->rtInternal = format->glInternal;
1155 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1159 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1165 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1169 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1171 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1172 struct wined3d_format *format;
1176 ERR("Format %s (%#x) not found.\n",
1177 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1181 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1183 format = &gl_info->formats[fmt_idx];
1185 /* ARB_texture_rg defines floating point formats, but only if
1186 * ARB_texture_float is also supported. */
1187 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1188 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1191 format->glInternal = format_texture_info[i].gl_internal;
1192 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1193 format->rtInternal = format_texture_info[i].gl_rt_internal;
1194 format->glFormat = format_texture_info[i].gl_format;
1195 format->glType = format_texture_info[i].gl_type;
1196 format->color_fixup = COLOR_FIXUP_IDENTITY;
1197 format->flags |= format_texture_info[i].flags;
1198 format->heightscale = 1.0f;
1200 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) size *= format->heightscale;
1623 /*****************************************************************************
1624 * Trace formatting of useful values
1626 const char *debug_d3dformat(enum wined3d_format_id format_id)
1630 #define FMT_TO_STR(format_id) case format_id: return #format_id
1631 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1632 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1633 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1634 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1635 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1636 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1637 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1638 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1639 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1640 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1641 FMT_TO_STR(WINED3DFMT_P8_UINT);
1642 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1643 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1644 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1645 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1646 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1647 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1648 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1649 FMT_TO_STR(WINED3DFMT_UYVY);
1650 FMT_TO_STR(WINED3DFMT_YUY2);
1651 FMT_TO_STR(WINED3DFMT_YV12);
1652 FMT_TO_STR(WINED3DFMT_DXT1);
1653 FMT_TO_STR(WINED3DFMT_DXT2);
1654 FMT_TO_STR(WINED3DFMT_DXT3);
1655 FMT_TO_STR(WINED3DFMT_DXT4);
1656 FMT_TO_STR(WINED3DFMT_DXT5);
1657 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1658 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1659 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1660 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1661 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1662 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1663 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1664 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1665 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1666 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1667 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1668 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1669 FMT_TO_STR(WINED3DFMT_ATI2N);
1670 FMT_TO_STR(WINED3DFMT_NVDB);
1671 FMT_TO_STR(WINED3DFMT_NVHU);
1672 FMT_TO_STR(WINED3DFMT_NVHS);
1673 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1674 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1675 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1676 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1677 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1678 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1679 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1680 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1681 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1682 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1683 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1684 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1685 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1686 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1687 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1688 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1689 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1690 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1691 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1692 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1693 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1694 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1695 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1696 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1697 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1698 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1699 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1700 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1701 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1702 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1703 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1704 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1705 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1706 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1707 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1708 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1709 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1710 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1711 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1712 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1713 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1714 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1715 FMT_TO_STR(WINED3DFMT_R32_UINT);
1716 FMT_TO_STR(WINED3DFMT_R32_SINT);
1717 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1718 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1719 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1720 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1721 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1722 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1723 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1724 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1725 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1726 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1727 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1728 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1729 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1730 FMT_TO_STR(WINED3DFMT_R16_UINT);
1731 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1732 FMT_TO_STR(WINED3DFMT_R16_SINT);
1733 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1734 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1735 FMT_TO_STR(WINED3DFMT_R8_UINT);
1736 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1737 FMT_TO_STR(WINED3DFMT_R8_SINT);
1738 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1739 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1740 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1741 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1742 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1743 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1744 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1745 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1746 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1747 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1748 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1749 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1750 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1751 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1752 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1753 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1754 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1755 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1756 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1757 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1758 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1759 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1760 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1761 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1762 FMT_TO_STR(WINED3DFMT_INTZ);
1763 FMT_TO_STR(WINED3DFMT_NULL);
1768 fourcc[0] = (char)(format_id);
1769 fourcc[1] = (char)(format_id >> 8);
1770 fourcc[2] = (char)(format_id >> 16);
1771 fourcc[3] = (char)(format_id >> 24);
1773 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1774 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1776 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1778 return "unrecognized";
1782 const char *debug_d3ddevicetype(WINED3DDEVTYPE devtype)
1786 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1787 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1788 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1789 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1790 #undef DEVTYPE_TO_STR
1792 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1793 return "unrecognized";
1797 const char *debug_d3dusage(DWORD usage)
1802 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1803 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1804 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1805 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1806 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1807 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1808 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1809 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1810 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1811 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1812 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1813 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1814 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1815 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1816 #undef WINED3DUSAGE_TO_STR
1817 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1819 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1822 const char *debug_d3dusagequery(DWORD usagequery)
1827 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1828 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1829 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1830 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1831 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1832 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1833 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1834 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1835 #undef WINED3DUSAGEQUERY_TO_STR
1836 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1838 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1841 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1843 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1844 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1845 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1846 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1847 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1848 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1849 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1850 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1851 #undef WINED3DDECLMETHOD_TO_STR
1853 FIXME("Unrecognized %u declaration method!\n", method);
1854 return "unrecognized";
1858 const char* debug_d3ddeclusage(BYTE usage) {
1860 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1861 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1862 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1863 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1864 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1865 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1866 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1867 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1868 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1869 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1870 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1871 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1872 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1873 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1874 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1875 #undef WINED3DDECLUSAGE_TO_STR
1877 FIXME("Unrecognized %u declaration usage!\n", usage);
1878 return "unrecognized";
1882 const char *debug_d3dresourcetype(WINED3DRESOURCETYPE res)
1886 #define RES_TO_STR(res) case res: return #res
1887 RES_TO_STR(WINED3DRTYPE_SURFACE);
1888 RES_TO_STR(WINED3DRTYPE_VOLUME);
1889 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1890 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1891 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1892 RES_TO_STR(WINED3DRTYPE_BUFFER);
1895 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1896 return "unrecognized";
1900 const char *debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType)
1902 switch (PrimitiveType)
1904 #define PRIM_TO_STR(prim) case prim: return #prim
1905 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1906 PRIM_TO_STR(WINED3DPT_POINTLIST);
1907 PRIM_TO_STR(WINED3DPT_LINELIST);
1908 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1909 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1910 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1911 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1912 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1913 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1914 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1915 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1918 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1919 return "unrecognized";
1923 const char *debug_d3drenderstate(WINED3DRENDERSTATETYPE state)
1927 #define D3DSTATE_TO_STR(u) case u: return #u
1928 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS);
1929 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE);
1930 D3DSTATE_TO_STR(WINED3DRS_WRAPU);
1931 D3DSTATE_TO_STR(WINED3DRS_WRAPV);
1932 D3DSTATE_TO_STR(WINED3DRS_ZENABLE);
1933 D3DSTATE_TO_STR(WINED3DRS_FILLMODE);
1934 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE);
1935 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN);
1936 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE);
1937 D3DSTATE_TO_STR(WINED3DRS_ROP2);
1938 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK);
1939 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE);
1940 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE);
1941 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL);
1942 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND);
1943 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND);
1944 D3DSTATE_TO_STR(WINED3DRS_CULLMODE);
1945 D3DSTATE_TO_STR(WINED3DRS_ZFUNC);
1946 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF);
1947 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC);
1948 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE);
1949 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE);
1950 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE);
1951 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE);
1952 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE);
1953 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL);
1954 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX);
1955 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA);
1956 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR);
1957 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE);
1958 D3DSTATE_TO_STR(WINED3DRS_FOGSTART);
1959 D3DSTATE_TO_STR(WINED3DRS_FOGEND);
1960 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY);
1961 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE);
1962 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS);
1963 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE);
1964 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS);
1965 D3DSTATE_TO_STR(WINED3DRS_ZBIAS);
1966 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE);
1967 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY);
1968 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH);
1969 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1970 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE);
1971 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL);
1972 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL);
1973 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS);
1974 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC);
1975 D3DSTATE_TO_STR(WINED3DRS_STENCILREF);
1976 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK);
1977 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK);
1978 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR);
1979 D3DSTATE_TO_STR(WINED3DRS_WRAP0);
1980 D3DSTATE_TO_STR(WINED3DRS_WRAP1);
1981 D3DSTATE_TO_STR(WINED3DRS_WRAP2);
1982 D3DSTATE_TO_STR(WINED3DRS_WRAP3);
1983 D3DSTATE_TO_STR(WINED3DRS_WRAP4);
1984 D3DSTATE_TO_STR(WINED3DRS_WRAP5);
1985 D3DSTATE_TO_STR(WINED3DRS_WRAP6);
1986 D3DSTATE_TO_STR(WINED3DRS_WRAP7);
1987 D3DSTATE_TO_STR(WINED3DRS_CLIPPING);
1988 D3DSTATE_TO_STR(WINED3DRS_LIGHTING);
1989 D3DSTATE_TO_STR(WINED3DRS_EXTENTS);
1990 D3DSTATE_TO_STR(WINED3DRS_AMBIENT);
1991 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE);
1992 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX);
1993 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER);
1994 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS);
1995 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE);
1996 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE);
1997 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE);
1998 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE);
1999 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE);
2000 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND);
2001 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE);
2002 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING);
2003 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE);
2004 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN);
2005 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE);
2006 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE);
2007 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A);
2008 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B);
2009 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C);
2010 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS);
2011 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK);
2012 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE);
2013 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS);
2014 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN);
2015 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX);
2016 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE);
2017 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE);
2018 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR);
2019 D3DSTATE_TO_STR(WINED3DRS_BLENDOP);
2020 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE);
2021 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE);
2022 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE);
2023 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS);
2024 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE);
2025 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL);
2026 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL);
2027 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X);
2028 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y);
2029 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z);
2030 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W);
2031 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
2032 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE);
2033 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL);
2034 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL);
2035 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS);
2036 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC);
2037 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1);
2038 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2);
2039 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3);
2040 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR);
2041 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE);
2042 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS);
2043 D3DSTATE_TO_STR(WINED3DRS_WRAP8);
2044 D3DSTATE_TO_STR(WINED3DRS_WRAP9);
2045 D3DSTATE_TO_STR(WINED3DRS_WRAP10);
2046 D3DSTATE_TO_STR(WINED3DRS_WRAP11);
2047 D3DSTATE_TO_STR(WINED3DRS_WRAP12);
2048 D3DSTATE_TO_STR(WINED3DRS_WRAP13);
2049 D3DSTATE_TO_STR(WINED3DRS_WRAP14);
2050 D3DSTATE_TO_STR(WINED3DRS_WRAP15);
2051 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE);
2052 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA);
2053 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA);
2054 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA);
2055 #undef D3DSTATE_TO_STR
2057 FIXME("Unrecognized %u render state!\n", state);
2058 return "unrecognized";
2062 const char *debug_d3dsamplerstate(DWORD state)
2066 #define D3DSTATE_TO_STR(u) case u: return #u
2067 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR);
2068 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU);
2069 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV);
2070 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW);
2071 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER);
2072 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER);
2073 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER);
2074 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
2075 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL);
2076 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
2077 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE);
2078 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX);
2079 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET);
2080 #undef D3DSTATE_TO_STR
2082 FIXME("Unrecognized %u sampler state!\n", state);
2083 return "unrecognized";
2087 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2088 switch (filter_type) {
2089 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2090 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2091 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2092 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2093 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2094 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2095 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2096 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2097 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2098 #undef D3DTEXTUREFILTERTYPE_TO_STR
2100 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2101 return "unrecognized";
2105 const char *debug_d3dtexturestate(DWORD state)
2109 #define D3DSTATE_TO_STR(u) case u: return #u
2110 D3DSTATE_TO_STR(WINED3DTSS_COLOROP);
2111 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1);
2112 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2);
2113 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP);
2114 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1);
2115 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2);
2116 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00);
2117 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01);
2118 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10);
2119 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11);
2120 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX);
2121 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE);
2122 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET);
2123 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS);
2124 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0);
2125 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0);
2126 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG);
2127 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT);
2128 #undef D3DSTATE_TO_STR
2130 FIXME("Unrecognized %u texture state!\n", state);
2131 return "unrecognized";
2135 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2137 #define D3DTOP_TO_STR(u) case u: return #u
2138 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2139 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2140 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2141 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2142 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2143 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2144 D3DTOP_TO_STR(WINED3DTOP_ADD);
2145 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2146 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2147 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2148 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2149 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2150 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2151 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2152 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2153 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2154 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2155 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2156 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2157 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2158 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2159 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2160 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2161 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2162 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2163 D3DTOP_TO_STR(WINED3DTOP_LERP);
2164 #undef D3DTOP_TO_STR
2166 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2167 return "unrecognized";
2171 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2173 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2174 TSTYPE_TO_STR(WINED3DTS_VIEW);
2175 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2176 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2177 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2178 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2179 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2180 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2181 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2182 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2183 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2184 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2185 #undef TSTYPE_TO_STR
2187 if (tstype > 256 && tstype < 512) {
2188 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2189 return ("WINED3DTS_WORLDMATRIX > 0");
2191 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2192 return "unrecognized";
2196 const char *debug_d3dstate(DWORD state)
2198 if (STATE_IS_RENDER(state))
2199 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2200 if (STATE_IS_TEXTURESTAGE(state))
2202 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2203 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2204 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2205 texture_stage, debug_d3dtexturestate(texture_state));
2207 if (STATE_IS_SAMPLER(state))
2208 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2209 if (STATE_IS_PIXELSHADER(state))
2210 return "STATE_PIXELSHADER";
2211 if (STATE_IS_TRANSFORM(state))
2212 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2213 if (STATE_IS_STREAMSRC(state))
2214 return "STATE_STREAMSRC";
2215 if (STATE_IS_INDEXBUFFER(state))
2216 return "STATE_INDEXBUFFER";
2217 if (STATE_IS_VDECL(state))
2218 return "STATE_VDECL";
2219 if (STATE_IS_VSHADER(state))
2220 return "STATE_VSHADER";
2221 if (STATE_IS_VIEWPORT(state))
2222 return "STATE_VIEWPORT";
2223 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2224 return "STATE_VERTEXSHADERCONSTANT";
2225 if (STATE_IS_PIXELSHADERCONSTANT(state))
2226 return "STATE_PIXELSHADERCONSTANT";
2227 if (STATE_IS_ACTIVELIGHT(state))
2228 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2229 if (STATE_IS_SCISSORRECT(state))
2230 return "STATE_SCISSORRECT";
2231 if (STATE_IS_CLIPPLANE(state))
2232 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2233 if (STATE_IS_MATERIAL(state))
2234 return "STATE_MATERIAL";
2235 if (STATE_IS_FRONTFACE(state))
2236 return "STATE_FRONTFACE";
2237 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2238 return "STATE_POINTSPRITECOORDORIGIN";
2240 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2243 const char *debug_d3dpool(WINED3DPOOL pool)
2247 #define POOL_TO_STR(p) case p: return #p
2248 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2249 POOL_TO_STR(WINED3DPOOL_MANAGED);
2250 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2251 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2254 FIXME("Unrecognized %u WINED3DPOOL!\n", pool);
2255 return "unrecognized";
2259 const char *debug_fbostatus(GLenum status) {
2261 #define FBOSTATUS_TO_STR(u) case u: return #u
2262 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2263 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2264 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2265 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2266 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2267 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2268 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2269 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2270 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2271 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2272 #undef FBOSTATUS_TO_STR
2274 FIXME("Unrecognied FBO status 0x%08x\n", status);
2275 return "unrecognized";
2279 const char *debug_glerror(GLenum error) {
2281 #define GLERROR_TO_STR(u) case u: return #u
2282 GLERROR_TO_STR(GL_NO_ERROR);
2283 GLERROR_TO_STR(GL_INVALID_ENUM);
2284 GLERROR_TO_STR(GL_INVALID_VALUE);
2285 GLERROR_TO_STR(GL_INVALID_OPERATION);
2286 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2287 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2288 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2289 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2290 #undef GLERROR_TO_STR
2292 FIXME("Unrecognied GL error 0x%08x\n", error);
2293 return "unrecognized";
2297 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2299 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2300 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2301 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2302 default: return "unrecognized";
2306 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2308 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2309 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2310 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2311 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2312 default: return "unrecognized";
2316 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2320 #define WINED3D_TO_STR(x) case x: return #x
2321 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2322 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2323 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2324 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2325 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2326 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2327 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2328 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2329 #undef WINED3D_TO_STR
2331 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2332 return "unrecognized";
2336 static const char *debug_complex_fixup(enum complex_fixup fixup)
2340 #define WINED3D_TO_STR(x) case x: return #x
2341 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2342 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2343 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2344 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2345 #undef WINED3D_TO_STR
2347 FIXME("Unrecognized complex fixup %#x\n", fixup);
2348 return "unrecognized";
2352 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2354 if (is_complex_fixup(fixup))
2356 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2360 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2361 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2362 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2363 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2366 const char *debug_surflocation(DWORD flag) {
2370 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2371 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2372 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2373 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2374 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2377 /*****************************************************************************
2378 * Useful functions mapping GL <-> D3D values
2380 GLenum StencilOp(DWORD op) {
2382 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2383 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2384 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2385 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2386 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2387 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2388 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2389 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2391 FIXME("Unrecognized stencil op %d\n", op);
2396 GLenum CompareFunc(DWORD func) {
2397 switch ((WINED3DCMPFUNC)func) {
2398 case WINED3DCMP_NEVER : return GL_NEVER;
2399 case WINED3DCMP_LESS : return GL_LESS;
2400 case WINED3DCMP_EQUAL : return GL_EQUAL;
2401 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2402 case WINED3DCMP_GREATER : return GL_GREATER;
2403 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2404 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2405 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2407 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2412 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2413 WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
2415 if (op == WINED3DTOP_DISABLE) return FALSE;
2416 if (state->textures[stage]) return FALSE;
2418 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2419 && op != WINED3DTOP_SELECTARG2) return TRUE;
2420 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2421 && op != WINED3DTOP_SELECTARG1) return TRUE;
2422 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2423 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2428 /* Setup this textures matrix according to the texture flags*/
2429 /* GL locking is done by the caller (state handler) */
2430 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2431 enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2435 glMatrixMode(GL_TEXTURE);
2436 checkGLcall("glMatrixMode(GL_TEXTURE)");
2438 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2440 checkGLcall("glLoadIdentity()");
2444 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2445 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2449 memcpy(mat, smat, 16 * sizeof(float));
2451 if (flags & WINED3DTTFF_PROJECTED) {
2452 if(!ffp_proj_control) {
2453 switch (flags & ~WINED3DTTFF_PROJECTED) {
2454 case WINED3DTTFF_COUNT2:
2455 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2456 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2458 case WINED3DTTFF_COUNT3:
2459 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2460 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2464 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2465 if(!calculatedCoords) {
2468 case WINED3DFMT_R32_FLOAT:
2469 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2470 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2471 * the input value to the transformation will be 0, so the matrix value is irrelevant
2478 case WINED3DFMT_R32G32_FLOAT:
2479 /* See above, just 3rd and 4th coord
2486 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2487 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2489 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2490 * into a bad place. The division elimination below will apply to make sure the
2491 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2493 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2496 FIXME("Unexpected fixed function texture coord input\n");
2499 if(!ffp_proj_control) {
2500 switch (flags & ~WINED3DTTFF_PROJECTED) {
2501 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2502 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2503 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2504 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2505 * the 4th coord evaluates to 1.0 to eliminate that.
2507 * If the fixed function pipeline is used, the 4th value remains unused,
2508 * so there is no danger in doing this. With vertex shaders we have a
2509 * problem. Should an app hit that problem, the code here would have to
2510 * check for pixel shaders, and the shader has to undo the default gl divide.
2512 * A more serious problem occurs if the app passes 4 coordinates in, and the
2513 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2514 * or a replacement shader
2516 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2522 checkGLcall("glLoadMatrixf(mat)");
2525 /* This small helper function is used to convert a bitmask into the number of masked bits */
2526 unsigned int count_bits(unsigned int mask)
2529 for (count = 0; mask; ++count)
2536 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2537 * The later function requires individual color components. */
2538 BOOL getColorBits(const struct wined3d_format *format,
2539 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2541 TRACE("format %s.\n", debug_d3dformat(format->id));
2545 case WINED3DFMT_B10G10R10A2_UNORM:
2546 case WINED3DFMT_R10G10B10A2_UNORM:
2547 case WINED3DFMT_B8G8R8X8_UNORM:
2548 case WINED3DFMT_B8G8R8_UNORM:
2549 case WINED3DFMT_B8G8R8A8_UNORM:
2550 case WINED3DFMT_R8G8B8A8_UNORM:
2551 case WINED3DFMT_B5G5R5X1_UNORM:
2552 case WINED3DFMT_B5G5R5A1_UNORM:
2553 case WINED3DFMT_B5G6R5_UNORM:
2554 case WINED3DFMT_B4G4R4X4_UNORM:
2555 case WINED3DFMT_B4G4R4A4_UNORM:
2556 case WINED3DFMT_B2G3R3_UNORM:
2557 case WINED3DFMT_P8_UINT_A8_UNORM:
2558 case WINED3DFMT_P8_UINT:
2561 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2565 *redSize = count_bits(format->red_mask);
2566 *greenSize = count_bits(format->green_mask);
2567 *blueSize = count_bits(format->blue_mask);
2568 *alphaSize = count_bits(format->alpha_mask);
2569 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2571 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2572 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2576 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2577 BOOL getDepthStencilBits(const struct wined3d_format *format, short *depthSize, short *stencilSize)
2579 TRACE("format %s.\n", debug_d3dformat(format->id));
2583 case WINED3DFMT_D16_LOCKABLE:
2584 case WINED3DFMT_D16_UNORM:
2585 case WINED3DFMT_S1_UINT_D15_UNORM:
2586 case WINED3DFMT_X8D24_UNORM:
2587 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2588 case WINED3DFMT_D24_UNORM_S8_UINT:
2589 case WINED3DFMT_S8_UINT_D24_FLOAT:
2590 case WINED3DFMT_D32_UNORM:
2591 case WINED3DFMT_D32_FLOAT:
2592 case WINED3DFMT_INTZ:
2595 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2599 *depthSize = format->depth_size;
2600 *stencilSize = format->stencil_size;
2602 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2603 *depthSize, *stencilSize, debug_d3dformat(format->id));
2607 /* Note: It's the caller's responsibility to ensure values can be expressed
2608 * in the requested format. UNORM formats for example can only express values
2609 * in the range 0.0f -> 1.0f. */
2610 DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, const WINED3DCOLORVALUE *color)
2614 enum wined3d_format_id format_id;
2626 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2627 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2628 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2629 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2630 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2631 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2632 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2633 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2634 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2635 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2636 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2637 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2638 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2639 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2643 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2644 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2646 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2650 if (format->id != conv[i].format_id) continue;
2652 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2653 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2654 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2655 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2657 TRACE("Returning 0x%08x.\n", ret);
2662 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2667 /* DirectDraw stuff */
2668 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2672 case 8: return WINED3DFMT_P8_UINT;
2673 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2674 case 16: return WINED3DFMT_B5G6R5_UNORM;
2675 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2676 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2677 default: return WINED3DFMT_UNKNOWN;
2681 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2684 /* Now do the multiplication 'by hand'.
2685 I know that all this could be optimised, but this will be done later :-) */
2686 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);
2687 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);
2688 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);
2689 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);
2691 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);
2692 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);
2693 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);
2694 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);
2696 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);
2697 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);
2698 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);
2699 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);
2701 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);
2702 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);
2703 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);
2704 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);
2706 /* And copy the new matrix in the good storage.. */
2707 memcpy(dest, &temp, 16 * sizeof(float));
2710 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2713 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2715 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2716 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2717 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2718 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2719 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2720 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2721 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2722 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2723 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2724 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2725 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2726 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2727 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2728 default: ERR("Unexpected position mask\n");
2730 for (i = 0; i < numTextures; i++) {
2731 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2737 void gen_ffp_frag_op(struct wined3d_stateblock *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype)
2742 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2744 /* D3DTOP_DISABLE */ 0,
2745 /* D3DTOP_SELECTARG1 */ ARG1,
2746 /* D3DTOP_SELECTARG2 */ ARG2,
2747 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2748 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2749 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2750 /* D3DTOP_ADD */ ARG1 | ARG2,
2751 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2752 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2753 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2754 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2755 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2756 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2757 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2758 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2759 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2760 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2761 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2762 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2763 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2764 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2765 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2766 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2767 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2768 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2769 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2773 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2774 IWineD3DDeviceImpl *device = stateblock->device;
2775 IWineD3DSurfaceImpl *rt = device->render_targets[0];
2776 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2778 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2780 const struct wined3d_texture *texture;
2782 settings->op[i].padding = 0;
2783 if (stateblock->state.texture_states[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE)
2785 settings->op[i].cop = WINED3DTOP_DISABLE;
2786 settings->op[i].aop = WINED3DTOP_DISABLE;
2787 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2788 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2789 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2790 settings->op[i].dst = resultreg;
2791 settings->op[i].tex_type = tex_1d;
2792 settings->op[i].projected = proj_none;
2797 if ((texture = stateblock->state.textures[i]))
2799 settings->op[i].color_fixup = texture->resource.format->color_fixup;
2802 settings->op[i].tex_type = tex_1d;
2806 switch (texture->target)
2809 settings->op[i].tex_type = tex_1d;
2812 settings->op[i].tex_type = tex_2d;
2815 settings->op[i].tex_type = tex_3d;
2817 case GL_TEXTURE_CUBE_MAP_ARB:
2818 settings->op[i].tex_type = tex_cube;
2820 case GL_TEXTURE_RECTANGLE_ARB:
2821 settings->op[i].tex_type = tex_rect;
2826 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2827 settings->op[i].tex_type = tex_1d;
2830 cop = stateblock->state.texture_states[i][WINED3DTSS_COLOROP];
2831 aop = stateblock->state.texture_states[i][WINED3DTSS_ALPHAOP];
2833 carg1 = (args[cop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2834 carg2 = (args[cop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2835 carg0 = (args[cop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2837 if (is_invalid_op(&stateblock->state, i, cop, carg1, carg2, carg0))
2841 carg1 = WINED3DTA_CURRENT;
2842 cop = WINED3DTOP_SELECTARG1;
2845 if(cop == WINED3DTOP_DOTPRODUCT3) {
2846 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2847 * the color result to the alpha component of the destination
2856 aarg1 = (args[aop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2857 aarg2 = (args[aop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2858 aarg0 = (args[aop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2861 if (!i && stateblock->state.textures[0] && stateblock->state.render_states[WINED3DRS_COLORKEYENABLE])
2863 GLenum texture_dimensions;
2865 texture = stateblock->state.textures[0];
2866 texture_dimensions = texture->target;
2868 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2870 IWineD3DSurfaceImpl *surf = surface_from_resource(texture->sub_resources[0]);
2872 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
2874 if (aop == WINED3DTOP_DISABLE)
2876 aarg1 = WINED3DTA_TEXTURE;
2877 aop = WINED3DTOP_SELECTARG1;
2879 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2881 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2883 aarg2 = WINED3DTA_TEXTURE;
2884 aop = WINED3DTOP_MODULATE;
2886 else aarg1 = WINED3DTA_TEXTURE;
2888 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2890 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2892 aarg1 = WINED3DTA_TEXTURE;
2893 aop = WINED3DTOP_MODULATE;
2895 else aarg2 = WINED3DTA_TEXTURE;
2901 if (is_invalid_op(&stateblock->state, i, aop, aarg1, aarg2, aarg0))
2905 aarg1 = WINED3DTA_CURRENT;
2906 aop = WINED3DTOP_SELECTARG1;
2909 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
2910 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
2912 ttff = stateblock->state.texture_states[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2913 if (ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3))
2915 settings->op[i].projected = proj_count3;
2916 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2917 settings->op[i].projected = proj_count4;
2919 settings->op[i].projected = proj_none;
2922 settings->op[i].projected = proj_none;
2925 settings->op[i].cop = cop;
2926 settings->op[i].aop = aop;
2927 settings->op[i].carg0 = carg0;
2928 settings->op[i].carg1 = carg1;
2929 settings->op[i].carg2 = carg2;
2930 settings->op[i].aarg0 = aarg0;
2931 settings->op[i].aarg1 = aarg1;
2932 settings->op[i].aarg2 = aarg2;
2934 if (stateblock->state.texture_states[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP)
2936 settings->op[i].dst = tempreg;
2938 settings->op[i].dst = resultreg;
2942 /* Clear unsupported stages */
2943 for(; i < MAX_TEXTURES; i++) {
2944 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2947 if (!stateblock->state.render_states[WINED3DRS_FOGENABLE])
2949 settings->fog = FOG_OFF;
2951 else if (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
2953 if (use_vs(&stateblock->state) || stateblock->state.vertex_declaration->position_transformed)
2955 settings->fog = FOG_LINEAR;
2959 switch (stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE])
2961 case WINED3DFOG_NONE:
2962 case WINED3DFOG_LINEAR:
2963 settings->fog = FOG_LINEAR;
2965 case WINED3DFOG_EXP:
2966 settings->fog = FOG_EXP;
2968 case WINED3DFOG_EXP2:
2969 settings->fog = FOG_EXP2;
2976 switch (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE])
2978 case WINED3DFOG_LINEAR:
2979 settings->fog = FOG_LINEAR;
2981 case WINED3DFOG_EXP:
2982 settings->fog = FOG_EXP;
2984 case WINED3DFOG_EXP2:
2985 settings->fog = FOG_EXP2;
2989 if (stateblock->state.render_states[WINED3DRS_SRGBWRITEENABLE]
2990 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
2992 settings->sRGB_write = 1;
2994 settings->sRGB_write = 0;
2996 if (device->vs_clipping || !use_vs(&stateblock->state) || !stateblock->state.render_states[WINED3DRS_CLIPPING]
2997 || !stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE])
2999 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3000 * the fixed function vertex pipeline is used(which always supports clipplanes), or
3001 * if no clipplane is enabled
3003 settings->emul_clipplanes = 0;
3005 settings->emul_clipplanes = 1;
3009 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3010 const struct ffp_frag_settings *settings)
3012 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3013 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3016 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3018 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3019 * whereas desc points to an extended structure with implementation specific parts. */
3020 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3022 ERR("Failed to insert ffp frag shader.\n");
3026 /* Activates the texture dimension according to the bound D3D texture.
3027 * Does not care for the colorop or correct gl texture unit(when using nvrc)
3028 * Requires the caller to activate the correct unit before
3030 /* GL locking is done by the caller (state handler) */
3031 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3035 switch (texture->target)
3038 glDisable(GL_TEXTURE_3D);
3039 checkGLcall("glDisable(GL_TEXTURE_3D)");
3040 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3042 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3043 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3045 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3047 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3048 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3050 glEnable(GL_TEXTURE_2D);
3051 checkGLcall("glEnable(GL_TEXTURE_2D)");
3053 case GL_TEXTURE_RECTANGLE_ARB:
3054 glDisable(GL_TEXTURE_2D);
3055 checkGLcall("glDisable(GL_TEXTURE_2D)");
3056 glDisable(GL_TEXTURE_3D);
3057 checkGLcall("glDisable(GL_TEXTURE_3D)");
3058 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3060 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3061 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3063 glEnable(GL_TEXTURE_RECTANGLE_ARB);
3064 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3067 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3069 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3070 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3072 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3074 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3075 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3077 glDisable(GL_TEXTURE_2D);
3078 checkGLcall("glDisable(GL_TEXTURE_2D)");
3079 glEnable(GL_TEXTURE_3D);
3080 checkGLcall("glEnable(GL_TEXTURE_3D)");
3082 case GL_TEXTURE_CUBE_MAP_ARB:
3083 glDisable(GL_TEXTURE_2D);
3084 checkGLcall("glDisable(GL_TEXTURE_2D)");
3085 glDisable(GL_TEXTURE_3D);
3086 checkGLcall("glDisable(GL_TEXTURE_3D)");
3087 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3089 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3090 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3092 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3093 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3097 glEnable(GL_TEXTURE_2D);
3098 checkGLcall("glEnable(GL_TEXTURE_2D)");
3099 glDisable(GL_TEXTURE_3D);
3100 checkGLcall("glDisable(GL_TEXTURE_3D)");
3101 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3103 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3104 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3106 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3108 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3109 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3111 /* Binding textures is done by samplers. A dummy texture will be bound */
3115 /* GL locking is done by the caller (state handler) */
3116 void sampler_texdim(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3118 DWORD sampler = state - STATE_SAMPLER(0);
3119 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3121 /* No need to enable / disable anything here for unused samplers. The tex_colorop
3122 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3123 * will take care of this business
3125 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3126 if (sampler >= stateblock->state.lowest_disabled_stage) return;
3127 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3129 texture_activate_dimensions(stateblock->state.textures[sampler], context->gl_info);
3132 void *wined3d_rb_alloc(size_t size)
3134 return HeapAlloc(GetProcessHeap(), 0, size);
3137 void *wined3d_rb_realloc(void *ptr, size_t size)
3139 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3142 void wined3d_rb_free(void *ptr)
3144 HeapFree(GetProcessHeap(), 0, ptr);
3147 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3149 const struct ffp_frag_settings *ka = key;
3150 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3152 return memcmp(ka, kb, sizeof(*ka));
3155 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3160 ffp_frag_program_key_compare,
3163 UINT wined3d_log2i(UINT32 x)
3165 static const UINT l[] =
3167 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3168 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3169 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3170 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3171 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3172 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3173 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3174 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3175 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3176 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3177 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
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,
3186 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3189 /* Set the shader type for this device, depending on the given capabilities
3190 * and the user preferences in wined3d_settings. */
3191 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3193 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3195 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3196 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3198 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3199 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3200 * shaders only on this card. */
3201 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3202 else *vs_selected = SHADER_GLSL;
3204 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3205 else *vs_selected = SHADER_NONE;
3207 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3208 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3209 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3210 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3211 else *ps_selected = SHADER_NONE;
3214 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3215 const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format *src_format,
3216 const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format *dst_format)
3218 static const struct blit_shader * const blitters[] =
3226 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3228 if (blitters[i]->blit_supported(gl_info, blit_op,
3229 src_rect, src_usage, src_pool, src_format,
3230 dst_rect, dst_usage, dst_pool, dst_format))