wined3d: Rename the "format" field in wined3d_format_desc to "id".
[wine/multimedia.git] / dlls / wined3d / utils.c
blobd2d729512c8602666b7465986ca97402fb8bbf59
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 enum wined3d_format_id id;
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 /* format id 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 enum wined3d_format_id id;
139 DWORD flags;
142 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
143 * still needs to use the correct block based calculation for e.g. the
144 * resource size. */
145 static const struct wined3d_format_base_flags format_base_flags[] =
147 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
148 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
149 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
150 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
151 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
152 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
153 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
156 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
157 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
158 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
159 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
160 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
161 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
162 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
163 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
164 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
165 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
166 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
170 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
171 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
172 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
173 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
174 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
175 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
176 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
177 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
178 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
179 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 struct wined3d_format_compression_info
185 enum wined3d_format_id id;
186 UINT block_width;
187 UINT block_height;
188 UINT block_byte_count;
191 static const struct wined3d_format_compression_info format_compression_info[] =
193 {WINED3DFMT_DXT1, 4, 4, 8},
194 {WINED3DFMT_DXT2, 4, 4, 16},
195 {WINED3DFMT_DXT3, 4, 4, 16},
196 {WINED3DFMT_DXT4, 4, 4, 16},
197 {WINED3DFMT_DXT5, 4, 4, 16},
198 {WINED3DFMT_ATI2N, 4, 4, 16},
201 struct wined3d_format_vertex_info
203 enum wined3d_format_id id;
204 enum wined3d_ffp_emit_idx emit_idx;
205 GLint component_count;
206 GLenum gl_vtx_type;
207 GLint gl_vtx_format;
208 GLboolean gl_normalized;
209 unsigned int component_size;
212 static const struct wined3d_format_vertex_info format_vertex_info[] =
214 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
215 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
216 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
217 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
218 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
219 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
220 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
221 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
222 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
223 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
224 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
225 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
226 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
227 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
228 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
229 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
230 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
233 struct wined3d_format_texture_info
235 enum wined3d_format_id id;
236 GLint gl_internal;
237 GLint gl_srgb_internal;
238 GLint gl_rt_internal;
239 GLint gl_format;
240 GLint gl_type;
241 unsigned int conv_byte_count;
242 unsigned int flags;
243 GL_SupportedExt extension;
244 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
247 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
249 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
250 * format+type combination to load it. Thus convert it to A8L8, then load it
251 * with A4L4 internal, but A8L8 format+type
253 unsigned int x, y;
254 const unsigned char *Source;
255 unsigned char *Dest;
256 UINT outpitch = pitch * 2;
258 for(y = 0; y < height; y++) {
259 Source = src + y * pitch;
260 Dest = dst + y * outpitch;
261 for (x = 0; x < width; x++ ) {
262 unsigned char color = (*Source++);
263 /* A */ Dest[1] = (color & 0xf0) << 0;
264 /* L */ Dest[0] = (color & 0x0f) << 4;
265 Dest += 2;
270 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
272 unsigned int x, y;
273 const WORD *Source;
275 for(y = 0; y < height; y++)
277 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
278 Source = (const WORD *)(src + y * pitch);
279 for (x = 0; x < width; x++ )
281 short color = (*Source++);
282 unsigned char l = ((color >> 10) & 0xfc);
283 short v = ((color >> 5) & 0x3e);
284 short u = ((color ) & 0x1f);
285 short v_conv = v + 16;
286 short u_conv = u + 16;
288 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
289 Dest_s += 1;
294 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
296 unsigned int x, y;
297 const WORD *Source;
298 unsigned char *Dest;
299 UINT outpitch = (pitch * 3)/2;
301 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
302 * fixed function and shaders without further conversion once the surface is
303 * loaded
305 for(y = 0; y < height; y++) {
306 Source = (const WORD *)(src + y * pitch);
307 Dest = dst + y * outpitch;
308 for (x = 0; x < width; x++ ) {
309 short color = (*Source++);
310 unsigned char l = ((color >> 10) & 0xfc);
311 char v = ((color >> 5) & 0x3e);
312 char u = ((color ) & 0x1f);
314 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
315 * and doubles the positive range. Thus shift left only once, gl does the 2nd
316 * shift. GL reads a signed value and converts it into an unsigned value.
318 /* M */ Dest[2] = l << 1;
320 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
321 * from 5 bit values to 8 bit values.
323 /* V */ Dest[1] = v << 3;
324 /* U */ Dest[0] = u << 3;
325 Dest += 3;
330 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
332 unsigned int x, y;
333 const short *Source;
334 unsigned char *Dest;
335 UINT outpitch = (pitch * 3)/2;
337 for(y = 0; y < height; y++)
339 Source = (const short *)(src + y * pitch);
340 Dest = dst + y * outpitch;
341 for (x = 0; x < width; x++ )
343 LONG color = (*Source++);
344 /* B */ Dest[0] = 0xff;
345 /* G */ Dest[1] = (color >> 8) + 128; /* V */
346 /* R */ Dest[2] = (color) + 128; /* U */
347 Dest += 3;
352 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
354 unsigned int x, y;
355 const DWORD *Source;
356 unsigned char *Dest;
358 /* Doesn't work correctly with the fixed function pipeline, but can work in
359 * shaders if the shader is adjusted. (There's no use for this format in gl's
360 * standard fixed function pipeline anyway).
362 for(y = 0; y < height; y++)
364 Source = (const DWORD *)(src + y * pitch);
365 Dest = dst + y * pitch;
366 for (x = 0; x < width; x++ )
368 LONG color = (*Source++);
369 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
370 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
371 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
372 Dest += 4;
377 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
379 unsigned int x, y;
380 const DWORD *Source;
381 unsigned char *Dest;
383 /* This implementation works with the fixed function pipeline and shaders
384 * without further modification after converting the surface.
386 for(y = 0; y < height; y++)
388 Source = (const DWORD *)(src + y * pitch);
389 Dest = dst + y * pitch;
390 for (x = 0; x < width; x++ )
392 LONG color = (*Source++);
393 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
394 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
395 /* U */ Dest[0] = (color & 0xff); /* U */
396 /* I */ Dest[3] = 255; /* X */
397 Dest += 4;
402 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
404 unsigned int x, y;
405 const DWORD *Source;
406 unsigned char *Dest;
408 for(y = 0; y < height; y++)
410 Source = (const DWORD *)(src + y * pitch);
411 Dest = dst + y * pitch;
412 for (x = 0; x < width; x++ )
414 LONG color = (*Source++);
415 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
416 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
417 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
418 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
419 Dest += 4;
424 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
426 unsigned int x, y;
427 const DWORD *Source;
428 unsigned short *Dest;
429 UINT outpitch = (pitch * 3)/2;
431 for(y = 0; y < height; y++)
433 Source = (const DWORD *)(src + y * pitch);
434 Dest = (unsigned short *) (dst + y * outpitch);
435 for (x = 0; x < width; x++ )
437 DWORD color = (*Source++);
438 /* B */ Dest[0] = 0xffff;
439 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
440 /* R */ Dest[2] = (color ) + 32768; /* U */
441 Dest += 3;
446 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
448 unsigned int x, y;
449 const WORD *Source;
450 WORD *Dest;
451 UINT outpitch = (pitch * 3)/2;
453 for(y = 0; y < height; y++)
455 Source = (const WORD *)(src + y * pitch);
456 Dest = (WORD *) (dst + y * outpitch);
457 for (x = 0; x < width; x++ )
459 WORD green = (*Source++);
460 WORD red = (*Source++);
461 Dest[0] = green;
462 Dest[1] = red;
463 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
464 * shader overwrites it anyway
466 Dest[2] = 0xffff;
467 Dest += 3;
472 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
474 unsigned int x, y;
475 const float *Source;
476 float *Dest;
477 UINT outpitch = (pitch * 3)/2;
479 for(y = 0; y < height; y++)
481 Source = (const float *)(src + y * pitch);
482 Dest = (float *) (dst + y * outpitch);
483 for (x = 0; x < width; x++ )
485 float green = (*Source++);
486 float red = (*Source++);
487 Dest[0] = green;
488 Dest[1] = red;
489 Dest[2] = 1.0f;
490 Dest += 3;
495 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
497 unsigned int x, y;
498 UINT outpitch = pitch * 2;
500 for (y = 0; y < height; ++y)
502 const WORD *source = (const WORD *)(src + y * pitch);
503 DWORD *dest = (DWORD *)(dst + y * outpitch);
505 for (x = 0; x < width; ++x)
507 /* The depth data is normalized, so needs to be scaled,
508 * the stencil data isn't. Scale depth data by
509 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
510 WORD d15 = source[x] >> 1;
511 DWORD d24 = (d15 << 9) + (d15 >> 6);
512 dest[x] = (d24 << 8) | (source[x] & 0x1);
517 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
519 unsigned int x, y;
521 for (y = 0; y < height; ++y)
523 const DWORD *source = (const DWORD *)(src + y * pitch);
524 DWORD *dest = (DWORD *)(dst + y * pitch);
526 for (x = 0; x < width; ++x)
528 /* Just need to clear out the X4 part. */
529 dest[x] = source[x] & ~0xf0;
534 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
536 unsigned int x, y;
537 UINT outpitch = pitch * 2;
539 for (y = 0; y < height; ++y)
541 const DWORD *source = (const DWORD *)(src + y * pitch);
542 float *dest_f = (float *)(dst + y * outpitch);
543 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
545 for (x = 0; x < width; ++x)
547 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
548 dest_s[x * 2 + 1] = source[x] & 0xff;
553 static const struct wined3d_format_texture_info format_texture_info[] =
555 /* format id internal srgbInternal rtInternal
556 format type
557 flags
558 extension */
559 /* FourCC formats */
560 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
561 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
562 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
563 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
564 * endian machine
566 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
567 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
568 WINED3DFMT_FLAG_FILTERING,
569 WINED3D_GL_EXT_NONE, NULL},
570 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
571 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
572 WINED3DFMT_FLAG_FILTERING,
573 APPLE_YCBCR_422, NULL},
574 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
575 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
576 WINED3DFMT_FLAG_FILTERING,
577 WINED3D_GL_EXT_NONE, NULL},
578 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
579 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
580 WINED3DFMT_FLAG_FILTERING,
581 APPLE_YCBCR_422, NULL},
582 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
583 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
584 WINED3DFMT_FLAG_FILTERING,
585 WINED3D_GL_EXT_NONE, NULL},
586 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
587 GL_RGBA, GL_UNSIGNED_BYTE, 0,
588 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
589 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
590 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
591 GL_RGBA, GL_UNSIGNED_BYTE, 0,
592 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
593 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
594 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
595 GL_RGBA, GL_UNSIGNED_BYTE, 0,
596 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
597 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
598 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
599 GL_RGBA, GL_UNSIGNED_BYTE, 0,
600 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
601 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
602 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
603 GL_RGBA, GL_UNSIGNED_BYTE, 0,
604 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
605 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
606 /* IEEE formats */
607 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
608 GL_RED, GL_FLOAT, 0,
609 WINED3DFMT_FLAG_RENDERTARGET,
610 ARB_TEXTURE_FLOAT, NULL},
611 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
612 GL_RED, GL_FLOAT, 0,
613 WINED3DFMT_FLAG_RENDERTARGET,
614 ARB_TEXTURE_RG, NULL},
615 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
616 GL_RGB, GL_FLOAT, 12,
617 WINED3DFMT_FLAG_RENDERTARGET,
618 ARB_TEXTURE_FLOAT, &convert_r32g32_float},
619 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
620 GL_RG, GL_FLOAT, 0,
621 WINED3DFMT_FLAG_RENDERTARGET,
622 ARB_TEXTURE_RG, NULL},
623 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
624 GL_RGBA, GL_FLOAT, 0,
625 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
626 ARB_TEXTURE_FLOAT, NULL},
627 /* Float */
628 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
629 GL_RED, GL_HALF_FLOAT_ARB, 0,
630 WINED3DFMT_FLAG_RENDERTARGET,
631 ARB_TEXTURE_FLOAT, NULL},
632 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
633 GL_RED, GL_HALF_FLOAT_ARB, 0,
634 WINED3DFMT_FLAG_RENDERTARGET,
635 ARB_TEXTURE_RG, NULL},
636 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
637 GL_RGB, GL_HALF_FLOAT_ARB, 6,
638 WINED3DFMT_FLAG_RENDERTARGET,
639 ARB_TEXTURE_FLOAT, &convert_r16g16},
640 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
641 GL_RG, GL_HALF_FLOAT_ARB, 0,
642 WINED3DFMT_FLAG_RENDERTARGET,
643 ARB_TEXTURE_RG, NULL},
644 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
645 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
646 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
647 ARB_TEXTURE_FLOAT, NULL},
648 /* Palettized formats */
649 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
650 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
652 ARB_FRAGMENT_PROGRAM, NULL},
653 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
654 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
656 EXT_PALETTED_TEXTURE, NULL},
657 /* Standard ARGB formats */
658 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
659 GL_BGR, GL_UNSIGNED_BYTE, 0,
660 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
661 WINED3D_GL_EXT_NONE, NULL},
662 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
663 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
664 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
665 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
666 WINED3D_GL_EXT_NONE, NULL},
667 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
668 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
669 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
670 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
671 WINED3D_GL_EXT_NONE, NULL},
672 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
673 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
674 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
675 WINED3D_GL_EXT_NONE, NULL},
676 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
677 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
678 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
679 WINED3D_GL_EXT_NONE, NULL},
680 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
681 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
682 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
683 WINED3D_GL_EXT_NONE, NULL},
684 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
685 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
686 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
687 WINED3D_GL_EXT_NONE, NULL},
688 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
689 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
690 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
691 WINED3D_GL_EXT_NONE, NULL},
692 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
693 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
694 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
695 WINED3D_GL_EXT_NONE, NULL},
696 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
697 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
698 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
699 WINED3D_GL_EXT_NONE, NULL},
700 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
701 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
702 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
703 WINED3D_GL_EXT_NONE, NULL},
704 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
705 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
706 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
707 WINED3D_GL_EXT_NONE, NULL},
708 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
709 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
710 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
711 WINED3D_GL_EXT_NONE, NULL},
712 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
713 GL_RGB, GL_UNSIGNED_SHORT, 6,
714 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
715 WINED3D_GL_EXT_NONE, &convert_r16g16},
716 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
717 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
718 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
719 WINED3D_GL_EXT_NONE, NULL},
720 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
721 GL_RGBA, GL_UNSIGNED_SHORT, 0,
722 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
723 WINED3D_GL_EXT_NONE, NULL},
724 /* Luminance */
725 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
726 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
727 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
728 WINED3D_GL_EXT_NONE, NULL},
729 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
730 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
731 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
732 WINED3D_GL_EXT_NONE, NULL},
733 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
734 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
736 WINED3D_GL_EXT_NONE, &convert_l4a4_unorm},
737 /* Bump mapping stuff */
738 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
739 GL_BGR, GL_UNSIGNED_BYTE, 3,
740 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
741 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm},
742 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
743 GL_DSDT_NV, GL_BYTE, 0,
744 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
745 NV_TEXTURE_SHADER, NULL},
746 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
747 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
748 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
749 WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm},
750 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
751 GL_DSDT_MAG_NV, GL_BYTE, 3,
752 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
753 NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv},
754 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
755 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
756 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
757 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm},
758 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
759 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
760 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
761 NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv},
762 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
763 GL_BGRA, GL_UNSIGNED_BYTE, 4,
764 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
765 WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm},
766 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
767 GL_RGBA, GL_BYTE, 0,
768 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
769 NV_TEXTURE_SHADER, NULL},
770 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
771 GL_BGR, GL_UNSIGNED_SHORT, 6,
772 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
773 WINED3D_GL_EXT_NONE, &convert_r16g16_snorm},
774 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
775 GL_HILO_NV, GL_SHORT, 0,
776 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
777 NV_TEXTURE_SHADER, NULL},
778 /* Depth stencil formats */
779 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
780 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
781 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
782 ARB_DEPTH_TEXTURE, NULL},
783 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
784 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
785 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
786 ARB_DEPTH_TEXTURE, NULL},
787 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
788 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
789 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
790 ARB_DEPTH_TEXTURE, NULL},
791 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
792 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
793 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
794 EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm},
795 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
796 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
797 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
798 ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm},
799 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
800 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
801 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
802 | WINED3DFMT_FLAG_SHADOW,
803 ARB_DEPTH_TEXTURE, NULL},
804 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
805 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
806 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
807 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
808 EXT_PACKED_DEPTH_STENCIL, NULL},
809 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
810 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
811 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
812 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
813 ARB_FRAMEBUFFER_OBJECT, NULL},
814 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
815 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
816 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
817 | WINED3DFMT_FLAG_SHADOW,
818 ARB_DEPTH_TEXTURE, NULL},
819 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
820 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
821 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
822 ARB_DEPTH_TEXTURE, NULL},
823 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
824 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
825 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
826 EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm},
827 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
828 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
829 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
830 ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm},
831 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
832 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
833 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
834 | WINED3DFMT_FLAG_SHADOW,
835 ARB_DEPTH_TEXTURE, NULL},
836 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
837 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
838 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
839 WINED3D_GL_EXT_NONE, NULL},
840 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
841 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
842 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
843 ARB_DEPTH_BUFFER_FLOAT, NULL},
844 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
845 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
846 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
847 ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float},
848 /* Vendor-specific formats */
849 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
850 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
851 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
852 ATI_TEXTURE_COMPRESSION_3DC, NULL},
853 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2, GL_COMPRESSED_RED_GREEN_RGTC2, 0,
854 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
855 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
856 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
859 static inline int getFmtIdx(enum wined3d_format_id format_id)
861 /* First check if the format is at the position of its value.
862 * This will catch the argb formats before the loop is entered. */
863 if (format_id < (sizeof(formats) / sizeof(*formats))
864 && formats[format_id].id == format_id)
866 return format_id;
868 else
870 unsigned int i;
872 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
874 if (formats[i].id == format_id) return i;
877 return -1;
880 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
882 UINT format_count = sizeof(formats) / sizeof(*formats);
883 UINT i;
885 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->gl_formats));
886 if (!gl_info->gl_formats)
888 ERR("Failed to allocate memory.\n");
889 return FALSE;
892 for (i = 0; i < format_count; ++i)
894 struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
895 desc->id = formats[i].id;
896 desc->red_mask = formats[i].redMask;
897 desc->green_mask = formats[i].greenMask;
898 desc->blue_mask = formats[i].blueMask;
899 desc->alpha_mask = formats[i].alphaMask;
900 desc->byte_count = formats[i].bpp;
901 desc->depth_size = formats[i].depthSize;
902 desc->stencil_size = formats[i].stencilSize;
905 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
907 int fmt_idx = getFmtIdx(format_base_flags[i].id);
909 if (fmt_idx == -1)
911 ERR("Format %s (%#x) not found.\n",
912 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
913 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
914 return FALSE;
917 gl_info->gl_formats[fmt_idx].Flags |= format_base_flags[i].flags;
920 return TRUE;
923 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
925 unsigned int i;
927 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
929 struct wined3d_format_desc *format_desc;
930 int fmt_idx = getFmtIdx(format_compression_info[i].id);
932 if (fmt_idx == -1)
934 ERR("Format %s (%#x) not found.\n",
935 debug_d3dformat(format_compression_info[i].id), format_compression_info[i].id);
936 return FALSE;
939 format_desc = &gl_info->gl_formats[fmt_idx];
940 format_desc->block_width = format_compression_info[i].block_width;
941 format_desc->block_height = format_compression_info[i].block_height;
942 format_desc->block_byte_count = format_compression_info[i].block_byte_count;
943 format_desc->Flags |= WINED3DFMT_FLAG_COMPRESSED;
946 return TRUE;
949 /* Context activation is done by the caller. */
950 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format_desc *format_desc)
952 /* Check if the default internal format is supported as a frame buffer
953 * target, otherwise fall back to the render target internal.
955 * Try to stick to the standard format if possible, this limits precision differences. */
956 GLenum status;
957 GLuint tex;
959 ENTER_GL();
961 while(glGetError());
962 glDisable(GL_BLEND);
964 glGenTextures(1, &tex);
965 glBindTexture(GL_TEXTURE_2D, tex);
967 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glInternal, 16, 16, 0,
968 format_desc->glFormat, format_desc->glType, NULL);
969 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
970 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
972 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
974 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
975 checkGLcall("Framebuffer format check");
977 if (status == GL_FRAMEBUFFER_COMPLETE)
979 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format_desc->id));
980 format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
981 format_desc->rtInternal = format_desc->glInternal;
983 else
985 if (!format_desc->rtInternal)
987 if (format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)
989 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
990 " and no fallback specified.\n", debug_d3dformat(format_desc->id));
991 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
993 else
995 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format_desc->id));
997 format_desc->rtInternal = format_desc->glInternal;
999 else
1001 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1002 debug_d3dformat(format_desc->id));
1004 while(glGetError());
1006 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1008 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->rtInternal, 16, 16, 0,
1009 format_desc->glFormat, format_desc->glType, NULL);
1010 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1011 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1013 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1015 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1016 checkGLcall("Framebuffer format check");
1018 if (status == GL_FRAMEBUFFER_COMPLETE)
1020 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1021 debug_d3dformat(format_desc->id));
1023 else
1025 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1026 debug_d3dformat(format_desc->id));
1027 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1032 if (status == GL_FRAMEBUFFER_COMPLETE && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1034 GLuint rb;
1036 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1037 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1039 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1040 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1041 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1042 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1043 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1044 checkGLcall("RB attachment");
1047 glEnable(GL_BLEND);
1048 glClear(GL_COLOR_BUFFER_BIT);
1049 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1051 while(glGetError());
1052 TRACE("Format doesn't support post-pixelshader blending.\n");
1053 format_desc->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1056 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1057 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1059 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1060 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1061 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1062 checkGLcall("RB cleanup");
1066 if (format_desc->glInternal != format_desc->glGammaInternal)
1068 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glGammaInternal, 16, 16, 0,
1069 format_desc->glFormat, format_desc->glType, NULL);
1070 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1072 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1073 checkGLcall("Framebuffer format check");
1075 if (status == GL_FRAMEBUFFER_COMPLETE)
1077 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format_desc->id));
1078 format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1080 else
1082 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format_desc->id));
1086 glDeleteTextures(1, &tex);
1088 LEAVE_GL();
1091 /* Context activation is done by the caller. */
1092 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1094 unsigned int i;
1095 GLuint fbo;
1097 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1099 ENTER_GL();
1101 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1102 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1104 LEAVE_GL();
1107 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1109 struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
1111 if (!desc->glInternal) continue;
1113 if (desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1115 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1116 debug_d3dformat(desc->id));
1117 continue;
1120 if (desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
1122 TRACE("Skipping format %s because it's a compressed format.\n",
1123 debug_d3dformat(desc->id));
1124 continue;
1127 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1129 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc->id));
1130 check_fbo_compat(gl_info, desc);
1132 else
1134 desc->rtInternal = desc->glInternal;
1138 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1140 ENTER_GL();
1142 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1144 LEAVE_GL();
1148 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1150 unsigned int i;
1152 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1154 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1155 struct wined3d_format_desc *desc;
1157 if (fmt_idx == -1)
1159 ERR("Format %s (%#x) not found.\n",
1160 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1161 return FALSE;
1164 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1166 desc = &gl_info->gl_formats[fmt_idx];
1167 desc->glInternal = format_texture_info[i].gl_internal;
1168 desc->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1169 desc->rtInternal = format_texture_info[i].gl_rt_internal;
1170 desc->glFormat = format_texture_info[i].gl_format;
1171 desc->glType = format_texture_info[i].gl_type;
1172 desc->color_fixup = COLOR_FIXUP_IDENTITY;
1173 desc->Flags |= format_texture_info[i].flags;
1174 desc->heightscale = 1.0f;
1176 /* Texture conversion stuff */
1177 desc->convert = format_texture_info[i].convert;
1178 desc->conv_byte_count = format_texture_info[i].conv_byte_count;
1181 return TRUE;
1184 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1186 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1187 c1 >>= 8; c2 >>= 8;
1188 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1189 c1 >>= 8; c2 >>= 8;
1190 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1191 c1 >>= 8; c2 >>= 8;
1192 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1193 return TRUE;
1196 /* A context is provided by the caller */
1197 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1199 static const DWORD data[] = {0x00000000, 0xffffffff};
1200 GLuint tex, fbo, buffer;
1201 DWORD readback[16 * 1];
1202 BOOL ret = FALSE;
1204 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1205 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1206 * falling back to software. If this changes in the future this code will get fooled and
1207 * apps might hit the software path due to incorrectly advertised caps.
1209 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1210 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1211 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1214 ENTER_GL();
1215 while(glGetError());
1217 glGenTextures(1, &buffer);
1218 glBindTexture(GL_TEXTURE_2D, buffer);
1219 memset(readback, 0x7e, sizeof(readback));
1220 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1221 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1222 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1223 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1224 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1225 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1227 glGenTextures(1, &tex);
1228 glBindTexture(GL_TEXTURE_2D, tex);
1229 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1230 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1231 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1232 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1233 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1234 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1235 glEnable(GL_TEXTURE_2D);
1237 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1238 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1239 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1240 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1242 glViewport(0, 0, 16, 1);
1243 glDisable(GL_LIGHTING);
1244 glMatrixMode(GL_MODELVIEW);
1245 glLoadIdentity();
1246 glMatrixMode(GL_PROJECTION);
1247 glLoadIdentity();
1249 glClearColor(0, 1, 0, 0);
1250 glClear(GL_COLOR_BUFFER_BIT);
1252 glBegin(GL_TRIANGLE_STRIP);
1253 glTexCoord2f(0.0, 0.0);
1254 glVertex2f(-1.0f, -1.0f);
1255 glTexCoord2f(1.0, 0.0);
1256 glVertex2f(1.0f, -1.0f);
1257 glTexCoord2f(0.0, 1.0);
1258 glVertex2f(-1.0f, 1.0f);
1259 glTexCoord2f(1.0, 1.0);
1260 glVertex2f(1.0f, 1.0f);
1261 glEnd();
1263 glBindTexture(GL_TEXTURE_2D, buffer);
1264 memset(readback, 0x7f, sizeof(readback));
1265 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1266 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1267 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1269 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1270 readback[6], readback[9]);
1271 ret = FALSE;
1273 else
1275 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1276 readback[6], readback[9]);
1277 ret = TRUE;
1280 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1281 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1282 glDeleteTextures(1, &tex);
1283 glDeleteTextures(1, &buffer);
1285 if(glGetError())
1287 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1288 ret = FALSE;
1290 LEAVE_GL();
1291 return ret;
1294 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1296 struct wined3d_format_desc *desc;
1297 unsigned int fmt_idx, i;
1298 static const enum wined3d_format_id fmts16[] =
1300 WINED3DFMT_R16_FLOAT,
1301 WINED3DFMT_R16G16_FLOAT,
1302 WINED3DFMT_R16G16B16A16_FLOAT,
1304 BOOL filtered;
1306 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1308 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1309 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1311 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1312 filtered = TRUE;
1314 else if (gl_info->limits.glsl_varyings > 44)
1316 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1317 filtered = TRUE;
1319 else
1321 TRACE("Assuming no float16 blending\n");
1322 filtered = FALSE;
1325 if(filtered)
1327 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1329 fmt_idx = getFmtIdx(fmts16[i]);
1330 gl_info->gl_formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
1333 return;
1336 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1338 fmt_idx = getFmtIdx(fmts16[i]);
1339 desc = &gl_info->gl_formats[fmt_idx];
1340 if(!desc->glInternal) continue; /* Not supported by GL */
1342 filtered = check_filter(gl_info, gl_info->gl_formats[fmt_idx].glInternal);
1343 if(filtered)
1345 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1346 desc->Flags |= WINED3DFMT_FLAG_FILTERING;
1348 else
1350 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1355 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1357 int idx;
1359 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1360 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1361 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1363 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1364 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1365 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1367 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
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 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1372 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1373 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1375 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1376 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1377 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1379 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1380 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1381 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1382 * the only driver that implements it(fglrx) has a buggy implementation.
1384 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1385 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1386 * conversion for this format.
1388 if (!gl_info->supported[NV_TEXTURE_SHADER])
1390 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1391 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1392 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1393 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1394 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1395 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1397 else
1399 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1400 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1401 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1403 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1404 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1405 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1408 if (!gl_info->supported[NV_TEXTURE_SHADER])
1410 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1411 * with each other
1413 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1414 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1415 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1416 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1417 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1418 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1419 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1420 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1421 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1423 else
1425 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1426 * are converted at surface loading time, but they do not need any modification in
1427 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1428 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1432 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1434 idx = getFmtIdx(WINED3DFMT_ATI2N);
1435 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1436 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1438 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1440 idx = getFmtIdx(WINED3DFMT_ATI2N);
1441 gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
1442 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1445 if (!gl_info->supported[APPLE_YCBCR_422])
1447 idx = getFmtIdx(WINED3DFMT_YUY2);
1448 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1450 idx = getFmtIdx(WINED3DFMT_UYVY);
1451 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1454 idx = getFmtIdx(WINED3DFMT_YV12);
1455 gl_info->gl_formats[idx].heightscale = 1.5f;
1456 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1458 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1460 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1461 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1464 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1466 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1467 gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
1470 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1472 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1473 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1474 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1475 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1477 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1478 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1482 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1484 unsigned int i;
1486 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1488 struct wined3d_format_desc *format_desc;
1489 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1491 if (fmt_idx == -1)
1493 ERR("Format %s (%#x) not found.\n",
1494 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1495 return FALSE;
1498 format_desc = &gl_info->gl_formats[fmt_idx];
1499 format_desc->emit_idx = format_vertex_info[i].emit_idx;
1500 format_desc->component_count = format_vertex_info[i].component_count;
1501 format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1502 format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1503 format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
1504 format_desc->component_size = format_vertex_info[i].component_size;
1507 return TRUE;
1510 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1512 if (!init_format_base_info(gl_info)) return FALSE;
1514 if (!init_format_compression_info(gl_info))
1516 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1517 gl_info->gl_formats = NULL;
1518 return FALSE;
1521 return TRUE;
1524 /* Context activation is done by the caller. */
1525 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1527 if (!init_format_base_info(gl_info)) return FALSE;
1529 if (!init_format_compression_info(gl_info)) goto fail;
1530 if (!init_format_texture_info(gl_info)) goto fail;
1531 if (!init_format_vertex_info(gl_info)) goto fail;
1533 apply_format_fixups(gl_info);
1534 init_format_fbo_compat_info(gl_info);
1535 init_format_filter_info(gl_info, vendor);
1537 return TRUE;
1539 fail:
1540 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1541 gl_info->gl_formats = NULL;
1542 return FALSE;
1545 const struct wined3d_format_desc *getFormatDescEntry(enum wined3d_format_id format_id,
1546 const struct wined3d_gl_info *gl_info)
1548 int idx = getFmtIdx(format_id);
1550 if (idx == -1)
1552 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1553 debug_d3dformat(format_id), format_id);
1554 /* Get the caller a valid pointer */
1555 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1558 return &gl_info->gl_formats[idx];
1561 UINT wined3d_format_calculate_size(const struct wined3d_format_desc *format, UINT alignment, UINT width, UINT height)
1563 UINT size;
1565 if (format->id == WINED3DFMT_UNKNOWN)
1567 size = 0;
1569 else if (format->Flags & WINED3DFMT_FLAG_COMPRESSED)
1571 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1572 UINT row_count = (height + format->block_height - 1) / format->block_height;
1573 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1575 else
1577 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1580 if (format->heightscale != 0.0f) size *= format->heightscale;
1582 return size;
1585 /*****************************************************************************
1586 * Trace formatting of useful values
1588 const char *debug_d3dformat(enum wined3d_format_id format_id)
1590 switch (format_id)
1592 #define FMT_TO_STR(format_id) case format_id: return #format_id
1593 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1594 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1595 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1596 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1597 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1598 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1599 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1600 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1601 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1602 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1603 FMT_TO_STR(WINED3DFMT_P8_UINT);
1604 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1605 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1606 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1607 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1608 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1609 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1610 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1611 FMT_TO_STR(WINED3DFMT_UYVY);
1612 FMT_TO_STR(WINED3DFMT_YUY2);
1613 FMT_TO_STR(WINED3DFMT_YV12);
1614 FMT_TO_STR(WINED3DFMT_DXT1);
1615 FMT_TO_STR(WINED3DFMT_DXT2);
1616 FMT_TO_STR(WINED3DFMT_DXT3);
1617 FMT_TO_STR(WINED3DFMT_DXT4);
1618 FMT_TO_STR(WINED3DFMT_DXT5);
1619 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1620 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1621 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1622 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1623 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1624 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1625 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1626 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1627 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1628 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1629 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1630 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1631 FMT_TO_STR(WINED3DFMT_ATI2N);
1632 FMT_TO_STR(WINED3DFMT_NVHU);
1633 FMT_TO_STR(WINED3DFMT_NVHS);
1634 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1635 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1636 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1637 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1638 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1639 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1640 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1641 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1642 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1643 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1644 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1645 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1646 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1647 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1648 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1649 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1650 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1651 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1652 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1653 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1654 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1655 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1656 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1657 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1658 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1659 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1660 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1661 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1662 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1663 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1664 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1665 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1666 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1667 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1668 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1669 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1670 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1671 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1672 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1673 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1674 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1675 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1676 FMT_TO_STR(WINED3DFMT_R32_UINT);
1677 FMT_TO_STR(WINED3DFMT_R32_SINT);
1678 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1679 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1680 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1681 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1682 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1683 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1684 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1685 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1686 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1687 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1688 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1689 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1690 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1691 FMT_TO_STR(WINED3DFMT_R16_UINT);
1692 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1693 FMT_TO_STR(WINED3DFMT_R16_SINT);
1694 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1695 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1696 FMT_TO_STR(WINED3DFMT_R8_UINT);
1697 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1698 FMT_TO_STR(WINED3DFMT_R8_SINT);
1699 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1700 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1701 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1702 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1703 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1704 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1705 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1706 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1707 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1708 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1709 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1710 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1711 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1712 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1713 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1714 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1715 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1716 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1717 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1718 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1719 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1720 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1721 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1722 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1723 #undef FMT_TO_STR
1724 default:
1726 char fourcc[5];
1727 fourcc[0] = (char)(format_id);
1728 fourcc[1] = (char)(format_id >> 8);
1729 fourcc[2] = (char)(format_id >> 16);
1730 fourcc[3] = (char)(format_id >> 24);
1731 fourcc[4] = 0;
1732 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1733 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1734 else
1735 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1737 return "unrecognized";
1741 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
1742 switch (devtype) {
1743 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1744 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1745 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1746 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1747 #undef DEVTYPE_TO_STR
1748 default:
1749 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1750 return "unrecognized";
1754 const char *debug_d3dusage(DWORD usage)
1756 char buf[333];
1758 buf[0] = '\0';
1759 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1760 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1761 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1762 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1763 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1764 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1765 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1766 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1767 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1768 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1769 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1770 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1771 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1772 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1773 #undef WINED3DUSAGE_TO_STR
1774 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1776 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1779 const char *debug_d3dusagequery(DWORD usagequery)
1781 char buf[238];
1783 buf[0] = '\0';
1784 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1785 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1786 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1787 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1788 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1789 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1790 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1791 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1792 #undef WINED3DUSAGEQUERY_TO_STR
1793 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1795 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1798 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1799 switch (method) {
1800 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1801 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1802 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1803 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1804 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1805 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1806 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1807 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1808 #undef WINED3DDECLMETHOD_TO_STR
1809 default:
1810 FIXME("Unrecognized %u declaration method!\n", method);
1811 return "unrecognized";
1815 const char* debug_d3ddeclusage(BYTE usage) {
1816 switch (usage) {
1817 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1818 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1819 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1820 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1821 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1822 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1823 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1824 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1825 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1826 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1827 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1828 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1829 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1830 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1831 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1832 #undef WINED3DDECLUSAGE_TO_STR
1833 default:
1834 FIXME("Unrecognized %u declaration usage!\n", usage);
1835 return "unrecognized";
1839 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1840 switch (res) {
1841 #define RES_TO_STR(res) case res: return #res
1842 RES_TO_STR(WINED3DRTYPE_SURFACE);
1843 RES_TO_STR(WINED3DRTYPE_VOLUME);
1844 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1845 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1846 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1847 RES_TO_STR(WINED3DRTYPE_BUFFER);
1848 #undef RES_TO_STR
1849 default:
1850 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1851 return "unrecognized";
1855 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1856 switch (PrimitiveType) {
1857 #define PRIM_TO_STR(prim) case prim: return #prim
1858 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1859 PRIM_TO_STR(WINED3DPT_POINTLIST);
1860 PRIM_TO_STR(WINED3DPT_LINELIST);
1861 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1862 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1863 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1864 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1865 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1866 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1867 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1868 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1869 #undef PRIM_TO_STR
1870 default:
1871 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1872 return "unrecognized";
1876 const char* debug_d3drenderstate(DWORD state) {
1877 switch (state) {
1878 #define D3DSTATE_TO_STR(u) case u: return #u
1879 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1880 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1881 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1882 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1883 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1884 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1885 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1886 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1887 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1888 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1889 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1890 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1891 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1892 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1893 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1894 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1895 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1896 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1897 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1898 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1899 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1900 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1901 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1902 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1903 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1904 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1905 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1906 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1907 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1908 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1909 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1910 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1911 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1912 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1913 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1914 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1915 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1916 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1917 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1918 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1919 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1920 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1921 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1922 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1923 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1924 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1925 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1926 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1927 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1928 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1929 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1930 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1931 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1932 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1933 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1934 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1935 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1936 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1937 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1938 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1939 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1940 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1941 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1942 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1943 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1944 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1945 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1946 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1947 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1948 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1949 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1950 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1951 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1952 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1953 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1954 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1955 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1956 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1957 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1958 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1959 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1960 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1961 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1962 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1963 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1964 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1965 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1966 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1967 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1968 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1969 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1970 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1971 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1972 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1973 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1974 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1975 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1976 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1977 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1978 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1979 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1980 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1981 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1982 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1983 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1984 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1985 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1986 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1987 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1988 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1989 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1990 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1991 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1992 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1993 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1994 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1995 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1996 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1997 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1998 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1999 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
2000 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
2001 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
2002 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
2003 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
2004 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
2005 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
2006 #undef D3DSTATE_TO_STR
2007 default:
2008 FIXME("Unrecognized %u render state!\n", state);
2009 return "unrecognized";
2013 const char* debug_d3dsamplerstate(DWORD state) {
2014 switch (state) {
2015 #define D3DSTATE_TO_STR(u) case u: return #u
2016 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
2017 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
2018 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
2019 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
2020 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
2021 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
2022 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
2023 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
2024 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
2025 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
2026 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
2027 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
2028 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
2029 #undef D3DSTATE_TO_STR
2030 default:
2031 FIXME("Unrecognized %u sampler state!\n", state);
2032 return "unrecognized";
2036 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2037 switch (filter_type) {
2038 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2039 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2040 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2041 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2042 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2043 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2044 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2045 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2046 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2047 #undef D3DTEXTUREFILTERTYPE_TO_STR
2048 default:
2049 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2050 return "unrecognized";
2054 const char* debug_d3dtexturestate(DWORD state) {
2055 switch (state) {
2056 #define D3DSTATE_TO_STR(u) case u: return #u
2057 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
2058 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
2059 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
2060 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
2061 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
2062 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
2063 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
2064 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
2065 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
2066 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
2067 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
2068 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
2069 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
2070 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
2071 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
2072 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
2073 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
2074 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
2075 #undef D3DSTATE_TO_STR
2076 default:
2077 FIXME("Unrecognized %u texture state!\n", state);
2078 return "unrecognized";
2082 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2083 switch (d3dtop) {
2084 #define D3DTOP_TO_STR(u) case u: return #u
2085 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2086 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2087 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2088 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2089 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2090 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2091 D3DTOP_TO_STR(WINED3DTOP_ADD);
2092 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2093 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2094 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2095 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2096 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2097 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2098 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2099 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2100 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2101 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2102 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2103 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2104 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2105 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2106 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2107 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2108 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2109 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2110 D3DTOP_TO_STR(WINED3DTOP_LERP);
2111 #undef D3DTOP_TO_STR
2112 default:
2113 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2114 return "unrecognized";
2118 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2119 switch (tstype) {
2120 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2121 TSTYPE_TO_STR(WINED3DTS_VIEW);
2122 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2123 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2124 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2125 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2126 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2127 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2128 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2129 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2130 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2131 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2132 #undef TSTYPE_TO_STR
2133 default:
2134 if (tstype > 256 && tstype < 512) {
2135 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2136 return ("WINED3DTS_WORLDMATRIX > 0");
2138 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2139 return "unrecognized";
2143 const char *debug_d3dstate(DWORD state)
2145 if (STATE_IS_RENDER(state))
2146 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2147 if (STATE_IS_TEXTURESTAGE(state))
2149 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2150 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2151 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2152 texture_stage, debug_d3dtexturestate(texture_state));
2154 if (STATE_IS_SAMPLER(state))
2155 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2156 if (STATE_IS_PIXELSHADER(state))
2157 return "STATE_PIXELSHADER";
2158 if (STATE_IS_TRANSFORM(state))
2159 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2160 if (STATE_IS_STREAMSRC(state))
2161 return "STATE_STREAMSRC";
2162 if (STATE_IS_INDEXBUFFER(state))
2163 return "STATE_INDEXBUFFER";
2164 if (STATE_IS_VDECL(state))
2165 return "STATE_VDECL";
2166 if (STATE_IS_VSHADER(state))
2167 return "STATE_VSHADER";
2168 if (STATE_IS_VIEWPORT(state))
2169 return "STATE_VIEWPORT";
2170 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2171 return "STATE_VERTEXSHADERCONSTANT";
2172 if (STATE_IS_PIXELSHADERCONSTANT(state))
2173 return "STATE_PIXELSHADERCONSTANT";
2174 if (STATE_IS_ACTIVELIGHT(state))
2175 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2176 if (STATE_IS_SCISSORRECT(state))
2177 return "STATE_SCISSORRECT";
2178 if (STATE_IS_CLIPPLANE(state))
2179 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2180 if (STATE_IS_MATERIAL(state))
2181 return "STATE_MATERIAL";
2182 if (STATE_IS_FRONTFACE(state))
2183 return "STATE_FRONTFACE";
2185 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2188 const char* debug_d3dpool(WINED3DPOOL Pool) {
2189 switch (Pool) {
2190 #define POOL_TO_STR(p) case p: return #p
2191 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2192 POOL_TO_STR(WINED3DPOOL_MANAGED);
2193 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2194 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2195 #undef POOL_TO_STR
2196 default:
2197 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
2198 return "unrecognized";
2202 const char *debug_fbostatus(GLenum status) {
2203 switch(status) {
2204 #define FBOSTATUS_TO_STR(u) case u: return #u
2205 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2206 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2207 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2208 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2209 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2210 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2211 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2212 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2213 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2214 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2215 #undef FBOSTATUS_TO_STR
2216 default:
2217 FIXME("Unrecognied FBO status 0x%08x\n", status);
2218 return "unrecognized";
2222 const char *debug_glerror(GLenum error) {
2223 switch(error) {
2224 #define GLERROR_TO_STR(u) case u: return #u
2225 GLERROR_TO_STR(GL_NO_ERROR);
2226 GLERROR_TO_STR(GL_INVALID_ENUM);
2227 GLERROR_TO_STR(GL_INVALID_VALUE);
2228 GLERROR_TO_STR(GL_INVALID_OPERATION);
2229 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2230 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2231 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2232 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2233 #undef GLERROR_TO_STR
2234 default:
2235 FIXME("Unrecognied GL error 0x%08x\n", error);
2236 return "unrecognized";
2240 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2241 switch(basis) {
2242 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2243 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2244 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2245 default: return "unrecognized";
2249 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2250 switch(degree) {
2251 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2252 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2253 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2254 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2255 default: return "unrecognized";
2259 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2261 switch(source)
2263 #define WINED3D_TO_STR(x) case x: return #x
2264 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2265 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2266 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2267 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2268 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2269 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2270 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2271 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2272 #undef WINED3D_TO_STR
2273 default:
2274 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2275 return "unrecognized";
2279 static const char *debug_complex_fixup(enum complex_fixup fixup)
2281 switch(fixup)
2283 #define WINED3D_TO_STR(x) case x: return #x
2284 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2285 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2286 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2287 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2288 #undef WINED3D_TO_STR
2289 default:
2290 FIXME("Unrecognized complex fixup %#x\n", fixup);
2291 return "unrecognized";
2295 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2297 if (is_complex_fixup(fixup))
2299 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2300 return;
2303 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2304 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2305 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2306 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2309 const char *debug_surflocation(DWORD flag) {
2310 char buf[128];
2312 buf[0] = 0;
2313 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2314 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2315 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2316 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2317 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2320 /*****************************************************************************
2321 * Useful functions mapping GL <-> D3D values
2323 GLenum StencilOp(DWORD op) {
2324 switch(op) {
2325 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2326 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2327 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2328 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2329 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2330 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2331 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2332 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2333 default:
2334 FIXME("Unrecognized stencil op %d\n", op);
2335 return GL_KEEP;
2339 GLenum CompareFunc(DWORD func) {
2340 switch ((WINED3DCMPFUNC)func) {
2341 case WINED3DCMP_NEVER : return GL_NEVER;
2342 case WINED3DCMP_LESS : return GL_LESS;
2343 case WINED3DCMP_EQUAL : return GL_EQUAL;
2344 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2345 case WINED3DCMP_GREATER : return GL_GREATER;
2346 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2347 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2348 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2349 default:
2350 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2351 return 0;
2355 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
2356 if (op == WINED3DTOP_DISABLE) return FALSE;
2357 if (This->stateBlock->textures[stage]) return FALSE;
2359 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2360 && op != WINED3DTOP_SELECTARG2) return TRUE;
2361 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2362 && op != WINED3DTOP_SELECTARG1) return TRUE;
2363 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2364 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2366 return FALSE;
2369 /* Setup this textures matrix according to the texture flags*/
2370 /* GL locking is done by the caller (state handler) */
2371 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2372 enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2374 float mat[16];
2376 glMatrixMode(GL_TEXTURE);
2377 checkGLcall("glMatrixMode(GL_TEXTURE)");
2379 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2380 glLoadIdentity();
2381 checkGLcall("glLoadIdentity()");
2382 return;
2385 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2386 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2387 return;
2390 memcpy(mat, smat, 16 * sizeof(float));
2392 if (flags & WINED3DTTFF_PROJECTED) {
2393 if(!ffp_proj_control) {
2394 switch (flags & ~WINED3DTTFF_PROJECTED) {
2395 case WINED3DTTFF_COUNT2:
2396 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2397 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2398 break;
2399 case WINED3DTTFF_COUNT3:
2400 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2401 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2402 break;
2405 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2406 if(!calculatedCoords) {
2407 switch(vtx_fmt)
2409 case WINED3DFMT_R32_FLOAT:
2410 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2411 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2412 * the input value to the transformation will be 0, so the matrix value is irrelevant
2414 mat[12] = mat[4];
2415 mat[13] = mat[5];
2416 mat[14] = mat[6];
2417 mat[15] = mat[7];
2418 break;
2419 case WINED3DFMT_R32G32_FLOAT:
2420 /* See above, just 3rd and 4th coord
2422 mat[12] = mat[8];
2423 mat[13] = mat[9];
2424 mat[14] = mat[10];
2425 mat[15] = mat[11];
2426 break;
2427 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2428 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2430 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2431 * into a bad place. The division elimination below will apply to make sure the
2432 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2434 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2435 break;
2436 default:
2437 FIXME("Unexpected fixed function texture coord input\n");
2440 if(!ffp_proj_control) {
2441 switch (flags & ~WINED3DTTFF_PROJECTED) {
2442 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2443 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2444 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2445 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2446 * the 4th coord evaluates to 1.0 to eliminate that.
2448 * If the fixed function pipeline is used, the 4th value remains unused,
2449 * so there is no danger in doing this. With vertex shaders we have a
2450 * problem. Should an app hit that problem, the code here would have to
2451 * check for pixel shaders, and the shader has to undo the default gl divide.
2453 * A more serious problem occurs if the app passes 4 coordinates in, and the
2454 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2455 * or a replacement shader
2457 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2462 glLoadMatrixf(mat);
2463 checkGLcall("glLoadMatrixf(mat)");
2466 /* This small helper function is used to convert a bitmask into the number of masked bits */
2467 unsigned int count_bits(unsigned int mask)
2469 unsigned int count;
2470 for (count = 0; mask; ++count)
2472 mask &= mask - 1;
2474 return count;
2477 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2478 * The later function requires individual color components. */
2479 BOOL getColorBits(const struct wined3d_format_desc *format_desc,
2480 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2482 TRACE("format %s.\n", debug_d3dformat(format_desc->id));
2484 switch (format_desc->id)
2486 case WINED3DFMT_B8G8R8X8_UNORM:
2487 case WINED3DFMT_B8G8R8_UNORM:
2488 case WINED3DFMT_B8G8R8A8_UNORM:
2489 case WINED3DFMT_R8G8B8A8_UNORM:
2490 case WINED3DFMT_B10G10R10A2_UNORM:
2491 case WINED3DFMT_B5G5R5X1_UNORM:
2492 case WINED3DFMT_B5G5R5A1_UNORM:
2493 case WINED3DFMT_B5G6R5_UNORM:
2494 case WINED3DFMT_B4G4R4X4_UNORM:
2495 case WINED3DFMT_B4G4R4A4_UNORM:
2496 case WINED3DFMT_B2G3R3_UNORM:
2497 case WINED3DFMT_P8_UINT_A8_UNORM:
2498 case WINED3DFMT_P8_UINT:
2499 break;
2500 default:
2501 FIXME("Unsupported format %s.\n", debug_d3dformat(format_desc->id));
2502 return FALSE;
2505 *redSize = count_bits(format_desc->red_mask);
2506 *greenSize = count_bits(format_desc->green_mask);
2507 *blueSize = count_bits(format_desc->blue_mask);
2508 *alphaSize = count_bits(format_desc->alpha_mask);
2509 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2511 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2512 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->id));
2513 return TRUE;
2516 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2517 BOOL getDepthStencilBits(const struct wined3d_format_desc *format_desc, short *depthSize, short *stencilSize)
2519 TRACE("format %s.\n", debug_d3dformat(format_desc->id));
2521 switch (format_desc->id)
2523 case WINED3DFMT_D16_LOCKABLE:
2524 case WINED3DFMT_D16_UNORM:
2525 case WINED3DFMT_S1_UINT_D15_UNORM:
2526 case WINED3DFMT_X8D24_UNORM:
2527 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2528 case WINED3DFMT_D24_UNORM_S8_UINT:
2529 case WINED3DFMT_S8_UINT_D24_FLOAT:
2530 case WINED3DFMT_D32_UNORM:
2531 case WINED3DFMT_D32_FLOAT:
2532 break;
2533 default:
2534 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format_desc->id));
2535 return FALSE;
2538 *depthSize = format_desc->depth_size;
2539 *stencilSize = format_desc->stencil_size;
2541 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2542 *depthSize, *stencilSize, debug_d3dformat(format_desc->id));
2543 return TRUE;
2546 DWORD wined3d_format_convert_from_float(const struct wined3d_format_desc *format, const WINED3DCOLORVALUE *color)
2548 enum wined3d_format_id destfmt = format->id;
2549 unsigned int r, g, b, a;
2550 DWORD ret;
2552 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2553 color->r, color->g, color->b, color->a, debug_d3dformat(destfmt));
2555 r = (DWORD)((color->r * 255.0f) + 0.5f);
2556 g = (DWORD)((color->g * 255.0f) + 0.5f);
2557 b = (DWORD)((color->b * 255.0f) + 0.5f);
2558 a = (DWORD)((color->a * 255.0f) + 0.5f);
2560 switch(destfmt)
2562 case WINED3DFMT_B8G8R8A8_UNORM:
2563 case WINED3DFMT_B8G8R8X8_UNORM:
2564 case WINED3DFMT_B8G8R8_UNORM:
2565 ret = b;
2566 ret |= g << 8;
2567 ret |= r << 16;
2568 ret |= a << 24;
2569 TRACE("Returning 0x%08x.\n", ret);
2570 return ret;
2573 case WINED3DFMT_B5G6R5_UNORM:
2574 if(r == 0xff && g == 0xff && b == 0xff) return 0xffff;
2575 r = (r * 32) / 256;
2576 g = (g * 64) / 256;
2577 b = (b * 32) / 256;
2578 ret = r << 11;
2579 ret |= g << 5;
2580 ret |= b;
2581 TRACE("Returning %08x\n", ret);
2582 return ret;
2584 case WINED3DFMT_B5G5R5X1_UNORM:
2585 case WINED3DFMT_B5G5R5A1_UNORM:
2586 a = (a * 2) / 256;
2587 r = (r * 32) / 256;
2588 g = (g * 32) / 256;
2589 b = (b * 32) / 256;
2590 ret = a << 15;
2591 ret |= r << 10;
2592 ret |= g << 5;
2593 ret |= b << 0;
2594 TRACE("Returning %08x\n", ret);
2595 return ret;
2597 case WINED3DFMT_A8_UNORM:
2598 TRACE("Returning %08x\n", a);
2599 return a;
2601 case WINED3DFMT_B4G4R4X4_UNORM:
2602 case WINED3DFMT_B4G4R4A4_UNORM:
2603 a = (a * 16) / 256;
2604 r = (r * 16) / 256;
2605 g = (g * 16) / 256;
2606 b = (b * 16) / 256;
2607 ret = a << 12;
2608 ret |= r << 8;
2609 ret |= g << 4;
2610 ret |= b << 0;
2611 TRACE("Returning %08x\n", ret);
2612 return ret;
2614 case WINED3DFMT_B2G3R3_UNORM:
2615 r = (r * 8) / 256;
2616 g = (g * 8) / 256;
2617 b = (b * 4) / 256;
2618 ret = r << 5;
2619 ret |= g << 2;
2620 ret |= b << 0;
2621 TRACE("Returning %08x\n", ret);
2622 return ret;
2624 case WINED3DFMT_R8G8B8X8_UNORM:
2625 case WINED3DFMT_R8G8B8A8_UNORM:
2626 ret = a << 24;
2627 ret |= b << 16;
2628 ret |= g << 8;
2629 ret |= r << 0;
2630 TRACE("Returning %08x\n", ret);
2631 return ret;
2633 case WINED3DFMT_B10G10R10A2_UNORM:
2634 a = (a * 4) / 256;
2635 r = (r * 1024) / 256;
2636 g = (g * 1024) / 256;
2637 b = (b * 1024) / 256;
2638 ret = a << 30;
2639 ret |= r << 20;
2640 ret |= g << 10;
2641 ret |= b << 0;
2642 TRACE("Returning %08x\n", ret);
2643 return ret;
2645 case WINED3DFMT_R10G10B10A2_UNORM:
2646 a = (a * 4) / 256;
2647 r = (r * 1024) / 256;
2648 g = (g * 1024) / 256;
2649 b = (b * 1024) / 256;
2650 ret = a << 30;
2651 ret |= b << 20;
2652 ret |= g << 10;
2653 ret |= r << 0;
2654 TRACE("Returning %08x\n", ret);
2655 return ret;
2657 default:
2658 FIXME("Add a COLORFILL conversion for format %s\n", debug_d3dformat(destfmt));
2659 return 0;
2663 /* DirectDraw stuff */
2664 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2666 switch (depth)
2668 case 8: return WINED3DFMT_P8_UINT;
2669 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2670 case 16: return WINED3DFMT_B5G6R5_UNORM;
2671 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2672 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2673 default: return WINED3DFMT_UNKNOWN;
2677 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2678 WINED3DMATRIX temp;
2680 /* Now do the multiplication 'by hand'.
2681 I know that all this could be optimised, but this will be done later :-) */
2682 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);
2683 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);
2684 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);
2685 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);
2687 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);
2688 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);
2689 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);
2690 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);
2692 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);
2693 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);
2694 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);
2695 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);
2697 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);
2698 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);
2699 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);
2700 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);
2702 /* And copy the new matrix in the good storage.. */
2703 memcpy(dest, &temp, 16 * sizeof(float));
2706 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2707 DWORD size = 0;
2708 int i;
2709 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2711 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2712 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2713 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2714 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2715 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2716 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2717 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2718 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2719 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2720 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2721 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2722 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2723 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2724 default: ERR("Unexpected position mask\n");
2726 for (i = 0; i < numTextures; i++) {
2727 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2730 return size;
2733 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2734 #define ARG1 0x01
2735 #define ARG2 0x02
2736 #define ARG0 0x04
2737 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2738 /* undefined */ 0,
2739 /* D3DTOP_DISABLE */ 0,
2740 /* D3DTOP_SELECTARG1 */ ARG1,
2741 /* D3DTOP_SELECTARG2 */ ARG2,
2742 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2743 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2744 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2745 /* D3DTOP_ADD */ ARG1 | ARG2,
2746 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2747 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2748 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2749 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2750 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2751 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2752 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2753 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2754 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2755 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2756 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2757 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2758 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2759 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2760 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2761 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2762 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2763 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2764 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2766 unsigned int i;
2767 DWORD ttff;
2768 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2769 IWineD3DDeviceImpl *device = stateblock->device;
2770 IWineD3DSurfaceImpl *rt = device->render_targets[0];
2771 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2773 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2775 IWineD3DBaseTextureImpl *texture;
2776 settings->op[i].padding = 0;
2777 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2778 settings->op[i].cop = WINED3DTOP_DISABLE;
2779 settings->op[i].aop = WINED3DTOP_DISABLE;
2780 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2781 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2782 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2783 settings->op[i].dst = resultreg;
2784 settings->op[i].tex_type = tex_1d;
2785 settings->op[i].projected = proj_none;
2786 i++;
2787 break;
2790 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2791 if(texture) {
2792 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2793 if(ignore_textype) {
2794 settings->op[i].tex_type = tex_1d;
2795 } else {
2796 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2797 case GL_TEXTURE_1D:
2798 settings->op[i].tex_type = tex_1d;
2799 break;
2800 case GL_TEXTURE_2D:
2801 settings->op[i].tex_type = tex_2d;
2802 break;
2803 case GL_TEXTURE_3D:
2804 settings->op[i].tex_type = tex_3d;
2805 break;
2806 case GL_TEXTURE_CUBE_MAP_ARB:
2807 settings->op[i].tex_type = tex_cube;
2808 break;
2809 case GL_TEXTURE_RECTANGLE_ARB:
2810 settings->op[i].tex_type = tex_rect;
2811 break;
2814 } else {
2815 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2816 settings->op[i].tex_type = tex_1d;
2819 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2820 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2822 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2823 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2824 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2826 if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2827 carg0 = ARG_UNUSED;
2828 carg2 = ARG_UNUSED;
2829 carg1 = WINED3DTA_CURRENT;
2830 cop = WINED3DTOP_SELECTARG1;
2833 if(cop == WINED3DTOP_DOTPRODUCT3) {
2834 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2835 * the color result to the alpha component of the destination
2837 aop = cop;
2838 aarg1 = carg1;
2839 aarg2 = carg2;
2840 aarg0 = carg0;
2841 } else {
2842 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2843 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2844 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2847 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2849 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2851 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2853 IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)stateblock->textures[0];
2854 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
2856 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2858 if (aop == WINED3DTOP_DISABLE)
2860 aarg1 = WINED3DTA_TEXTURE;
2861 aop = WINED3DTOP_SELECTARG1;
2863 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2865 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2867 aarg2 = WINED3DTA_TEXTURE;
2868 aop = WINED3DTOP_MODULATE;
2870 else aarg1 = WINED3DTA_TEXTURE;
2872 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2874 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2876 aarg1 = WINED3DTA_TEXTURE;
2877 aop = WINED3DTOP_MODULATE;
2879 else aarg2 = WINED3DTA_TEXTURE;
2885 if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2886 aarg0 = ARG_UNUSED;
2887 aarg2 = ARG_UNUSED;
2888 aarg1 = WINED3DTA_CURRENT;
2889 aop = WINED3DTOP_SELECTARG1;
2892 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2893 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2894 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2895 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2896 settings->op[i].projected = proj_count3;
2897 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2898 settings->op[i].projected = proj_count4;
2899 } else {
2900 settings->op[i].projected = proj_none;
2902 } else {
2903 settings->op[i].projected = proj_none;
2906 settings->op[i].cop = cop;
2907 settings->op[i].aop = aop;
2908 settings->op[i].carg0 = carg0;
2909 settings->op[i].carg1 = carg1;
2910 settings->op[i].carg2 = carg2;
2911 settings->op[i].aarg0 = aarg0;
2912 settings->op[i].aarg1 = aarg1;
2913 settings->op[i].aarg2 = aarg2;
2915 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2916 settings->op[i].dst = tempreg;
2917 } else {
2918 settings->op[i].dst = resultreg;
2922 /* Clear unsupported stages */
2923 for(; i < MAX_TEXTURES; i++) {
2924 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2927 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2928 settings->fog = FOG_OFF;
2929 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2930 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2931 settings->fog = FOG_LINEAR;
2932 } else {
2933 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2934 case WINED3DFOG_NONE:
2935 case WINED3DFOG_LINEAR:
2936 settings->fog = FOG_LINEAR;
2937 break;
2938 case WINED3DFOG_EXP:
2939 settings->fog = FOG_EXP;
2940 break;
2941 case WINED3DFOG_EXP2:
2942 settings->fog = FOG_EXP2;
2943 break;
2946 } else {
2947 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2948 case WINED3DFOG_LINEAR:
2949 settings->fog = FOG_LINEAR;
2950 break;
2951 case WINED3DFOG_EXP:
2952 settings->fog = FOG_EXP;
2953 break;
2954 case WINED3DFOG_EXP2:
2955 settings->fog = FOG_EXP2;
2956 break;
2959 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE] &&
2960 rt->resource.format_desc->Flags & WINED3DFMT_FLAG_SRGB_WRITE) {
2961 settings->sRGB_write = 1;
2962 } else {
2963 settings->sRGB_write = 0;
2965 if(device->vs_clipping || !use_vs(stateblock) || !stateblock->renderState[WINED3DRS_CLIPPING] ||
2966 !stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
2967 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2968 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2969 * if no clipplane is enabled
2971 settings->emul_clipplanes = 0;
2972 } else {
2973 settings->emul_clipplanes = 1;
2977 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2978 const struct ffp_frag_settings *settings)
2980 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2981 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2984 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2986 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2987 * whereas desc points to an extended structure with implementation specific parts. */
2988 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2990 ERR("Failed to insert ffp frag shader.\n");
2994 /* Activates the texture dimension according to the bound D3D texture.
2995 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2996 * Requires the caller to activate the correct unit before
2998 /* GL locking is done by the caller (state handler) */
2999 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3001 const struct wined3d_gl_info *gl_info = context->gl_info;
3003 if (stateblock->textures[stage])
3005 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
3006 case GL_TEXTURE_2D:
3007 glDisable(GL_TEXTURE_3D);
3008 checkGLcall("glDisable(GL_TEXTURE_3D)");
3009 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3011 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3012 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3014 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3016 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3017 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3019 glEnable(GL_TEXTURE_2D);
3020 checkGLcall("glEnable(GL_TEXTURE_2D)");
3021 break;
3022 case GL_TEXTURE_RECTANGLE_ARB:
3023 glDisable(GL_TEXTURE_2D);
3024 checkGLcall("glDisable(GL_TEXTURE_2D)");
3025 glDisable(GL_TEXTURE_3D);
3026 checkGLcall("glDisable(GL_TEXTURE_3D)");
3027 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3029 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3030 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3032 glEnable(GL_TEXTURE_RECTANGLE_ARB);
3033 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3034 break;
3035 case GL_TEXTURE_3D:
3036 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3038 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3039 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3041 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3043 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3044 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3046 glDisable(GL_TEXTURE_2D);
3047 checkGLcall("glDisable(GL_TEXTURE_2D)");
3048 glEnable(GL_TEXTURE_3D);
3049 checkGLcall("glEnable(GL_TEXTURE_3D)");
3050 break;
3051 case GL_TEXTURE_CUBE_MAP_ARB:
3052 glDisable(GL_TEXTURE_2D);
3053 checkGLcall("glDisable(GL_TEXTURE_2D)");
3054 glDisable(GL_TEXTURE_3D);
3055 checkGLcall("glDisable(GL_TEXTURE_3D)");
3056 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3058 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3059 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3061 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3062 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3063 break;
3065 } else {
3066 glEnable(GL_TEXTURE_2D);
3067 checkGLcall("glEnable(GL_TEXTURE_2D)");
3068 glDisable(GL_TEXTURE_3D);
3069 checkGLcall("glDisable(GL_TEXTURE_3D)");
3070 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3072 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3073 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3075 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3077 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3078 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3080 /* Binding textures is done by samplers. A dummy texture will be bound */
3084 /* GL locking is done by the caller (state handler) */
3085 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3087 DWORD sampler = state - STATE_SAMPLER(0);
3088 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3090 /* No need to enable / disable anything here for unused samplers. The tex_colorop
3091 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3092 * will take care of this business
3094 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3095 if(sampler >= stateblock->lowest_disabled_stage) return;
3096 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3098 texture_activate_dimensions(sampler, stateblock, context);
3101 void *wined3d_rb_alloc(size_t size)
3103 return HeapAlloc(GetProcessHeap(), 0, size);
3106 void *wined3d_rb_realloc(void *ptr, size_t size)
3108 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3111 void wined3d_rb_free(void *ptr)
3113 HeapFree(GetProcessHeap(), 0, ptr);
3116 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3118 const struct ffp_frag_settings *ka = key;
3119 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3121 return memcmp(ka, kb, sizeof(*ka));
3124 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3126 wined3d_rb_alloc,
3127 wined3d_rb_realloc,
3128 wined3d_rb_free,
3129 ffp_frag_program_key_compare,
3132 UINT wined3d_log2i(UINT32 x)
3134 static const UINT l[] =
3136 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3137 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3138 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3139 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3140 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3141 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3142 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3143 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3144 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3145 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3146 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3147 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3148 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3149 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3150 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3151 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3153 UINT32 i;
3155 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3158 /* Set the shader type for this device, depending on the given capabilities
3159 * and the user preferences in wined3d_settings. */
3160 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3162 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3164 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3165 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3167 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3168 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3169 * shaders only on this card. */
3170 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3171 else *vs_selected = SHADER_GLSL;
3173 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3174 else *vs_selected = SHADER_NONE;
3176 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3177 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3178 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3179 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3180 else *ps_selected = SHADER_NONE;