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