wined3d: Add support for ARB_texture_compression_rgtc.
[wine/hramrach.git] / dlls / wined3d / utils.c
blobf2bb60ee9d4063fa250e1d0623a36c17144a0a4b
1 /*
2 * Utility functions for the WineD3D Library
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2008 Henri Verbeet
9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
10 * Copyright 2009 Henri Verbeet for CodeWeavers
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "config.h"
28 #include "wined3d_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
32 struct StaticPixelFormatDesc
34 WINED3DFORMAT format;
35 DWORD alphaMask, redMask, greenMask, blueMask;
36 UINT bpp;
37 short depthSize, stencilSize;
40 /*****************************************************************************
41 * Pixel format array
43 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
44 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
45 * high masks do not fit into the 32 bit values needed for ddraw. It is only
46 * used for ddraw mostly, and to figure out if the format has alpha at all, so
47 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
48 * formats are not usable in 2D rendering because ddraw doesn't support them.
50 static const struct StaticPixelFormatDesc formats[] =
52 /* WINED3DFORMAT alphamask redmask greenmask bluemask bpp depth stencil */
53 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
54 /* FourCC formats */
55 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
56 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
57 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
58 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
59 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
60 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
61 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
62 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
63 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
64 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
65 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
66 /* IEEE formats */
67 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
68 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
69 {WINED3DFMT_R32G32B32_FLOAT, 0x0, 0x0, 0x0, 0x0, 12, 0, 0},
70 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0},
71 /* Hmm? */
72 {WINED3DFMT_R8G8_SNORM_Cx, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
73 /* Float */
74 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
75 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
76 {WINED3DFMT_R16G16_SINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
77 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
78 {WINED3DFMT_R16G16B16A16_SINT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
79 /* Palettized formats */
80 {WINED3DFMT_P8_UINT_A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
81 {WINED3DFMT_P8_UINT, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
82 /* Standard ARGB formats. */
83 {WINED3DFMT_B8G8R8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0},
84 {WINED3DFMT_B8G8R8A8_UNORM, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
85 {WINED3DFMT_B8G8R8X8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
86 {WINED3DFMT_B5G6R5_UNORM, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0},
87 {WINED3DFMT_B5G5R5X1_UNORM, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
88 {WINED3DFMT_B5G5R5A1_UNORM, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
89 {WINED3DFMT_B4G4R4A4_UNORM, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
90 {WINED3DFMT_B2G3R3_UNORM, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0},
91 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0},
92 {WINED3DFMT_B2G3R3A8_UNORM, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0},
93 {WINED3DFMT_B4G4R4X4_UNORM, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
94 {WINED3DFMT_R10G10B10A2_UNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
95 {WINED3DFMT_R10G10B10A2_UINT, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
96 {WINED3DFMT_R10G10B10A2_SNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
97 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
98 {WINED3DFMT_R8G8B8A8_UINT, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
99 {WINED3DFMT_R8G8B8X8_UNORM, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
100 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0},
101 {WINED3DFMT_B10G10R10A2_UNORM, 0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0},
102 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0},
103 /* Luminance */
104 {WINED3DFMT_L8_UNORM, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
105 {WINED3DFMT_L8A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
106 {WINED3DFMT_L4A4_UNORM, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0},
107 {WINED3DFMT_L16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
108 /* Bump mapping stuff */
109 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
110 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
111 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
112 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
113 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
114 {WINED3DFMT_R10G11B11_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
115 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0},
116 /* Depth stencil formats */
117 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
118 {WINED3DFMT_D32_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
119 {WINED3DFMT_S1_UINT_D15_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 15, 1},
120 {WINED3DFMT_D24_UNORM_S8_UINT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
121 {WINED3DFMT_X8D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 0},
122 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 4},
123 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
124 {WINED3DFMT_D32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
125 {WINED3DFMT_S8_UINT_D24_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
126 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
127 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
128 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
129 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
130 /* Vendor-specific formats */
131 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
132 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
133 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
136 struct wined3d_format_base_flags
138 WINED3DFORMAT format;
139 DWORD flags;
142 static const struct wined3d_format_base_flags format_base_flags[] =
144 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
145 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
146 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
147 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
148 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
149 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
150 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
151 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
152 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
153 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
156 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
157 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
158 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
159 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
160 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
161 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
162 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
163 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
164 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
165 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
166 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC},
167 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
168 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
169 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
170 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
171 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
172 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
173 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
174 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
175 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
176 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
177 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 struct wined3d_format_compression_info
182 WINED3DFORMAT format;
183 UINT block_width;
184 UINT block_height;
185 UINT block_byte_count;
188 static const struct wined3d_format_compression_info format_compression_info[] =
190 {WINED3DFMT_DXT1, 4, 4, 8},
191 {WINED3DFMT_DXT2, 4, 4, 16},
192 {WINED3DFMT_DXT3, 4, 4, 16},
193 {WINED3DFMT_DXT4, 4, 4, 16},
194 {WINED3DFMT_DXT5, 4, 4, 16},
195 {WINED3DFMT_ATI2N, 1, 1, 1},
198 struct wined3d_format_vertex_info
200 WINED3DFORMAT format;
201 enum wined3d_ffp_emit_idx emit_idx;
202 GLint component_count;
203 GLenum gl_vtx_type;
204 GLint gl_vtx_format;
205 GLboolean gl_normalized;
206 unsigned int component_size;
209 static const struct wined3d_format_vertex_info format_vertex_info[] =
211 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
212 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
213 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
214 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
215 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
216 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
217 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
218 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
219 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
220 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
221 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
222 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
223 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
224 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
225 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
226 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
227 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
230 struct wined3d_format_texture_info
232 WINED3DFORMAT format;
233 GLint gl_internal;
234 GLint gl_srgb_internal;
235 GLint gl_rt_internal;
236 GLint gl_format;
237 GLint gl_type;
238 unsigned int conv_byte_count;
239 unsigned int flags;
240 GL_SupportedExt extension;
241 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
244 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
246 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
247 * format+type combination to load it. Thus convert it to A8L8, then load it
248 * with A4L4 internal, but A8L8 format+type
250 unsigned int x, y;
251 const unsigned char *Source;
252 unsigned char *Dest;
253 UINT outpitch = pitch * 2;
255 for(y = 0; y < height; y++) {
256 Source = src + y * pitch;
257 Dest = dst + y * outpitch;
258 for (x = 0; x < width; x++ ) {
259 unsigned char color = (*Source++);
260 /* A */ Dest[1] = (color & 0xf0) << 0;
261 /* L */ Dest[0] = (color & 0x0f) << 4;
262 Dest += 2;
267 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
269 unsigned int x, y;
270 const WORD *Source;
272 for(y = 0; y < height; y++)
274 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
275 Source = (const WORD *)(src + y * pitch);
276 for (x = 0; x < width; x++ )
278 short color = (*Source++);
279 unsigned char l = ((color >> 10) & 0xfc);
280 short v = ((color >> 5) & 0x3e);
281 short u = ((color ) & 0x1f);
282 short v_conv = v + 16;
283 short u_conv = u + 16;
285 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
286 Dest_s += 1;
291 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
293 unsigned int x, y;
294 const WORD *Source;
295 unsigned char *Dest;
296 UINT outpitch = (pitch * 3)/2;
298 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
299 * fixed function and shaders without further conversion once the surface is
300 * loaded
302 for(y = 0; y < height; y++) {
303 Source = (const WORD *)(src + y * pitch);
304 Dest = dst + y * outpitch;
305 for (x = 0; x < width; x++ ) {
306 short color = (*Source++);
307 unsigned char l = ((color >> 10) & 0xfc);
308 char v = ((color >> 5) & 0x3e);
309 char u = ((color ) & 0x1f);
311 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
312 * and doubles the positive range. Thus shift left only once, gl does the 2nd
313 * shift. GL reads a signed value and converts it into an unsigned value.
315 /* M */ Dest[2] = l << 1;
317 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
318 * from 5 bit values to 8 bit values.
320 /* V */ Dest[1] = v << 3;
321 /* U */ Dest[0] = u << 3;
322 Dest += 3;
327 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
329 unsigned int x, y;
330 const short *Source;
331 unsigned char *Dest;
332 UINT outpitch = (pitch * 3)/2;
334 for(y = 0; y < height; y++)
336 Source = (const short *)(src + y * pitch);
337 Dest = dst + y * outpitch;
338 for (x = 0; x < width; x++ )
340 LONG color = (*Source++);
341 /* B */ Dest[0] = 0xff;
342 /* G */ Dest[1] = (color >> 8) + 128; /* V */
343 /* R */ Dest[2] = (color) + 128; /* U */
344 Dest += 3;
349 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
351 unsigned int x, y;
352 const DWORD *Source;
353 unsigned char *Dest;
355 /* Doesn't work correctly with the fixed function pipeline, but can work in
356 * shaders if the shader is adjusted. (There's no use for this format in gl's
357 * standard fixed function pipeline anyway).
359 for(y = 0; y < height; y++)
361 Source = (const DWORD *)(src + y * pitch);
362 Dest = dst + y * pitch;
363 for (x = 0; x < width; x++ )
365 LONG color = (*Source++);
366 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
367 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
368 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
369 Dest += 4;
374 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
376 unsigned int x, y;
377 const DWORD *Source;
378 unsigned char *Dest;
380 /* This implementation works with the fixed function pipeline and shaders
381 * without further modification after converting the surface.
383 for(y = 0; y < height; y++)
385 Source = (const DWORD *)(src + y * pitch);
386 Dest = dst + y * pitch;
387 for (x = 0; x < width; x++ )
389 LONG color = (*Source++);
390 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
391 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
392 /* U */ Dest[0] = (color & 0xff); /* U */
393 /* I */ Dest[3] = 255; /* X */
394 Dest += 4;
399 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
401 unsigned int x, y;
402 const DWORD *Source;
403 unsigned char *Dest;
405 for(y = 0; y < height; y++)
407 Source = (const DWORD *)(src + y * pitch);
408 Dest = dst + y * pitch;
409 for (x = 0; x < width; x++ )
411 LONG color = (*Source++);
412 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
413 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
414 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
415 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
416 Dest += 4;
421 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
423 unsigned int x, y;
424 const DWORD *Source;
425 unsigned short *Dest;
426 UINT outpitch = (pitch * 3)/2;
428 for(y = 0; y < height; y++)
430 Source = (const DWORD *)(src + y * pitch);
431 Dest = (unsigned short *) (dst + y * outpitch);
432 for (x = 0; x < width; x++ )
434 DWORD color = (*Source++);
435 /* B */ Dest[0] = 0xffff;
436 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
437 /* R */ Dest[2] = (color ) + 32768; /* U */
438 Dest += 3;
443 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
445 unsigned int x, y;
446 const WORD *Source;
447 WORD *Dest;
448 UINT outpitch = (pitch * 3)/2;
450 for(y = 0; y < height; y++)
452 Source = (const WORD *)(src + y * pitch);
453 Dest = (WORD *) (dst + y * outpitch);
454 for (x = 0; x < width; x++ )
456 WORD green = (*Source++);
457 WORD red = (*Source++);
458 Dest[0] = green;
459 Dest[1] = red;
460 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
461 * shader overwrites it anyway
463 Dest[2] = 0xffff;
464 Dest += 3;
469 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
471 unsigned int x, y;
472 const float *Source;
473 float *Dest;
474 UINT outpitch = (pitch * 3)/2;
476 for(y = 0; y < height; y++)
478 Source = (const float *)(src + y * pitch);
479 Dest = (float *) (dst + y * outpitch);
480 for (x = 0; x < width; x++ )
482 float green = (*Source++);
483 float red = (*Source++);
484 Dest[0] = green;
485 Dest[1] = red;
486 Dest[2] = 1.0f;
487 Dest += 3;
492 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
494 unsigned int x, y;
495 UINT outpitch = pitch * 2;
497 for (y = 0; y < height; ++y)
499 const WORD *source = (const WORD *)(src + y * pitch);
500 DWORD *dest = (DWORD *)(dst + y * outpitch);
502 for (x = 0; x < width; ++x)
504 /* The depth data is normalized, so needs to be scaled,
505 * the stencil data isn't. Scale depth data by
506 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
507 WORD d15 = source[x] >> 1;
508 DWORD d24 = (d15 << 9) + (d15 >> 6);
509 dest[x] = (d24 << 8) | (source[x] & 0x1);
514 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
516 unsigned int x, y;
518 for (y = 0; y < height; ++y)
520 const DWORD *source = (const DWORD *)(src + y * pitch);
521 DWORD *dest = (DWORD *)(dst + y * pitch);
523 for (x = 0; x < width; ++x)
525 /* Just need to clear out the X4 part. */
526 dest[x] = source[x] & ~0xf0;
531 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
533 unsigned int x, y;
534 UINT outpitch = pitch * 2;
536 for (y = 0; y < height; ++y)
538 const DWORD *source = (const DWORD *)(src + y * pitch);
539 float *dest_f = (float *)(dst + y * outpitch);
540 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
542 for (x = 0; x < width; ++x)
544 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
545 dest_s[x * 2 + 1] = source[x] & 0xff;
550 static const struct wined3d_format_texture_info format_texture_info[] =
552 /* WINED3DFORMAT internal srgbInternal rtInternal
553 format type
554 flags
555 extension */
556 /* FourCC formats */
557 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
558 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
559 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
560 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
561 * endian machine
563 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
564 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
565 WINED3DFMT_FLAG_FILTERING,
566 WINED3D_GL_EXT_NONE, NULL},
567 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
568 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
569 WINED3DFMT_FLAG_FILTERING,
570 APPLE_YCBCR_422, NULL},
571 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
572 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
573 WINED3DFMT_FLAG_FILTERING,
574 WINED3D_GL_EXT_NONE, NULL},
575 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
576 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
577 WINED3DFMT_FLAG_FILTERING,
578 APPLE_YCBCR_422, NULL},
579 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
580 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
581 WINED3DFMT_FLAG_FILTERING,
582 WINED3D_GL_EXT_NONE, NULL},
583 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
584 GL_RGBA, GL_UNSIGNED_BYTE, 0,
585 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
586 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
587 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
588 GL_RGBA, GL_UNSIGNED_BYTE, 0,
589 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
590 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
591 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
592 GL_RGBA, GL_UNSIGNED_BYTE, 0,
593 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
594 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
595 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
596 GL_RGBA, GL_UNSIGNED_BYTE, 0,
597 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
598 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
599 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
600 GL_RGBA, GL_UNSIGNED_BYTE, 0,
601 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
602 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
603 /* IEEE formats */
604 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
605 GL_RED, GL_FLOAT, 0,
606 WINED3DFMT_FLAG_RENDERTARGET,
607 ARB_TEXTURE_FLOAT, NULL},
608 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
609 GL_RED, GL_FLOAT, 0,
610 WINED3DFMT_FLAG_RENDERTARGET,
611 ARB_TEXTURE_RG, NULL},
612 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
613 GL_RGB, GL_FLOAT, 12,
614 WINED3DFMT_FLAG_RENDERTARGET,
615 ARB_TEXTURE_FLOAT, &convert_r32g32_float},
616 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
617 GL_RG, GL_FLOAT, 0,
618 WINED3DFMT_FLAG_RENDERTARGET,
619 ARB_TEXTURE_RG, NULL},
620 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
621 GL_RGBA, GL_FLOAT, 0,
622 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
623 ARB_TEXTURE_FLOAT, NULL},
624 /* Float */
625 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
626 GL_RED, GL_HALF_FLOAT_ARB, 0,
627 WINED3DFMT_FLAG_RENDERTARGET,
628 ARB_TEXTURE_FLOAT, NULL},
629 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
630 GL_RED, GL_HALF_FLOAT_ARB, 0,
631 WINED3DFMT_FLAG_RENDERTARGET,
632 ARB_TEXTURE_RG, NULL},
633 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
634 GL_RGB, GL_HALF_FLOAT_ARB, 6,
635 WINED3DFMT_FLAG_RENDERTARGET,
636 ARB_TEXTURE_FLOAT, &convert_r16g16},
637 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
638 GL_RG, GL_HALF_FLOAT_ARB, 0,
639 WINED3DFMT_FLAG_RENDERTARGET,
640 ARB_TEXTURE_RG, NULL},
641 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
642 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
643 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
644 ARB_TEXTURE_FLOAT, NULL},
645 /* Palettized formats */
646 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
647 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
649 ARB_FRAGMENT_PROGRAM, NULL},
650 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
651 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
653 EXT_PALETTED_TEXTURE, NULL},
654 /* Standard ARGB formats */
655 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
656 GL_BGR, GL_UNSIGNED_BYTE, 0,
657 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
658 WINED3D_GL_EXT_NONE, NULL},
659 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
660 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
661 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
662 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
663 WINED3D_GL_EXT_NONE, NULL},
664 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
665 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
666 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
667 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
668 WINED3D_GL_EXT_NONE, NULL},
669 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
670 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
671 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
672 WINED3D_GL_EXT_NONE, NULL},
673 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
674 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
675 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
676 WINED3D_GL_EXT_NONE, NULL},
677 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
678 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
679 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
680 WINED3D_GL_EXT_NONE, NULL},
681 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
682 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
683 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
684 WINED3D_GL_EXT_NONE, NULL},
685 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
686 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
687 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
688 WINED3D_GL_EXT_NONE, NULL},
689 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
690 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
691 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
692 WINED3D_GL_EXT_NONE, NULL},
693 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
694 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
695 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
696 WINED3D_GL_EXT_NONE, NULL},
697 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
698 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
699 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
700 WINED3D_GL_EXT_NONE, NULL},
701 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
702 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
703 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
704 WINED3D_GL_EXT_NONE, NULL},
705 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
706 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
707 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
708 WINED3D_GL_EXT_NONE, NULL},
709 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
710 GL_RGB, GL_UNSIGNED_SHORT, 6,
711 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
712 WINED3D_GL_EXT_NONE, &convert_r16g16},
713 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
714 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
715 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
716 WINED3D_GL_EXT_NONE, NULL},
717 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
718 GL_RGBA, GL_UNSIGNED_SHORT, 0,
719 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
720 WINED3D_GL_EXT_NONE, NULL},
721 /* Luminance */
722 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
723 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
724 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
725 WINED3D_GL_EXT_NONE, NULL},
726 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
727 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
728 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
729 WINED3D_GL_EXT_NONE, NULL},
730 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
731 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
733 WINED3D_GL_EXT_NONE, &convert_l4a4_unorm},
734 /* Bump mapping stuff */
735 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
736 GL_BGR, GL_UNSIGNED_BYTE, 3,
737 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
738 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm},
739 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
740 GL_DSDT_NV, GL_BYTE, 0,
741 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
742 NV_TEXTURE_SHADER, NULL},
743 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
744 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
745 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
746 WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm},
747 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
748 GL_DSDT_MAG_NV, GL_BYTE, 3,
749 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
750 NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv},
751 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
752 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
753 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
754 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm},
755 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
756 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
757 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
758 NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv},
759 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
760 GL_BGRA, GL_UNSIGNED_BYTE, 4,
761 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
762 WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm},
763 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
764 GL_RGBA, GL_BYTE, 0,
765 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
766 NV_TEXTURE_SHADER, NULL},
767 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
768 GL_BGR, GL_UNSIGNED_SHORT, 6,
769 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
770 WINED3D_GL_EXT_NONE, &convert_r16g16_snorm},
771 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
772 GL_HILO_NV, GL_SHORT, 0,
773 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
774 NV_TEXTURE_SHADER, NULL},
775 /* Depth stencil formats */
776 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
777 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
778 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
779 ARB_DEPTH_TEXTURE, NULL},
780 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
781 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
782 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
783 ARB_DEPTH_TEXTURE, NULL},
784 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
785 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
786 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
787 ARB_DEPTH_TEXTURE, NULL},
788 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
789 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
790 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
791 EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm},
792 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
793 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
794 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
795 ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm},
796 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
797 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
798 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
799 | WINED3DFMT_FLAG_SHADOW,
800 ARB_DEPTH_TEXTURE, NULL},
801 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
802 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
803 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
804 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
805 EXT_PACKED_DEPTH_STENCIL, NULL},
806 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
807 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
808 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
809 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
810 ARB_FRAMEBUFFER_OBJECT, NULL},
811 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
812 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
813 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
814 | WINED3DFMT_FLAG_SHADOW,
815 ARB_DEPTH_TEXTURE, NULL},
816 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
817 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
818 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
819 ARB_DEPTH_TEXTURE, NULL},
820 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
821 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
822 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
823 EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm},
824 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
825 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
826 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
827 ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm},
828 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
829 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
830 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
831 | WINED3DFMT_FLAG_SHADOW,
832 ARB_DEPTH_TEXTURE, NULL},
833 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
834 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
835 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
836 WINED3D_GL_EXT_NONE, NULL},
837 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
838 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
839 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
840 ARB_DEPTH_BUFFER_FLOAT, NULL},
841 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
842 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
843 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
844 ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float},
845 /* Vendor-specific formats */
846 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
847 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
849 ATI_TEXTURE_COMPRESSION_3DC, NULL},
850 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2, GL_COMPRESSED_RED_GREEN_RGTC2, 0,
851 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
853 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
856 static inline int getFmtIdx(WINED3DFORMAT fmt) {
857 /* First check if the format is at the position of its value.
858 * This will catch the argb formats before the loop is entered
860 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
861 return fmt;
862 } else {
863 unsigned int i;
864 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
865 if(formats[i].format == fmt) {
866 return i;
870 return -1;
873 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
875 UINT format_count = sizeof(formats) / sizeof(*formats);
876 UINT i;
878 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->gl_formats));
879 if (!gl_info->gl_formats)
881 ERR("Failed to allocate memory.\n");
882 return FALSE;
885 for (i = 0; i < format_count; ++i)
887 struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
888 desc->format = formats[i].format;
889 desc->red_mask = formats[i].redMask;
890 desc->green_mask = formats[i].greenMask;
891 desc->blue_mask = formats[i].blueMask;
892 desc->alpha_mask = formats[i].alphaMask;
893 desc->byte_count = formats[i].bpp;
894 desc->depth_size = formats[i].depthSize;
895 desc->stencil_size = formats[i].stencilSize;
898 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
900 int fmt_idx = getFmtIdx(format_base_flags[i].format);
902 if (fmt_idx == -1)
904 ERR("Format %s (%#x) not found.\n",
905 debug_d3dformat(format_base_flags[i].format), format_base_flags[i].format);
906 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
907 return FALSE;
910 gl_info->gl_formats[fmt_idx].Flags |= format_base_flags[i].flags;
913 return TRUE;
916 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
918 unsigned int i;
920 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
922 struct wined3d_format_desc *format_desc;
923 int fmt_idx = getFmtIdx(format_compression_info[i].format);
925 if (fmt_idx == -1)
927 ERR("Format %s (%#x) not found.\n",
928 debug_d3dformat(format_compression_info[i].format), format_compression_info[i].format);
929 return FALSE;
932 format_desc = &gl_info->gl_formats[fmt_idx];
933 format_desc->block_width = format_compression_info[i].block_width;
934 format_desc->block_height = format_compression_info[i].block_height;
935 format_desc->block_byte_count = format_compression_info[i].block_byte_count;
936 format_desc->Flags |= WINED3DFMT_FLAG_COMPRESSED;
939 return TRUE;
942 /* Context activation is done by the caller. */
943 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format_desc *format_desc)
945 /* Check if the default internal format is supported as a frame buffer
946 * target, otherwise fall back to the render target internal.
948 * Try to stick to the standard format if possible, this limits precision differences. */
949 GLenum status;
950 GLuint tex;
952 ENTER_GL();
954 while(glGetError());
955 glDisable(GL_BLEND);
957 glGenTextures(1, &tex);
958 glBindTexture(GL_TEXTURE_2D, tex);
960 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glInternal, 16, 16, 0,
961 format_desc->glFormat, format_desc->glType, NULL);
962 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
963 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
965 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
967 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
968 checkGLcall("Framebuffer format check");
970 if (status == GL_FRAMEBUFFER_COMPLETE)
972 TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(format_desc->format));
973 format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
974 format_desc->rtInternal = format_desc->glInternal;
976 else
978 if (!format_desc->rtInternal)
980 if (format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)
982 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
983 " and no fallback specified.\n", debug_d3dformat(format_desc->format));
984 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
986 else
988 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format_desc->format));
990 format_desc->rtInternal = format_desc->glInternal;
992 else
994 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
995 debug_d3dformat(format_desc->format));
997 while(glGetError());
999 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1001 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->rtInternal, 16, 16, 0,
1002 format_desc->glFormat, format_desc->glType, NULL);
1003 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1004 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1006 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1008 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1009 checkGLcall("Framebuffer format check");
1011 if (status == GL_FRAMEBUFFER_COMPLETE)
1013 TRACE("Format %s rtInternal format is supported as FBO color attachment\n",
1014 debug_d3dformat(format_desc->format));
1016 else
1018 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1019 debug_d3dformat(format_desc->format));
1020 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1025 if (status == GL_FRAMEBUFFER_COMPLETE && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1027 GLuint rb;
1029 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1030 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1032 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1033 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1034 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1035 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1036 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1037 checkGLcall("RB attachment");
1040 glEnable(GL_BLEND);
1041 glClear(GL_COLOR_BUFFER_BIT);
1042 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1044 while(glGetError());
1045 TRACE("Format doesn't support post-pixelshader blending.\n");
1046 format_desc->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1049 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1050 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1052 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1053 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1054 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1055 checkGLcall("RB cleanup");
1059 if (format_desc->glInternal != format_desc->glGammaInternal)
1061 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glGammaInternal, 16, 16, 0,
1062 format_desc->glFormat, format_desc->glType, NULL);
1063 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1065 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1066 checkGLcall("Framebuffer format check");
1068 if (status == GL_FRAMEBUFFER_COMPLETE)
1070 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format_desc->format));
1071 format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1073 else
1075 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format_desc->format));
1079 glDeleteTextures(1, &tex);
1081 LEAVE_GL();
1084 /* Context activation is done by the caller. */
1085 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1087 unsigned int i;
1088 GLuint fbo;
1090 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1092 ENTER_GL();
1094 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1095 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1097 LEAVE_GL();
1100 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1102 struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
1104 if (!desc->glInternal) continue;
1106 if (desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1108 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1109 debug_d3dformat(desc->format));
1110 continue;
1113 if (desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
1115 TRACE("Skipping format %s because it's a compressed format.\n",
1116 debug_d3dformat(desc->format));
1117 continue;
1120 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1122 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc->format));
1123 check_fbo_compat(gl_info, desc);
1125 else
1127 desc->rtInternal = desc->glInternal;
1131 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1133 ENTER_GL();
1135 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1137 LEAVE_GL();
1141 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1143 unsigned int i;
1145 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1147 int fmt_idx = getFmtIdx(format_texture_info[i].format);
1148 struct wined3d_format_desc *desc;
1150 if (fmt_idx == -1)
1152 ERR("Format %s (%#x) not found.\n",
1153 debug_d3dformat(format_texture_info[i].format), format_texture_info[i].format);
1154 return FALSE;
1157 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1159 desc = &gl_info->gl_formats[fmt_idx];
1160 desc->glInternal = format_texture_info[i].gl_internal;
1161 desc->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1162 desc->rtInternal = format_texture_info[i].gl_rt_internal;
1163 desc->glFormat = format_texture_info[i].gl_format;
1164 desc->glType = format_texture_info[i].gl_type;
1165 desc->color_fixup = COLOR_FIXUP_IDENTITY;
1166 desc->Flags |= format_texture_info[i].flags;
1167 desc->heightscale = 1.0f;
1169 /* Texture conversion stuff */
1170 desc->convert = format_texture_info[i].convert;
1171 desc->conv_byte_count = format_texture_info[i].conv_byte_count;
1174 return TRUE;
1177 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1179 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1180 c1 >>= 8; c2 >>= 8;
1181 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1182 c1 >>= 8; c2 >>= 8;
1183 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1184 c1 >>= 8; c2 >>= 8;
1185 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1186 return TRUE;
1189 /* A context is provided by the caller */
1190 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1192 GLuint tex, fbo, buffer;
1193 const DWORD data[] = {0x00000000, 0xffffffff};
1194 DWORD readback[16 * 1];
1195 BOOL ret = FALSE;
1197 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1198 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1199 * falling back to software. If this changes in the future this code will get fooled and
1200 * apps might hit the software path due to incorrectly advertised caps.
1202 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1203 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1204 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1207 ENTER_GL();
1208 while(glGetError());
1210 glGenTextures(1, &buffer);
1211 glBindTexture(GL_TEXTURE_2D, buffer);
1212 memset(readback, 0x7e, sizeof(readback));
1213 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1214 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1215 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1216 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1217 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1218 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1220 glGenTextures(1, &tex);
1221 glBindTexture(GL_TEXTURE_2D, tex);
1222 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1223 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1224 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1225 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1226 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1227 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1228 glEnable(GL_TEXTURE_2D);
1230 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1231 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1232 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1233 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1235 glViewport(0, 0, 16, 1);
1236 glDisable(GL_LIGHTING);
1237 glMatrixMode(GL_MODELVIEW);
1238 glLoadIdentity();
1239 glMatrixMode(GL_PROJECTION);
1240 glLoadIdentity();
1242 glClearColor(0, 1, 0, 0);
1243 glClear(GL_COLOR_BUFFER_BIT);
1245 glBegin(GL_TRIANGLE_STRIP);
1246 glTexCoord2f(0.0, 0.0);
1247 glVertex2f(-1.0f, -1.0f);
1248 glTexCoord2f(1.0, 0.0);
1249 glVertex2f(1.0f, -1.0f);
1250 glTexCoord2f(0.0, 1.0);
1251 glVertex2f(-1.0f, 1.0f);
1252 glTexCoord2f(1.0, 1.0);
1253 glVertex2f(1.0f, 1.0f);
1254 glEnd();
1256 glBindTexture(GL_TEXTURE_2D, buffer);
1257 memset(readback, 0x7f, sizeof(readback));
1258 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1259 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1260 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1262 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1263 readback[6], readback[9]);
1264 ret = FALSE;
1266 else
1268 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1269 readback[6], readback[9]);
1270 ret = TRUE;
1273 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1274 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1275 glDeleteTextures(1, &tex);
1276 glDeleteTextures(1, &buffer);
1278 if(glGetError())
1280 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1281 ret = FALSE;
1283 LEAVE_GL();
1284 return ret;
1287 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1289 struct wined3d_format_desc *desc;
1290 unsigned int fmt_idx, i;
1291 WINED3DFORMAT fmts16[] = {
1292 WINED3DFMT_R16_FLOAT,
1293 WINED3DFMT_R16G16_FLOAT,
1294 WINED3DFMT_R16G16B16A16_FLOAT,
1296 BOOL filtered;
1298 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1300 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1301 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1303 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1304 filtered = TRUE;
1306 else if (gl_info->limits.glsl_varyings > 44)
1308 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1309 filtered = TRUE;
1311 else
1313 TRACE("Assuming no float16 blending\n");
1314 filtered = FALSE;
1317 if(filtered)
1319 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1321 fmt_idx = getFmtIdx(fmts16[i]);
1322 gl_info->gl_formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
1325 return;
1328 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1330 fmt_idx = getFmtIdx(fmts16[i]);
1331 desc = &gl_info->gl_formats[fmt_idx];
1332 if(!desc->glInternal) continue; /* Not supported by GL */
1334 filtered = check_filter(gl_info, gl_info->gl_formats[fmt_idx].glInternal);
1335 if(filtered)
1337 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1338 desc->Flags |= WINED3DFMT_FLAG_FILTERING;
1340 else
1342 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1347 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1349 int idx;
1351 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1352 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1353 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1355 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1356 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1357 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1359 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1360 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1361 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1363 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1364 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1365 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1367 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1368 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1369 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1371 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1372 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1373 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1374 * the only driver that implements it(fglrx) has a buggy implementation.
1376 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1377 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1378 * conversion for this format.
1380 if (!gl_info->supported[NV_TEXTURE_SHADER])
1382 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1383 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1384 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1385 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1386 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1387 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1389 else
1391 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1392 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1393 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1395 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1396 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1397 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1400 if (!gl_info->supported[NV_TEXTURE_SHADER])
1402 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1403 * with each other
1405 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1406 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1407 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1408 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1409 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1410 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1411 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1412 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1413 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1415 else
1417 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1418 * are converted at surface loading time, but they do not need any modification in
1419 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1420 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1424 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1426 idx = getFmtIdx(WINED3DFMT_ATI2N);
1427 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1428 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1430 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1432 idx = getFmtIdx(WINED3DFMT_ATI2N);
1433 gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
1434 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1437 if (!gl_info->supported[APPLE_YCBCR_422])
1439 idx = getFmtIdx(WINED3DFMT_YUY2);
1440 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1442 idx = getFmtIdx(WINED3DFMT_UYVY);
1443 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1446 idx = getFmtIdx(WINED3DFMT_YV12);
1447 gl_info->gl_formats[idx].heightscale = 1.5f;
1448 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1450 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1452 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1453 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1456 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1458 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1459 gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
1462 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1464 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1465 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1466 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1467 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1469 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1470 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1474 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1476 unsigned int i;
1478 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1480 struct wined3d_format_desc *format_desc;
1481 int fmt_idx = getFmtIdx(format_vertex_info[i].format);
1483 if (fmt_idx == -1)
1485 ERR("Format %s (%#x) not found.\n",
1486 debug_d3dformat(format_vertex_info[i].format), format_vertex_info[i].format);
1487 return FALSE;
1490 format_desc = &gl_info->gl_formats[fmt_idx];
1491 format_desc->emit_idx = format_vertex_info[i].emit_idx;
1492 format_desc->component_count = format_vertex_info[i].component_count;
1493 format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1494 format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1495 format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
1496 format_desc->component_size = format_vertex_info[i].component_size;
1499 return TRUE;
1502 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1504 if (!init_format_base_info(gl_info)) return FALSE;
1506 if (!init_format_compression_info(gl_info))
1508 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1509 gl_info->gl_formats = NULL;
1510 return FALSE;
1513 return TRUE;
1516 /* Context activation is done by the caller. */
1517 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1519 if (!init_format_base_info(gl_info)) return FALSE;
1521 if (!init_format_compression_info(gl_info)) goto fail;
1522 if (!init_format_texture_info(gl_info)) goto fail;
1523 if (!init_format_vertex_info(gl_info)) goto fail;
1525 apply_format_fixups(gl_info);
1526 init_format_fbo_compat_info(gl_info);
1527 init_format_filter_info(gl_info, vendor);
1529 return TRUE;
1531 fail:
1532 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1533 gl_info->gl_formats = NULL;
1534 return FALSE;
1537 const struct wined3d_format_desc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info)
1539 int idx = getFmtIdx(fmt);
1541 if(idx == -1) {
1542 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
1543 /* Get the caller a valid pointer */
1544 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1547 return &gl_info->gl_formats[idx];
1550 /*****************************************************************************
1551 * Trace formatting of useful values
1553 const char* debug_d3dformat(WINED3DFORMAT fmt) {
1554 switch (fmt) {
1555 #define FMT_TO_STR(fmt) case fmt: return #fmt
1556 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1557 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1558 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1559 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1560 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1561 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1562 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1563 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1564 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1565 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1566 FMT_TO_STR(WINED3DFMT_P8_UINT);
1567 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1568 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1569 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1570 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1571 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1572 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1573 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1574 FMT_TO_STR(WINED3DFMT_UYVY);
1575 FMT_TO_STR(WINED3DFMT_YUY2);
1576 FMT_TO_STR(WINED3DFMT_YV12);
1577 FMT_TO_STR(WINED3DFMT_DXT1);
1578 FMT_TO_STR(WINED3DFMT_DXT2);
1579 FMT_TO_STR(WINED3DFMT_DXT3);
1580 FMT_TO_STR(WINED3DFMT_DXT4);
1581 FMT_TO_STR(WINED3DFMT_DXT5);
1582 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1583 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1584 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1585 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1586 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1587 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1588 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1589 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1590 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1591 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1592 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1593 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1594 FMT_TO_STR(WINED3DFMT_ATI2N);
1595 FMT_TO_STR(WINED3DFMT_NVHU);
1596 FMT_TO_STR(WINED3DFMT_NVHS);
1597 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1598 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1599 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1600 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1601 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1602 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1603 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1604 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1605 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1606 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1607 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1608 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1609 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1610 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1611 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1612 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1613 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1614 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1615 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1616 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1617 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1618 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1619 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1620 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1621 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1622 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1623 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1624 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1625 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1626 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1627 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1628 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1629 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1630 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1631 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1632 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1633 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1634 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1635 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1636 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1637 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1638 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1639 FMT_TO_STR(WINED3DFMT_R32_UINT);
1640 FMT_TO_STR(WINED3DFMT_R32_SINT);
1641 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1642 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1643 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1644 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1645 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1646 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1647 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1648 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1649 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1650 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1651 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1652 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1653 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1654 FMT_TO_STR(WINED3DFMT_R16_UINT);
1655 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1656 FMT_TO_STR(WINED3DFMT_R16_SINT);
1657 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1658 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1659 FMT_TO_STR(WINED3DFMT_R8_UINT);
1660 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1661 FMT_TO_STR(WINED3DFMT_R8_SINT);
1662 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1663 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1664 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1665 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1666 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1667 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1668 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1669 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1670 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1671 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1672 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1673 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1674 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1675 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1676 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1677 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1678 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1679 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1680 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1681 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1682 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1683 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1684 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1685 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1686 #undef FMT_TO_STR
1687 default:
1689 char fourcc[5];
1690 fourcc[0] = (char)(fmt);
1691 fourcc[1] = (char)(fmt >> 8);
1692 fourcc[2] = (char)(fmt >> 16);
1693 fourcc[3] = (char)(fmt >> 24);
1694 fourcc[4] = 0;
1695 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
1696 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
1697 else
1698 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
1700 return "unrecognized";
1704 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
1705 switch (devtype) {
1706 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1707 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1708 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1709 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1710 #undef DEVTYPE_TO_STR
1711 default:
1712 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1713 return "unrecognized";
1717 const char *debug_d3dusage(DWORD usage)
1719 char buf[333];
1721 buf[0] = '\0';
1722 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1723 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1724 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1725 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1726 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1727 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1728 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1729 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1730 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1731 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1732 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1733 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1734 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1735 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1736 #undef WINED3DUSAGE_TO_STR
1737 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1739 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1742 const char *debug_d3dusagequery(DWORD usagequery)
1744 char buf[238];
1746 buf[0] = '\0';
1747 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1748 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1749 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1750 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1751 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1752 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1753 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1754 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1755 #undef WINED3DUSAGEQUERY_TO_STR
1756 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1758 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1761 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1762 switch (method) {
1763 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1764 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1765 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1766 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1767 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1768 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1769 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1770 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1771 #undef WINED3DDECLMETHOD_TO_STR
1772 default:
1773 FIXME("Unrecognized %u declaration method!\n", method);
1774 return "unrecognized";
1778 const char* debug_d3ddeclusage(BYTE usage) {
1779 switch (usage) {
1780 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1781 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1782 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1783 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1784 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1785 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1786 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1787 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1788 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1789 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1790 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1791 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1792 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1793 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1794 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1795 #undef WINED3DDECLUSAGE_TO_STR
1796 default:
1797 FIXME("Unrecognized %u declaration usage!\n", usage);
1798 return "unrecognized";
1802 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1803 switch (res) {
1804 #define RES_TO_STR(res) case res: return #res
1805 RES_TO_STR(WINED3DRTYPE_SURFACE);
1806 RES_TO_STR(WINED3DRTYPE_VOLUME);
1807 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1808 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1809 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1810 RES_TO_STR(WINED3DRTYPE_BUFFER);
1811 #undef RES_TO_STR
1812 default:
1813 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1814 return "unrecognized";
1818 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1819 switch (PrimitiveType) {
1820 #define PRIM_TO_STR(prim) case prim: return #prim
1821 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1822 PRIM_TO_STR(WINED3DPT_POINTLIST);
1823 PRIM_TO_STR(WINED3DPT_LINELIST);
1824 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1825 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1826 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1827 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1828 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1829 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1830 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1831 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1832 #undef PRIM_TO_STR
1833 default:
1834 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1835 return "unrecognized";
1839 const char* debug_d3drenderstate(DWORD state) {
1840 switch (state) {
1841 #define D3DSTATE_TO_STR(u) case u: return #u
1842 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1843 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1844 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1845 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1846 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1847 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1848 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1849 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1850 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1851 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1852 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1853 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1854 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1855 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1856 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1857 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1858 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1859 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1860 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1861 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1862 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1863 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1864 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1865 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1866 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1867 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1868 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1869 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1870 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1871 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1872 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1873 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1874 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1875 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1876 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1877 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1878 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1879 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1880 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1881 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1882 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1883 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1884 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1885 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1886 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1887 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1888 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1889 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1890 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1891 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1892 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1893 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1894 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1895 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1896 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1897 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1898 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1899 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1900 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1901 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1902 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1903 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1904 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1905 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1906 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1907 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1908 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1909 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1910 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1911 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1912 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1913 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1914 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1915 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1916 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1917 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1918 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1919 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1920 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1921 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1922 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1923 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1924 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1925 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1926 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1927 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1928 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1929 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1930 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1931 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1932 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1933 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1934 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1935 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1936 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1937 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1938 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1939 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1940 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1941 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1942 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1943 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1944 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1945 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1946 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1947 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1948 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1949 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1950 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1951 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1952 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1953 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1954 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1955 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1956 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1957 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1958 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1959 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1960 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1961 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1962 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1963 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1964 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1965 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1966 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1967 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1968 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1969 #undef D3DSTATE_TO_STR
1970 default:
1971 FIXME("Unrecognized %u render state!\n", state);
1972 return "unrecognized";
1976 const char* debug_d3dsamplerstate(DWORD state) {
1977 switch (state) {
1978 #define D3DSTATE_TO_STR(u) case u: return #u
1979 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1980 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1981 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1982 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1983 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1984 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1985 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1986 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1987 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1988 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1989 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1990 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1991 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1992 #undef D3DSTATE_TO_STR
1993 default:
1994 FIXME("Unrecognized %u sampler state!\n", state);
1995 return "unrecognized";
1999 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2000 switch (filter_type) {
2001 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2002 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2003 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2004 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2005 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2006 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2007 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2008 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2009 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2010 #undef D3DTEXTUREFILTERTYPE_TO_STR
2011 default:
2012 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2013 return "unrecognized";
2017 const char* debug_d3dtexturestate(DWORD state) {
2018 switch (state) {
2019 #define D3DSTATE_TO_STR(u) case u: return #u
2020 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
2021 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
2022 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
2023 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
2024 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
2025 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
2026 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
2027 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
2028 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
2029 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
2030 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
2031 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
2032 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
2033 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
2034 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
2035 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
2036 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
2037 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
2038 #undef D3DSTATE_TO_STR
2039 default:
2040 FIXME("Unrecognized %u texture state!\n", state);
2041 return "unrecognized";
2045 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2046 switch (d3dtop) {
2047 #define D3DTOP_TO_STR(u) case u: return #u
2048 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2049 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2050 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2051 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2052 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2053 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2054 D3DTOP_TO_STR(WINED3DTOP_ADD);
2055 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2056 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2057 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2058 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2059 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2060 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2061 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2062 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2063 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2064 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2065 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2066 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2067 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2068 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2069 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2070 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2071 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2072 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2073 D3DTOP_TO_STR(WINED3DTOP_LERP);
2074 #undef D3DTOP_TO_STR
2075 default:
2076 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2077 return "unrecognized";
2081 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2082 switch (tstype) {
2083 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2084 TSTYPE_TO_STR(WINED3DTS_VIEW);
2085 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2086 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2087 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2088 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2089 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2090 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2091 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2092 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2093 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2094 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2095 #undef TSTYPE_TO_STR
2096 default:
2097 if (tstype > 256 && tstype < 512) {
2098 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2099 return ("WINED3DTS_WORLDMATRIX > 0");
2101 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2102 return "unrecognized";
2106 const char *debug_d3dstate(DWORD state)
2108 if (STATE_IS_RENDER(state))
2109 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2110 if (STATE_IS_TEXTURESTAGE(state))
2112 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2113 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2114 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2115 texture_stage, debug_d3dtexturestate(texture_state));
2117 if (STATE_IS_SAMPLER(state))
2118 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2119 if (STATE_IS_PIXELSHADER(state))
2120 return "STATE_PIXELSHADER";
2121 if (STATE_IS_TRANSFORM(state))
2122 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2123 if (STATE_IS_STREAMSRC(state))
2124 return "STATE_STREAMSRC";
2125 if (STATE_IS_INDEXBUFFER(state))
2126 return "STATE_INDEXBUFFER";
2127 if (STATE_IS_VDECL(state))
2128 return "STATE_VDECL";
2129 if (STATE_IS_VSHADER(state))
2130 return "STATE_VSHADER";
2131 if (STATE_IS_VIEWPORT(state))
2132 return "STATE_VIEWPORT";
2133 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2134 return "STATE_VERTEXSHADERCONSTANT";
2135 if (STATE_IS_PIXELSHADERCONSTANT(state))
2136 return "STATE_PIXELSHADERCONSTANT";
2137 if (STATE_IS_ACTIVELIGHT(state))
2138 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2139 if (STATE_IS_SCISSORRECT(state))
2140 return "STATE_SCISSORRECT";
2141 if (STATE_IS_CLIPPLANE(state))
2142 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2143 if (STATE_IS_MATERIAL(state))
2144 return "STATE_MATERIAL";
2145 if (STATE_IS_FRONTFACE(state))
2146 return "STATE_FRONTFACE";
2148 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2151 const char* debug_d3dpool(WINED3DPOOL Pool) {
2152 switch (Pool) {
2153 #define POOL_TO_STR(p) case p: return #p
2154 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2155 POOL_TO_STR(WINED3DPOOL_MANAGED);
2156 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2157 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2158 #undef POOL_TO_STR
2159 default:
2160 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
2161 return "unrecognized";
2165 const char *debug_fbostatus(GLenum status) {
2166 switch(status) {
2167 #define FBOSTATUS_TO_STR(u) case u: return #u
2168 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2169 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2170 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2171 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2172 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2173 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2174 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2175 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2176 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2177 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2178 #undef FBOSTATUS_TO_STR
2179 default:
2180 FIXME("Unrecognied FBO status 0x%08x\n", status);
2181 return "unrecognized";
2185 const char *debug_glerror(GLenum error) {
2186 switch(error) {
2187 #define GLERROR_TO_STR(u) case u: return #u
2188 GLERROR_TO_STR(GL_NO_ERROR);
2189 GLERROR_TO_STR(GL_INVALID_ENUM);
2190 GLERROR_TO_STR(GL_INVALID_VALUE);
2191 GLERROR_TO_STR(GL_INVALID_OPERATION);
2192 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2193 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2194 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2195 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2196 #undef GLERROR_TO_STR
2197 default:
2198 FIXME("Unrecognied GL error 0x%08x\n", error);
2199 return "unrecognized";
2203 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2204 switch(basis) {
2205 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2206 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2207 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2208 default: return "unrecognized";
2212 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2213 switch(degree) {
2214 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2215 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2216 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2217 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2218 default: return "unrecognized";
2222 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2224 switch(source)
2226 #define WINED3D_TO_STR(x) case x: return #x
2227 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2228 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2229 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2230 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2231 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2232 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2233 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2234 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2235 #undef WINED3D_TO_STR
2236 default:
2237 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2238 return "unrecognized";
2242 static const char *debug_complex_fixup(enum complex_fixup fixup)
2244 switch(fixup)
2246 #define WINED3D_TO_STR(x) case x: return #x
2247 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2248 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2249 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2250 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2251 #undef WINED3D_TO_STR
2252 default:
2253 FIXME("Unrecognized complex fixup %#x\n", fixup);
2254 return "unrecognized";
2258 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2260 if (is_complex_fixup(fixup))
2262 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2263 return;
2266 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2267 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2268 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2269 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2272 const char *debug_surflocation(DWORD flag) {
2273 char buf[128];
2275 buf[0] = 0;
2276 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2277 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2278 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2279 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2280 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2283 /*****************************************************************************
2284 * Useful functions mapping GL <-> D3D values
2286 GLenum StencilOp(DWORD op) {
2287 switch(op) {
2288 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2289 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2290 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2291 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2292 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2293 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2294 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2295 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2296 default:
2297 FIXME("Unrecognized stencil op %d\n", op);
2298 return GL_KEEP;
2302 GLenum CompareFunc(DWORD func) {
2303 switch ((WINED3DCMPFUNC)func) {
2304 case WINED3DCMP_NEVER : return GL_NEVER;
2305 case WINED3DCMP_LESS : return GL_LESS;
2306 case WINED3DCMP_EQUAL : return GL_EQUAL;
2307 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2308 case WINED3DCMP_GREATER : return GL_GREATER;
2309 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2310 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2311 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2312 default:
2313 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2314 return 0;
2318 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
2319 if (op == WINED3DTOP_DISABLE) return FALSE;
2320 if (This->stateBlock->textures[stage]) return FALSE;
2322 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2323 && op != WINED3DTOP_SELECTARG2) return TRUE;
2324 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2325 && op != WINED3DTOP_SELECTARG1) return TRUE;
2326 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2327 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2329 return FALSE;
2332 /* Setup this textures matrix according to the texture flags*/
2333 /* GL locking is done by the caller (state handler) */
2334 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2335 WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
2337 float mat[16];
2339 glMatrixMode(GL_TEXTURE);
2340 checkGLcall("glMatrixMode(GL_TEXTURE)");
2342 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2343 glLoadIdentity();
2344 checkGLcall("glLoadIdentity()");
2345 return;
2348 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2349 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2350 return;
2353 memcpy(mat, smat, 16 * sizeof(float));
2355 if (flags & WINED3DTTFF_PROJECTED) {
2356 if(!ffp_proj_control) {
2357 switch (flags & ~WINED3DTTFF_PROJECTED) {
2358 case WINED3DTTFF_COUNT2:
2359 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2360 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2361 break;
2362 case WINED3DTTFF_COUNT3:
2363 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2364 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2365 break;
2368 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2369 if(!calculatedCoords) {
2370 switch(vtx_fmt)
2372 case WINED3DFMT_R32_FLOAT:
2373 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2374 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2375 * the input value to the transformation will be 0, so the matrix value is irrelevant
2377 mat[12] = mat[4];
2378 mat[13] = mat[5];
2379 mat[14] = mat[6];
2380 mat[15] = mat[7];
2381 break;
2382 case WINED3DFMT_R32G32_FLOAT:
2383 /* See above, just 3rd and 4th coord
2385 mat[12] = mat[8];
2386 mat[13] = mat[9];
2387 mat[14] = mat[10];
2388 mat[15] = mat[11];
2389 break;
2390 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2391 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2393 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2394 * into a bad place. The division elimination below will apply to make sure the
2395 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2397 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2398 break;
2399 default:
2400 FIXME("Unexpected fixed function texture coord input\n");
2403 if(!ffp_proj_control) {
2404 switch (flags & ~WINED3DTTFF_PROJECTED) {
2405 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2406 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2407 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2408 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2409 * the 4th coord evaluates to 1.0 to eliminate that.
2411 * If the fixed function pipeline is used, the 4th value remains unused,
2412 * so there is no danger in doing this. With vertex shaders we have a
2413 * problem. Should an app hit that problem, the code here would have to
2414 * check for pixel shaders, and the shader has to undo the default gl divide.
2416 * A more serious problem occurs if the app passes 4 coordinates in, and the
2417 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2418 * or a replacement shader
2420 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2425 glLoadMatrixf(mat);
2426 checkGLcall("glLoadMatrixf(mat)");
2429 /* This small helper function is used to convert a bitmask into the number of masked bits */
2430 unsigned int count_bits(unsigned int mask)
2432 unsigned int count;
2433 for (count = 0; mask; ++count)
2435 mask &= mask - 1;
2437 return count;
2440 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2441 * The later function requires individual color components. */
2442 BOOL getColorBits(const struct wined3d_format_desc *format_desc,
2443 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2445 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2446 switch(format_desc->format)
2448 case WINED3DFMT_B8G8R8X8_UNORM:
2449 case WINED3DFMT_B8G8R8_UNORM:
2450 case WINED3DFMT_B8G8R8A8_UNORM:
2451 case WINED3DFMT_R8G8B8A8_UNORM:
2452 case WINED3DFMT_B10G10R10A2_UNORM:
2453 case WINED3DFMT_B5G5R5X1_UNORM:
2454 case WINED3DFMT_B5G5R5A1_UNORM:
2455 case WINED3DFMT_B5G6R5_UNORM:
2456 case WINED3DFMT_B4G4R4X4_UNORM:
2457 case WINED3DFMT_B4G4R4A4_UNORM:
2458 case WINED3DFMT_B2G3R3_UNORM:
2459 case WINED3DFMT_P8_UINT_A8_UNORM:
2460 case WINED3DFMT_P8_UINT:
2461 break;
2462 default:
2463 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
2464 return FALSE;
2467 *redSize = count_bits(format_desc->red_mask);
2468 *greenSize = count_bits(format_desc->green_mask);
2469 *blueSize = count_bits(format_desc->blue_mask);
2470 *alphaSize = count_bits(format_desc->alpha_mask);
2471 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2473 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
2474 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
2475 return TRUE;
2478 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2479 BOOL getDepthStencilBits(const struct wined3d_format_desc *format_desc, short *depthSize, short *stencilSize)
2481 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2482 switch(format_desc->format)
2484 case WINED3DFMT_D16_LOCKABLE:
2485 case WINED3DFMT_D16_UNORM:
2486 case WINED3DFMT_S1_UINT_D15_UNORM:
2487 case WINED3DFMT_X8D24_UNORM:
2488 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2489 case WINED3DFMT_D24_UNORM_S8_UINT:
2490 case WINED3DFMT_S8_UINT_D24_FLOAT:
2491 case WINED3DFMT_D32_UNORM:
2492 case WINED3DFMT_D32_FLOAT:
2493 break;
2494 default:
2495 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
2496 return FALSE;
2499 *depthSize = format_desc->depth_size;
2500 *stencilSize = format_desc->stencil_size;
2502 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
2503 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
2504 return TRUE;
2507 DWORD color_convert_argb_to_fmt(DWORD color, WINED3DFORMAT destfmt)
2509 unsigned int r, g, b, a;
2510 DWORD ret;
2512 if (destfmt == WINED3DFMT_B8G8R8A8_UNORM
2513 || destfmt == WINED3DFMT_B8G8R8X8_UNORM
2514 || destfmt == WINED3DFMT_B8G8R8_UNORM)
2515 return color;
2517 TRACE("Converting color %08x to format %s\n", color, debug_d3dformat(destfmt));
2519 a = (color & 0xff000000) >> 24;
2520 r = (color & 0x00ff0000) >> 16;
2521 g = (color & 0x0000ff00) >> 8;
2522 b = (color & 0x000000ff) >> 0;
2524 switch(destfmt)
2526 case WINED3DFMT_B5G6R5_UNORM:
2527 if(r == 0xff && g == 0xff && b == 0xff) return 0xffff;
2528 r = (r * 32) / 256;
2529 g = (g * 64) / 256;
2530 b = (b * 32) / 256;
2531 ret = r << 11;
2532 ret |= g << 5;
2533 ret |= b;
2534 TRACE("Returning %08x\n", ret);
2535 return ret;
2537 case WINED3DFMT_B5G5R5X1_UNORM:
2538 case WINED3DFMT_B5G5R5A1_UNORM:
2539 a = (a * 2) / 256;
2540 r = (r * 32) / 256;
2541 g = (g * 32) / 256;
2542 b = (b * 32) / 256;
2543 ret = a << 15;
2544 ret |= r << 10;
2545 ret |= g << 5;
2546 ret |= b << 0;
2547 TRACE("Returning %08x\n", ret);
2548 return ret;
2550 case WINED3DFMT_A8_UNORM:
2551 TRACE("Returning %08x\n", a);
2552 return a;
2554 case WINED3DFMT_B4G4R4X4_UNORM:
2555 case WINED3DFMT_B4G4R4A4_UNORM:
2556 a = (a * 16) / 256;
2557 r = (r * 16) / 256;
2558 g = (g * 16) / 256;
2559 b = (b * 16) / 256;
2560 ret = a << 12;
2561 ret |= r << 8;
2562 ret |= g << 4;
2563 ret |= b << 0;
2564 TRACE("Returning %08x\n", ret);
2565 return ret;
2567 case WINED3DFMT_B2G3R3_UNORM:
2568 r = (r * 8) / 256;
2569 g = (g * 8) / 256;
2570 b = (b * 4) / 256;
2571 ret = r << 5;
2572 ret |= g << 2;
2573 ret |= b << 0;
2574 TRACE("Returning %08x\n", ret);
2575 return ret;
2577 case WINED3DFMT_R8G8B8X8_UNORM:
2578 case WINED3DFMT_R8G8B8A8_UNORM:
2579 ret = a << 24;
2580 ret |= b << 16;
2581 ret |= g << 8;
2582 ret |= r << 0;
2583 TRACE("Returning %08x\n", ret);
2584 return ret;
2586 case WINED3DFMT_B10G10R10A2_UNORM:
2587 a = (a * 4) / 256;
2588 r = (r * 1024) / 256;
2589 g = (g * 1024) / 256;
2590 b = (b * 1024) / 256;
2591 ret = a << 30;
2592 ret |= r << 20;
2593 ret |= g << 10;
2594 ret |= b << 0;
2595 TRACE("Returning %08x\n", ret);
2596 return ret;
2598 case WINED3DFMT_R10G10B10A2_UNORM:
2599 a = (a * 4) / 256;
2600 r = (r * 1024) / 256;
2601 g = (g * 1024) / 256;
2602 b = (b * 1024) / 256;
2603 ret = a << 30;
2604 ret |= b << 20;
2605 ret |= g << 10;
2606 ret |= r << 0;
2607 TRACE("Returning %08x\n", ret);
2608 return ret;
2610 default:
2611 FIXME("Add a COLORFILL conversion for format %s\n", debug_d3dformat(destfmt));
2612 return 0;
2616 /* DirectDraw stuff */
2617 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2618 switch(depth) {
2619 case 8: return WINED3DFMT_P8_UINT;
2620 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2621 case 16: return WINED3DFMT_B5G6R5_UNORM;
2622 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2623 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2624 default: return WINED3DFMT_UNKNOWN;
2628 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2629 WINED3DMATRIX temp;
2631 /* Now do the multiplication 'by hand'.
2632 I know that all this could be optimised, but this will be done later :-) */
2633 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);
2634 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);
2635 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);
2636 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);
2638 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);
2639 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);
2640 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);
2641 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);
2643 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);
2644 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);
2645 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);
2646 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);
2648 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);
2649 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);
2650 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);
2651 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);
2653 /* And copy the new matrix in the good storage.. */
2654 memcpy(dest, &temp, 16 * sizeof(float));
2657 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2658 DWORD size = 0;
2659 int i;
2660 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2662 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2663 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2664 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2665 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2666 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2667 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2668 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2669 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2670 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2671 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2672 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2673 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2674 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2675 default: ERR("Unexpected position mask\n");
2677 for (i = 0; i < numTextures; i++) {
2678 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2681 return size;
2684 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2685 #define ARG1 0x01
2686 #define ARG2 0x02
2687 #define ARG0 0x04
2688 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2689 /* undefined */ 0,
2690 /* D3DTOP_DISABLE */ 0,
2691 /* D3DTOP_SELECTARG1 */ ARG1,
2692 /* D3DTOP_SELECTARG2 */ ARG2,
2693 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2694 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2695 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2696 /* D3DTOP_ADD */ ARG1 | ARG2,
2697 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2698 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2699 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2700 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2701 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2702 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2703 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2704 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2705 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2706 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2707 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2708 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2709 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2710 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2711 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2712 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2713 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2714 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2715 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2717 unsigned int i;
2718 DWORD ttff;
2719 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2720 IWineD3DDeviceImpl *device = stateblock->device;
2721 IWineD3DSurfaceImpl *rt = device->render_targets[0];
2722 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2724 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2726 IWineD3DBaseTextureImpl *texture;
2727 settings->op[i].padding = 0;
2728 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2729 settings->op[i].cop = WINED3DTOP_DISABLE;
2730 settings->op[i].aop = WINED3DTOP_DISABLE;
2731 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2732 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2733 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2734 settings->op[i].dst = resultreg;
2735 settings->op[i].tex_type = tex_1d;
2736 settings->op[i].projected = proj_none;
2737 i++;
2738 break;
2741 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2742 if(texture) {
2743 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2744 if(ignore_textype) {
2745 settings->op[i].tex_type = tex_1d;
2746 } else {
2747 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2748 case GL_TEXTURE_1D:
2749 settings->op[i].tex_type = tex_1d;
2750 break;
2751 case GL_TEXTURE_2D:
2752 settings->op[i].tex_type = tex_2d;
2753 break;
2754 case GL_TEXTURE_3D:
2755 settings->op[i].tex_type = tex_3d;
2756 break;
2757 case GL_TEXTURE_CUBE_MAP_ARB:
2758 settings->op[i].tex_type = tex_cube;
2759 break;
2760 case GL_TEXTURE_RECTANGLE_ARB:
2761 settings->op[i].tex_type = tex_rect;
2762 break;
2765 } else {
2766 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2767 settings->op[i].tex_type = tex_1d;
2770 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2771 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2773 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2774 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2775 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2777 if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2778 carg0 = ARG_UNUSED;
2779 carg2 = ARG_UNUSED;
2780 carg1 = WINED3DTA_CURRENT;
2781 cop = WINED3DTOP_SELECTARG1;
2784 if(cop == WINED3DTOP_DOTPRODUCT3) {
2785 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2786 * the color result to the alpha component of the destination
2788 aop = cop;
2789 aarg1 = carg1;
2790 aarg2 = carg2;
2791 aarg0 = carg0;
2792 } else {
2793 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2794 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2795 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2798 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2800 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2802 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2804 IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)stateblock->textures[0];
2805 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
2807 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2809 if (aop == WINED3DTOP_DISABLE)
2811 aarg1 = WINED3DTA_TEXTURE;
2812 aop = WINED3DTOP_SELECTARG1;
2814 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2816 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2818 aarg2 = WINED3DTA_TEXTURE;
2819 aop = WINED3DTOP_MODULATE;
2821 else aarg1 = WINED3DTA_TEXTURE;
2823 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2825 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2827 aarg1 = WINED3DTA_TEXTURE;
2828 aop = WINED3DTOP_MODULATE;
2830 else aarg2 = WINED3DTA_TEXTURE;
2836 if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2837 aarg0 = ARG_UNUSED;
2838 aarg2 = ARG_UNUSED;
2839 aarg1 = WINED3DTA_CURRENT;
2840 aop = WINED3DTOP_SELECTARG1;
2843 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2844 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2845 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2846 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2847 settings->op[i].projected = proj_count3;
2848 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2849 settings->op[i].projected = proj_count4;
2850 } else {
2851 settings->op[i].projected = proj_none;
2853 } else {
2854 settings->op[i].projected = proj_none;
2857 settings->op[i].cop = cop;
2858 settings->op[i].aop = aop;
2859 settings->op[i].carg0 = carg0;
2860 settings->op[i].carg1 = carg1;
2861 settings->op[i].carg2 = carg2;
2862 settings->op[i].aarg0 = aarg0;
2863 settings->op[i].aarg1 = aarg1;
2864 settings->op[i].aarg2 = aarg2;
2866 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2867 settings->op[i].dst = tempreg;
2868 } else {
2869 settings->op[i].dst = resultreg;
2873 /* Clear unsupported stages */
2874 for(; i < MAX_TEXTURES; i++) {
2875 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2878 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2879 settings->fog = FOG_OFF;
2880 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2881 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2882 settings->fog = FOG_LINEAR;
2883 } else {
2884 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2885 case WINED3DFOG_NONE:
2886 case WINED3DFOG_LINEAR:
2887 settings->fog = FOG_LINEAR;
2888 break;
2889 case WINED3DFOG_EXP:
2890 settings->fog = FOG_EXP;
2891 break;
2892 case WINED3DFOG_EXP2:
2893 settings->fog = FOG_EXP2;
2894 break;
2897 } else {
2898 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2899 case WINED3DFOG_LINEAR:
2900 settings->fog = FOG_LINEAR;
2901 break;
2902 case WINED3DFOG_EXP:
2903 settings->fog = FOG_EXP;
2904 break;
2905 case WINED3DFOG_EXP2:
2906 settings->fog = FOG_EXP2;
2907 break;
2910 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE] &&
2911 rt->resource.format_desc->Flags & WINED3DFMT_FLAG_SRGB_WRITE) {
2912 settings->sRGB_write = 1;
2913 } else {
2914 settings->sRGB_write = 0;
2916 if(device->vs_clipping || !use_vs(stateblock) || !stateblock->renderState[WINED3DRS_CLIPPING] ||
2917 !stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
2918 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2919 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2920 * if no clipplane is enabled
2922 settings->emul_clipplanes = 0;
2923 } else {
2924 settings->emul_clipplanes = 1;
2928 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2929 const struct ffp_frag_settings *settings)
2931 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2932 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2935 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2937 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2938 * whereas desc points to an extended structure with implementation specific parts. */
2939 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2941 ERR("Failed to insert ffp frag shader.\n");
2945 /* Activates the texture dimension according to the bound D3D texture.
2946 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2947 * Requires the caller to activate the correct unit before
2949 /* GL locking is done by the caller (state handler) */
2950 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2952 const struct wined3d_gl_info *gl_info = context->gl_info;
2954 if (stateblock->textures[stage])
2956 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2957 case GL_TEXTURE_2D:
2958 glDisable(GL_TEXTURE_3D);
2959 checkGLcall("glDisable(GL_TEXTURE_3D)");
2960 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2962 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2963 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2965 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2967 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2968 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2970 glEnable(GL_TEXTURE_2D);
2971 checkGLcall("glEnable(GL_TEXTURE_2D)");
2972 break;
2973 case GL_TEXTURE_RECTANGLE_ARB:
2974 glDisable(GL_TEXTURE_2D);
2975 checkGLcall("glDisable(GL_TEXTURE_2D)");
2976 glDisable(GL_TEXTURE_3D);
2977 checkGLcall("glDisable(GL_TEXTURE_3D)");
2978 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2980 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2981 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2983 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2984 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2985 break;
2986 case GL_TEXTURE_3D:
2987 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2989 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2990 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2992 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2994 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2995 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2997 glDisable(GL_TEXTURE_2D);
2998 checkGLcall("glDisable(GL_TEXTURE_2D)");
2999 glEnable(GL_TEXTURE_3D);
3000 checkGLcall("glEnable(GL_TEXTURE_3D)");
3001 break;
3002 case GL_TEXTURE_CUBE_MAP_ARB:
3003 glDisable(GL_TEXTURE_2D);
3004 checkGLcall("glDisable(GL_TEXTURE_2D)");
3005 glDisable(GL_TEXTURE_3D);
3006 checkGLcall("glDisable(GL_TEXTURE_3D)");
3007 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3009 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3010 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3012 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3013 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3014 break;
3016 } else {
3017 glEnable(GL_TEXTURE_2D);
3018 checkGLcall("glEnable(GL_TEXTURE_2D)");
3019 glDisable(GL_TEXTURE_3D);
3020 checkGLcall("glDisable(GL_TEXTURE_3D)");
3021 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3023 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3024 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3026 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3028 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3029 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3031 /* Binding textures is done by samplers. A dummy texture will be bound */
3035 /* GL locking is done by the caller (state handler) */
3036 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3038 DWORD sampler = state - STATE_SAMPLER(0);
3039 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3041 /* No need to enable / disable anything here for unused samplers. The tex_colorop
3042 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3043 * will take care of this business
3045 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3046 if(sampler >= stateblock->lowest_disabled_stage) return;
3047 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3049 texture_activate_dimensions(sampler, stateblock, context);
3052 void *wined3d_rb_alloc(size_t size)
3054 return HeapAlloc(GetProcessHeap(), 0, size);
3057 void *wined3d_rb_realloc(void *ptr, size_t size)
3059 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3062 void wined3d_rb_free(void *ptr)
3064 HeapFree(GetProcessHeap(), 0, ptr);
3067 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3069 const struct ffp_frag_settings *ka = key;
3070 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3072 return memcmp(ka, kb, sizeof(*ka));
3075 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3077 wined3d_rb_alloc,
3078 wined3d_rb_realloc,
3079 wined3d_rb_free,
3080 ffp_frag_program_key_compare,
3083 UINT wined3d_log2i(UINT32 x)
3085 static const UINT l[] =
3087 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3088 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3089 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3090 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3091 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3092 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3093 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3094 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3095 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3096 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3097 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3098 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3099 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3100 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3101 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3102 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3104 UINT32 i;
3106 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3109 /* Set the shader type for this device, depending on the given capabilities
3110 * and the user preferences in wined3d_settings. */
3111 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3113 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3115 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3116 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3118 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3119 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3120 * shaders only on this card. */
3121 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3122 else *vs_selected = SHADER_GLSL;
3124 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3125 else *vs_selected = SHADER_NONE;
3127 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3128 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3129 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3130 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3131 else *ps_selected = SHADER_NONE;