wined3d: Move A4L4 conversion to the formats table.
[wine/multimedia.git] / dlls / wined3d / utils.c
blob5ebf92d713abbc2a07a502dfc22a6eb275663e51
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,
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,
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,
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,
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,
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,
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 WINED3D_GL_EXT_NONE, NULL},
663 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
664 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
665 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
666 WINED3D_GL_EXT_NONE, NULL},
667 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
668 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
669 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
670 WINED3D_GL_EXT_NONE, NULL},
671 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
672 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
673 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
674 WINED3D_GL_EXT_NONE, NULL},
675 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
676 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
677 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
678 WINED3D_GL_EXT_NONE, NULL},
679 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
680 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
681 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
682 WINED3D_GL_EXT_NONE, NULL},
683 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
684 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
685 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
686 WINED3D_GL_EXT_NONE, NULL},
687 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
688 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
689 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
690 WINED3D_GL_EXT_NONE, NULL},
691 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
692 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
693 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
694 WINED3D_GL_EXT_NONE, NULL},
695 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
696 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
697 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
698 WINED3D_GL_EXT_NONE, NULL},
699 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
700 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
701 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
702 WINED3D_GL_EXT_NONE, NULL},
703 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
704 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
705 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
706 WINED3D_GL_EXT_NONE, NULL},
707 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
708 GL_RGB, GL_UNSIGNED_SHORT, 6,
709 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
710 WINED3D_GL_EXT_NONE, &convert_r16g16},
711 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
712 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
713 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
714 WINED3D_GL_EXT_NONE, NULL},
715 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
716 GL_RGBA, GL_UNSIGNED_SHORT, 0,
717 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
718 WINED3D_GL_EXT_NONE, NULL},
719 /* Luminance */
720 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
721 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
722 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
723 WINED3D_GL_EXT_NONE, NULL},
724 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
725 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
726 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
727 WINED3D_GL_EXT_NONE, NULL},
728 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
729 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
731 WINED3D_GL_EXT_NONE, &convert_l4a4_unorm},
732 /* Bump mapping stuff */
733 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
734 GL_BGR, GL_UNSIGNED_BYTE, 3,
735 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
736 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm},
737 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
738 GL_DSDT_NV, GL_BYTE, 0,
739 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
740 NV_TEXTURE_SHADER, NULL},
741 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
742 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
743 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
744 WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm},
745 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
746 GL_DSDT_MAG_NV, GL_BYTE, 3,
747 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
748 NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv},
749 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
750 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
751 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
752 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm},
753 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
754 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
755 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
756 NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv},
757 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
758 GL_BGRA, GL_UNSIGNED_BYTE, 4,
759 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
760 WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm},
761 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
762 GL_RGBA, GL_BYTE, 0,
763 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
764 NV_TEXTURE_SHADER, NULL},
765 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
766 GL_BGR, GL_UNSIGNED_SHORT, 6,
767 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
768 WINED3D_GL_EXT_NONE, &convert_r16g16_snorm},
769 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
770 GL_HILO_NV, GL_SHORT, 0,
771 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
772 NV_TEXTURE_SHADER, NULL},
773 /* Depth stencil formats */
774 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
775 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
776 WINED3DFMT_FLAG_DEPTH,
777 ARB_DEPTH_TEXTURE, NULL},
778 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
779 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
780 WINED3DFMT_FLAG_DEPTH,
781 ARB_DEPTH_TEXTURE, NULL},
782 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
783 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
784 WINED3DFMT_FLAG_DEPTH,
785 ARB_DEPTH_TEXTURE, NULL},
786 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
787 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
788 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
789 EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm},
790 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
791 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
792 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
793 ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm},
794 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
795 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
796 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
797 ARB_DEPTH_TEXTURE, NULL},
798 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
799 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
800 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
801 EXT_PACKED_DEPTH_STENCIL, NULL},
802 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
803 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
804 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
805 ARB_FRAMEBUFFER_OBJECT, NULL},
806 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
807 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
808 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
809 ARB_DEPTH_TEXTURE, NULL},
810 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
811 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
812 WINED3DFMT_FLAG_DEPTH,
813 ARB_DEPTH_TEXTURE, NULL},
814 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
815 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
816 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
817 EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm},
818 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
819 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
820 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
821 ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm},
822 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
823 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
824 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
825 ARB_DEPTH_TEXTURE, NULL},
826 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
827 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
828 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
829 WINED3D_GL_EXT_NONE, NULL},
830 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
831 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
832 WINED3DFMT_FLAG_DEPTH,
833 ARB_DEPTH_BUFFER_FLOAT, NULL},
834 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
835 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
836 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
837 ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float},
838 /* Vendor-specific formats */
839 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
840 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
842 ATI_TEXTURE_COMPRESSION_3DC, NULL},
843 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, 0,
844 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
846 EXT_TEXTURE_COMPRESSION_RGTC, NULL},
849 static inline int getFmtIdx(WINED3DFORMAT fmt) {
850 /* First check if the format is at the position of its value.
851 * This will catch the argb formats before the loop is entered
853 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
854 return fmt;
855 } else {
856 unsigned int i;
857 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
858 if(formats[i].format == fmt) {
859 return i;
863 return -1;
866 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
868 UINT format_count = sizeof(formats) / sizeof(*formats);
869 UINT i;
871 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->gl_formats));
872 if (!gl_info->gl_formats)
874 ERR("Failed to allocate memory.\n");
875 return FALSE;
878 for (i = 0; i < format_count; ++i)
880 struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
881 desc->format = formats[i].format;
882 desc->red_mask = formats[i].redMask;
883 desc->green_mask = formats[i].greenMask;
884 desc->blue_mask = formats[i].blueMask;
885 desc->alpha_mask = formats[i].alphaMask;
886 desc->byte_count = formats[i].bpp;
887 desc->depth_size = formats[i].depthSize;
888 desc->stencil_size = formats[i].stencilSize;
891 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
893 int fmt_idx = getFmtIdx(format_base_flags[i].format);
895 if (fmt_idx == -1)
897 ERR("Format %s (%#x) not found.\n",
898 debug_d3dformat(format_base_flags[i].format), format_base_flags[i].format);
899 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
900 return FALSE;
903 gl_info->gl_formats[fmt_idx].Flags |= format_base_flags[i].flags;
906 return TRUE;
909 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
911 unsigned int i;
913 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
915 struct wined3d_format_desc *format_desc;
916 int fmt_idx = getFmtIdx(format_compression_info[i].format);
918 if (fmt_idx == -1)
920 ERR("Format %s (%#x) not found.\n",
921 debug_d3dformat(format_compression_info[i].format), format_compression_info[i].format);
922 return FALSE;
925 format_desc = &gl_info->gl_formats[fmt_idx];
926 format_desc->block_width = format_compression_info[i].block_width;
927 format_desc->block_height = format_compression_info[i].block_height;
928 format_desc->block_byte_count = format_compression_info[i].block_byte_count;
929 format_desc->Flags |= WINED3DFMT_FLAG_COMPRESSED;
932 return TRUE;
935 /* Context activation is done by the caller. */
936 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format_desc *format_desc)
938 /* Check if the default internal format is supported as a frame buffer
939 * target, otherwise fall back to the render target internal.
941 * Try to stick to the standard format if possible, this limits precision differences. */
942 GLenum status;
943 GLuint tex;
945 ENTER_GL();
947 while(glGetError());
948 glDisable(GL_BLEND);
950 glGenTextures(1, &tex);
951 glBindTexture(GL_TEXTURE_2D, tex);
953 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glInternal, 16, 16, 0,
954 format_desc->glFormat, format_desc->glType, NULL);
955 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
956 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
958 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
960 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
961 checkGLcall("Framebuffer format check");
963 if (status == GL_FRAMEBUFFER_COMPLETE)
965 TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(format_desc->format));
966 format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
967 format_desc->rtInternal = format_desc->glInternal;
969 else
971 if (!format_desc->rtInternal)
973 if (format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)
975 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
976 " and no fallback specified.\n", debug_d3dformat(format_desc->format));
977 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
979 else
981 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format_desc->format));
983 format_desc->rtInternal = format_desc->glInternal;
985 else
987 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
988 debug_d3dformat(format_desc->format));
990 while(glGetError());
992 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
994 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->rtInternal, 16, 16, 0,
995 format_desc->glFormat, format_desc->glType, NULL);
996 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
997 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
999 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1001 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1002 checkGLcall("Framebuffer format check");
1004 if (status == GL_FRAMEBUFFER_COMPLETE)
1006 TRACE("Format %s rtInternal format is supported as FBO color attachment\n",
1007 debug_d3dformat(format_desc->format));
1009 else
1011 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1012 debug_d3dformat(format_desc->format));
1013 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1018 if (status == GL_FRAMEBUFFER_COMPLETE && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1020 GLuint rb;
1022 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1023 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1025 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1026 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1027 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1028 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1029 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1030 checkGLcall("RB attachment");
1033 glEnable(GL_BLEND);
1034 glClear(GL_COLOR_BUFFER_BIT);
1035 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1037 while(glGetError());
1038 TRACE("Format doesn't support post-pixelshader blending.\n");
1039 format_desc->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1042 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1043 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1045 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1046 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1047 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1048 checkGLcall("RB cleanup");
1052 glDeleteTextures(1, &tex);
1054 LEAVE_GL();
1057 /* Context activation is done by the caller. */
1058 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1060 unsigned int i;
1061 GLuint fbo;
1063 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1065 ENTER_GL();
1067 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1068 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1070 LEAVE_GL();
1073 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1075 struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
1077 if (!desc->glInternal) continue;
1079 if (desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1081 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1082 debug_d3dformat(desc->format));
1083 continue;
1086 if (desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
1088 TRACE("Skipping format %s because it's a compressed format.\n",
1089 debug_d3dformat(desc->format));
1090 continue;
1093 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1095 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc->format));
1096 check_fbo_compat(gl_info, desc);
1098 else
1100 desc->rtInternal = desc->glInternal;
1104 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1106 ENTER_GL();
1108 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1110 LEAVE_GL();
1114 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1116 unsigned int i;
1118 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1120 int fmt_idx = getFmtIdx(format_texture_info[i].format);
1121 struct wined3d_format_desc *desc;
1123 if (fmt_idx == -1)
1125 ERR("Format %s (%#x) not found.\n",
1126 debug_d3dformat(format_texture_info[i].format), format_texture_info[i].format);
1127 return FALSE;
1130 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1132 desc = &gl_info->gl_formats[fmt_idx];
1133 desc->glInternal = format_texture_info[i].gl_internal;
1134 desc->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1135 desc->rtInternal = format_texture_info[i].gl_rt_internal;
1136 desc->glFormat = format_texture_info[i].gl_format;
1137 desc->glType = format_texture_info[i].gl_type;
1138 desc->color_fixup = COLOR_FIXUP_IDENTITY;
1139 desc->Flags |= format_texture_info[i].flags;
1140 desc->heightscale = 1.0f;
1142 /* Texture conversion stuff */
1143 desc->convert = format_texture_info[i].convert;
1144 desc->conv_byte_count = format_texture_info[i].conv_byte_count;
1147 return TRUE;
1150 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1152 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1153 c1 >>= 8; c2 >>= 8;
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 return TRUE;
1162 /* A context is provided by the caller */
1163 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1165 GLuint tex, fbo, buffer;
1166 const DWORD data[] = {0x00000000, 0xffffffff};
1167 DWORD readback[16 * 1];
1168 BOOL ret = FALSE;
1170 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1171 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1172 * falling back to software. If this changes in the future this code will get fooled and
1173 * apps might hit the software path due to incorrectly advertised caps.
1175 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1176 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1177 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1180 ENTER_GL();
1181 while(glGetError());
1183 glGenTextures(1, &buffer);
1184 glBindTexture(GL_TEXTURE_2D, buffer);
1185 memset(readback, 0x7e, sizeof(readback));
1186 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1187 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1188 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1189 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1190 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1191 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1193 glGenTextures(1, &tex);
1194 glBindTexture(GL_TEXTURE_2D, tex);
1195 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1196 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1197 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1198 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1199 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1200 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1201 glEnable(GL_TEXTURE_2D);
1203 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1204 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1205 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1206 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1208 glViewport(0, 0, 16, 1);
1209 glDisable(GL_LIGHTING);
1210 glMatrixMode(GL_MODELVIEW);
1211 glLoadIdentity();
1212 glMatrixMode(GL_PROJECTION);
1213 glLoadIdentity();
1215 glClearColor(0, 1, 0, 0);
1216 glClear(GL_COLOR_BUFFER_BIT);
1218 glBegin(GL_TRIANGLE_STRIP);
1219 glTexCoord2f(0.0, 0.0);
1220 glVertex2f(-1.0f, -1.0f);
1221 glTexCoord2f(1.0, 0.0);
1222 glVertex2f(1.0f, -1.0f);
1223 glTexCoord2f(0.0, 1.0);
1224 glVertex2f(-1.0f, 1.0f);
1225 glTexCoord2f(1.0, 1.0);
1226 glVertex2f(1.0f, 1.0f);
1227 glEnd();
1229 glBindTexture(GL_TEXTURE_2D, buffer);
1230 memset(readback, 0x7f, sizeof(readback));
1231 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1232 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1233 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1235 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1236 readback[6], readback[9]);
1237 ret = FALSE;
1239 else
1241 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1242 readback[6], readback[9]);
1243 ret = TRUE;
1246 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1247 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1248 glDeleteTextures(1, &tex);
1249 glDeleteTextures(1, &buffer);
1251 if(glGetError())
1253 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1254 ret = FALSE;
1256 LEAVE_GL();
1257 return ret;
1260 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1262 struct wined3d_format_desc *desc;
1263 unsigned int fmt_idx, i;
1264 WINED3DFORMAT fmts16[] = {
1265 WINED3DFMT_R16_FLOAT,
1266 WINED3DFMT_R16G16_FLOAT,
1267 WINED3DFMT_R16G16B16A16_FLOAT,
1269 BOOL filtered;
1271 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1273 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1274 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1276 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1277 filtered = TRUE;
1279 else if (gl_info->limits.glsl_varyings > 44)
1281 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1282 filtered = TRUE;
1284 else
1286 TRACE("Assuming no float16 blending\n");
1287 filtered = FALSE;
1290 if(filtered)
1292 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1294 fmt_idx = getFmtIdx(fmts16[i]);
1295 gl_info->gl_formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
1298 return;
1301 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1303 fmt_idx = getFmtIdx(fmts16[i]);
1304 desc = &gl_info->gl_formats[fmt_idx];
1305 if(!desc->glInternal) continue; /* Not supported by GL */
1307 filtered = check_filter(gl_info, gl_info->gl_formats[fmt_idx].glInternal);
1308 if(filtered)
1310 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1311 desc->Flags |= WINED3DFMT_FLAG_FILTERING;
1313 else
1315 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1320 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1322 int idx;
1324 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1325 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1326 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1328 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1329 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1330 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1332 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1333 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1334 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1336 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1337 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1338 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1340 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1341 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1342 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1344 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1345 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1346 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1347 * the only driver that implements it(fglrx) has a buggy implementation.
1349 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1350 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1351 * conversion for this format.
1353 if (!gl_info->supported[NV_TEXTURE_SHADER])
1355 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1356 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1357 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1358 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1359 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1360 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1362 else
1364 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1365 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1366 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1368 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1369 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1370 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1373 if (!gl_info->supported[NV_TEXTURE_SHADER])
1375 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1376 * with each other
1378 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1379 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1380 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1381 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1382 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1383 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1384 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1385 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1386 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1388 else
1390 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1391 * are converted at surface loading time, but they do not need any modification in
1392 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1393 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1397 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1399 idx = getFmtIdx(WINED3DFMT_ATI2N);
1400 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1401 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1403 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1405 idx = getFmtIdx(WINED3DFMT_ATI2N);
1406 gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
1407 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1410 if (!gl_info->supported[APPLE_YCBCR_422])
1412 idx = getFmtIdx(WINED3DFMT_YUY2);
1413 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1415 idx = getFmtIdx(WINED3DFMT_UYVY);
1416 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1419 idx = getFmtIdx(WINED3DFMT_YV12);
1420 gl_info->gl_formats[idx].heightscale = 1.5f;
1421 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1423 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1425 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1426 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1429 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1431 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1432 gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
1435 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1437 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1438 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1439 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1440 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1442 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1443 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1447 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1449 unsigned int i;
1451 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1453 struct wined3d_format_desc *format_desc;
1454 int fmt_idx = getFmtIdx(format_vertex_info[i].format);
1456 if (fmt_idx == -1)
1458 ERR("Format %s (%#x) not found.\n",
1459 debug_d3dformat(format_vertex_info[i].format), format_vertex_info[i].format);
1460 return FALSE;
1463 format_desc = &gl_info->gl_formats[fmt_idx];
1464 format_desc->emit_idx = format_vertex_info[i].emit_idx;
1465 format_desc->component_count = format_vertex_info[i].component_count;
1466 format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1467 format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1468 format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
1469 format_desc->component_size = format_vertex_info[i].component_size;
1472 return TRUE;
1475 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1477 if (!init_format_base_info(gl_info)) return FALSE;
1479 if (!init_format_compression_info(gl_info))
1481 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1482 gl_info->gl_formats = NULL;
1483 return FALSE;
1486 return TRUE;
1489 /* Context activation is done by the caller. */
1490 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1492 if (!init_format_base_info(gl_info)) return FALSE;
1494 if (!init_format_compression_info(gl_info)) goto fail;
1495 if (!init_format_texture_info(gl_info)) goto fail;
1496 if (!init_format_vertex_info(gl_info)) goto fail;
1498 apply_format_fixups(gl_info);
1499 init_format_fbo_compat_info(gl_info);
1500 init_format_filter_info(gl_info, vendor);
1502 return TRUE;
1504 fail:
1505 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1506 gl_info->gl_formats = NULL;
1507 return FALSE;
1510 const struct wined3d_format_desc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info)
1512 int idx = getFmtIdx(fmt);
1514 if(idx == -1) {
1515 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
1516 /* Get the caller a valid pointer */
1517 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1520 return &gl_info->gl_formats[idx];
1523 /*****************************************************************************
1524 * Trace formatting of useful values
1526 const char* debug_d3dformat(WINED3DFORMAT fmt) {
1527 switch (fmt) {
1528 #define FMT_TO_STR(fmt) case fmt: return #fmt
1529 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1530 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1531 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1532 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1533 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1534 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1535 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1536 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1537 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1538 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1539 FMT_TO_STR(WINED3DFMT_P8_UINT);
1540 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1541 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1542 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1543 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1544 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1545 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1546 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1547 FMT_TO_STR(WINED3DFMT_UYVY);
1548 FMT_TO_STR(WINED3DFMT_YUY2);
1549 FMT_TO_STR(WINED3DFMT_YV12);
1550 FMT_TO_STR(WINED3DFMT_DXT1);
1551 FMT_TO_STR(WINED3DFMT_DXT2);
1552 FMT_TO_STR(WINED3DFMT_DXT3);
1553 FMT_TO_STR(WINED3DFMT_DXT4);
1554 FMT_TO_STR(WINED3DFMT_DXT5);
1555 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1556 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1557 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1558 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1559 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1560 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1561 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1562 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1563 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1564 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1565 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1566 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1567 FMT_TO_STR(WINED3DFMT_ATI2N);
1568 FMT_TO_STR(WINED3DFMT_NVHU);
1569 FMT_TO_STR(WINED3DFMT_NVHS);
1570 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1571 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1572 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1573 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1574 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1575 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1576 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1577 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1578 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1579 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1580 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1581 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1582 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1583 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1584 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1585 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1586 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1587 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1588 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1589 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1590 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1591 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1592 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1593 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1594 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1595 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1596 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1597 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1598 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1599 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1600 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1601 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1602 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1603 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1604 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1605 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1606 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1607 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1608 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1609 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1610 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1611 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1612 FMT_TO_STR(WINED3DFMT_R32_UINT);
1613 FMT_TO_STR(WINED3DFMT_R32_SINT);
1614 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1615 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1616 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1617 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1618 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1619 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1620 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1621 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1622 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1623 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1624 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1625 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1626 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1627 FMT_TO_STR(WINED3DFMT_R16_UINT);
1628 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1629 FMT_TO_STR(WINED3DFMT_R16_SINT);
1630 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1631 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1632 FMT_TO_STR(WINED3DFMT_R8_UINT);
1633 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1634 FMT_TO_STR(WINED3DFMT_R8_SINT);
1635 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1636 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1637 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1638 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1639 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1640 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1641 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1642 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1643 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1644 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1645 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1646 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1647 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1648 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1649 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1650 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1651 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1652 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1653 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1654 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1655 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1656 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1657 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1658 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1659 #undef FMT_TO_STR
1660 default:
1662 char fourcc[5];
1663 fourcc[0] = (char)(fmt);
1664 fourcc[1] = (char)(fmt >> 8);
1665 fourcc[2] = (char)(fmt >> 16);
1666 fourcc[3] = (char)(fmt >> 24);
1667 fourcc[4] = 0;
1668 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
1669 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
1670 else
1671 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
1673 return "unrecognized";
1677 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
1678 switch (devtype) {
1679 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1680 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1681 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1682 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1683 #undef DEVTYPE_TO_STR
1684 default:
1685 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1686 return "unrecognized";
1690 const char *debug_d3dusage(DWORD usage)
1692 char buf[284];
1694 buf[0] = '\0';
1695 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1696 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1697 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1698 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1699 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1700 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1701 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1702 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1703 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1704 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1705 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1706 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1707 #undef WINED3DUSAGE_TO_STR
1708 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1710 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1713 const char *debug_d3dusagequery(DWORD usagequery)
1715 char buf[238];
1717 buf[0] = '\0';
1718 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1719 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1720 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1721 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1722 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1723 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1724 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1725 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1726 #undef WINED3DUSAGEQUERY_TO_STR
1727 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1729 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1732 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1733 switch (method) {
1734 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1735 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1736 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1737 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1738 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1739 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1740 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1741 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1742 #undef WINED3DDECLMETHOD_TO_STR
1743 default:
1744 FIXME("Unrecognized %u declaration method!\n", method);
1745 return "unrecognized";
1749 const char* debug_d3ddeclusage(BYTE usage) {
1750 switch (usage) {
1751 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1752 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1753 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1754 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1755 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1756 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1757 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1758 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1759 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1760 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1761 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1762 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1763 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1764 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1765 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1766 #undef WINED3DDECLUSAGE_TO_STR
1767 default:
1768 FIXME("Unrecognized %u declaration usage!\n", usage);
1769 return "unrecognized";
1773 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1774 switch (res) {
1775 #define RES_TO_STR(res) case res: return #res
1776 RES_TO_STR(WINED3DRTYPE_SURFACE);
1777 RES_TO_STR(WINED3DRTYPE_VOLUME);
1778 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1779 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1780 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1781 RES_TO_STR(WINED3DRTYPE_BUFFER);
1782 #undef RES_TO_STR
1783 default:
1784 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1785 return "unrecognized";
1789 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1790 switch (PrimitiveType) {
1791 #define PRIM_TO_STR(prim) case prim: return #prim
1792 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1793 PRIM_TO_STR(WINED3DPT_POINTLIST);
1794 PRIM_TO_STR(WINED3DPT_LINELIST);
1795 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1796 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1797 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1798 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1799 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1800 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1801 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1802 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1803 #undef PRIM_TO_STR
1804 default:
1805 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1806 return "unrecognized";
1810 const char* debug_d3drenderstate(DWORD state) {
1811 switch (state) {
1812 #define D3DSTATE_TO_STR(u) case u: return #u
1813 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1814 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1815 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1816 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1817 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1818 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1819 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1820 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1821 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1822 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1823 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1824 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1825 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1826 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1827 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1828 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1829 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1830 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1831 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1832 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1833 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1834 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1835 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1836 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1837 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1838 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1839 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1840 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1841 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1842 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1843 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1844 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1845 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1846 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1847 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1848 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1849 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1850 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1851 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1852 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1853 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1854 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1855 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1856 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1857 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1858 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1859 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1860 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1861 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1862 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1863 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1864 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1865 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1866 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1867 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1868 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1869 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1870 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1871 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1872 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1873 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1874 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1875 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1876 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1877 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1878 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1879 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1880 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1881 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1882 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1883 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1884 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1885 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1886 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1887 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1888 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1889 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1890 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1891 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1892 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1893 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1894 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1895 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1896 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1897 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1898 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1899 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1900 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1901 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1902 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1903 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1904 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1905 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1906 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1907 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1908 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1909 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1910 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1911 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1912 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1913 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1914 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1915 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1916 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1917 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1918 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1919 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1920 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1921 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1922 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1923 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1924 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1925 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1926 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1927 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1928 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1929 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1930 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1931 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1932 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1933 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1934 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1935 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1936 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1937 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1938 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1939 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1940 #undef D3DSTATE_TO_STR
1941 default:
1942 FIXME("Unrecognized %u render state!\n", state);
1943 return "unrecognized";
1947 const char* debug_d3dsamplerstate(DWORD state) {
1948 switch (state) {
1949 #define D3DSTATE_TO_STR(u) case u: return #u
1950 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1951 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1952 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1953 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1954 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1955 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1956 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1957 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1958 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1959 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1960 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1961 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1962 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1963 #undef D3DSTATE_TO_STR
1964 default:
1965 FIXME("Unrecognized %u sampler state!\n", state);
1966 return "unrecognized";
1970 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1971 switch (filter_type) {
1972 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1973 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1974 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1975 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1976 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1977 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1978 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1979 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1980 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1981 #undef D3DTEXTUREFILTERTYPE_TO_STR
1982 default:
1983 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1984 return "unrecognized";
1988 const char* debug_d3dtexturestate(DWORD state) {
1989 switch (state) {
1990 #define D3DSTATE_TO_STR(u) case u: return #u
1991 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1992 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1993 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1994 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1995 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1996 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1997 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1998 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1999 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
2000 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
2001 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
2002 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
2003 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
2004 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
2005 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
2006 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
2007 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
2008 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
2009 #undef D3DSTATE_TO_STR
2010 default:
2011 FIXME("Unrecognized %u texture state!\n", state);
2012 return "unrecognized";
2016 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2017 switch (d3dtop) {
2018 #define D3DTOP_TO_STR(u) case u: return #u
2019 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2020 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2021 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2022 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2023 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2024 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2025 D3DTOP_TO_STR(WINED3DTOP_ADD);
2026 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2027 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2028 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2029 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2030 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2031 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2032 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2033 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2034 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2035 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2036 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2037 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2038 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2039 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2040 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2041 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2042 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2043 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2044 D3DTOP_TO_STR(WINED3DTOP_LERP);
2045 #undef D3DTOP_TO_STR
2046 default:
2047 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2048 return "unrecognized";
2052 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2053 switch (tstype) {
2054 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2055 TSTYPE_TO_STR(WINED3DTS_VIEW);
2056 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2057 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2058 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2059 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2060 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2061 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2062 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2063 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2064 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2065 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2066 #undef TSTYPE_TO_STR
2067 default:
2068 if (tstype > 256 && tstype < 512) {
2069 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2070 return ("WINED3DTS_WORLDMATRIX > 0");
2072 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2073 return "unrecognized";
2077 const char *debug_d3dstate(DWORD state)
2079 if (STATE_IS_RENDER(state))
2080 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2081 if (STATE_IS_TEXTURESTAGE(state))
2083 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2084 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2085 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2086 texture_stage, debug_d3dtexturestate(texture_state));
2088 if (STATE_IS_SAMPLER(state))
2089 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2090 if (STATE_IS_PIXELSHADER(state))
2091 return "STATE_PIXELSHADER";
2092 if (STATE_IS_TRANSFORM(state))
2093 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2094 if (STATE_IS_STREAMSRC(state))
2095 return "STATE_STREAMSRC";
2096 if (STATE_IS_INDEXBUFFER(state))
2097 return "STATE_INDEXBUFFER";
2098 if (STATE_IS_VDECL(state))
2099 return "STATE_VDECL";
2100 if (STATE_IS_VSHADER(state))
2101 return "STATE_VSHADER";
2102 if (STATE_IS_VIEWPORT(state))
2103 return "STATE_VIEWPORT";
2104 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2105 return "STATE_VERTEXSHADERCONSTANT";
2106 if (STATE_IS_PIXELSHADERCONSTANT(state))
2107 return "STATE_PIXELSHADERCONSTANT";
2108 if (STATE_IS_ACTIVELIGHT(state))
2109 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2110 if (STATE_IS_SCISSORRECT(state))
2111 return "STATE_SCISSORRECT";
2112 if (STATE_IS_CLIPPLANE(state))
2113 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2114 if (STATE_IS_MATERIAL(state))
2115 return "STATE_MATERIAL";
2116 if (STATE_IS_FRONTFACE(state))
2117 return "STATE_FRONTFACE";
2119 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2122 const char* debug_d3dpool(WINED3DPOOL Pool) {
2123 switch (Pool) {
2124 #define POOL_TO_STR(p) case p: return #p
2125 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2126 POOL_TO_STR(WINED3DPOOL_MANAGED);
2127 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2128 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2129 #undef POOL_TO_STR
2130 default:
2131 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
2132 return "unrecognized";
2136 const char *debug_fbostatus(GLenum status) {
2137 switch(status) {
2138 #define FBOSTATUS_TO_STR(u) case u: return #u
2139 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2140 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2141 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2142 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2143 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2144 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2145 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2146 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2147 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2148 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2149 #undef FBOSTATUS_TO_STR
2150 default:
2151 FIXME("Unrecognied FBO status 0x%08x\n", status);
2152 return "unrecognized";
2156 const char *debug_glerror(GLenum error) {
2157 switch(error) {
2158 #define GLERROR_TO_STR(u) case u: return #u
2159 GLERROR_TO_STR(GL_NO_ERROR);
2160 GLERROR_TO_STR(GL_INVALID_ENUM);
2161 GLERROR_TO_STR(GL_INVALID_VALUE);
2162 GLERROR_TO_STR(GL_INVALID_OPERATION);
2163 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2164 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2165 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2166 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2167 #undef GLERROR_TO_STR
2168 default:
2169 FIXME("Unrecognied GL error 0x%08x\n", error);
2170 return "unrecognized";
2174 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2175 switch(basis) {
2176 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2177 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2178 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2179 default: return "unrecognized";
2183 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2184 switch(degree) {
2185 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2186 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2187 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2188 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2189 default: return "unrecognized";
2193 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2195 switch(source)
2197 #define WINED3D_TO_STR(x) case x: return #x
2198 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2199 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2200 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2201 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2202 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2203 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2204 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2205 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2206 #undef WINED3D_TO_STR
2207 default:
2208 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2209 return "unrecognized";
2213 static const char *debug_complex_fixup(enum complex_fixup fixup)
2215 switch(fixup)
2217 #define WINED3D_TO_STR(x) case x: return #x
2218 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2219 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2220 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2221 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2222 #undef WINED3D_TO_STR
2223 default:
2224 FIXME("Unrecognized complex fixup %#x\n", fixup);
2225 return "unrecognized";
2229 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2231 if (is_complex_fixup(fixup))
2233 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2234 return;
2237 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2238 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2239 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2240 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2243 const char *debug_surflocation(DWORD flag) {
2244 char buf[128];
2246 buf[0] = 0;
2247 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2248 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2249 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2250 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2251 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2254 /*****************************************************************************
2255 * Useful functions mapping GL <-> D3D values
2257 GLenum StencilOp(DWORD op) {
2258 switch(op) {
2259 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2260 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2261 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2262 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2263 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2264 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2265 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2266 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2267 default:
2268 FIXME("Unrecognized stencil op %d\n", op);
2269 return GL_KEEP;
2273 GLenum CompareFunc(DWORD func) {
2274 switch ((WINED3DCMPFUNC)func) {
2275 case WINED3DCMP_NEVER : return GL_NEVER;
2276 case WINED3DCMP_LESS : return GL_LESS;
2277 case WINED3DCMP_EQUAL : return GL_EQUAL;
2278 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2279 case WINED3DCMP_GREATER : return GL_GREATER;
2280 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2281 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2282 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2283 default:
2284 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2285 return 0;
2289 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
2290 if (op == WINED3DTOP_DISABLE) return FALSE;
2291 if (This->stateBlock->textures[stage]) return FALSE;
2293 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2294 && op != WINED3DTOP_SELECTARG2) return TRUE;
2295 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2296 && op != WINED3DTOP_SELECTARG1) return TRUE;
2297 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2298 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2300 return FALSE;
2303 /* Setup this textures matrix according to the texture flags*/
2304 /* GL locking is done by the caller (state handler) */
2305 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2306 WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
2308 float mat[16];
2310 glMatrixMode(GL_TEXTURE);
2311 checkGLcall("glMatrixMode(GL_TEXTURE)");
2313 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2314 glLoadIdentity();
2315 checkGLcall("glLoadIdentity()");
2316 return;
2319 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2320 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2321 return;
2324 memcpy(mat, smat, 16 * sizeof(float));
2326 if (flags & WINED3DTTFF_PROJECTED) {
2327 if(!ffp_proj_control) {
2328 switch (flags & ~WINED3DTTFF_PROJECTED) {
2329 case WINED3DTTFF_COUNT2:
2330 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2331 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2332 break;
2333 case WINED3DTTFF_COUNT3:
2334 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2335 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2336 break;
2339 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2340 if(!calculatedCoords) {
2341 switch(vtx_fmt)
2343 case WINED3DFMT_R32_FLOAT:
2344 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2345 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2346 * the input value to the transformation will be 0, so the matrix value is irrelevant
2348 mat[12] = mat[4];
2349 mat[13] = mat[5];
2350 mat[14] = mat[6];
2351 mat[15] = mat[7];
2352 break;
2353 case WINED3DFMT_R32G32_FLOAT:
2354 /* See above, just 3rd and 4th coord
2356 mat[12] = mat[8];
2357 mat[13] = mat[9];
2358 mat[14] = mat[10];
2359 mat[15] = mat[11];
2360 break;
2361 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2362 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2364 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2365 * into a bad place. The division elimination below will apply to make sure the
2366 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2368 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2369 break;
2370 default:
2371 FIXME("Unexpected fixed function texture coord input\n");
2374 if(!ffp_proj_control) {
2375 switch (flags & ~WINED3DTTFF_PROJECTED) {
2376 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2377 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2378 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2379 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2380 * the 4th coord evaluates to 1.0 to eliminate that.
2382 * If the fixed function pipeline is used, the 4th value remains unused,
2383 * so there is no danger in doing this. With vertex shaders we have a
2384 * problem. Should an app hit that problem, the code here would have to
2385 * check for pixel shaders, and the shader has to undo the default gl divide.
2387 * A more serious problem occurs if the app passes 4 coordinates in, and the
2388 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2389 * or a replacement shader
2391 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2396 glLoadMatrixf(mat);
2397 checkGLcall("glLoadMatrixf(mat)");
2400 /* This small helper function is used to convert a bitmask into the number of masked bits */
2401 unsigned int count_bits(unsigned int mask)
2403 unsigned int count;
2404 for (count = 0; mask; ++count)
2406 mask &= mask - 1;
2408 return count;
2411 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2412 * The later function requires individual color components. */
2413 BOOL getColorBits(const struct wined3d_format_desc *format_desc,
2414 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2416 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2417 switch(format_desc->format)
2419 case WINED3DFMT_B8G8R8X8_UNORM:
2420 case WINED3DFMT_B8G8R8_UNORM:
2421 case WINED3DFMT_B8G8R8A8_UNORM:
2422 case WINED3DFMT_R8G8B8A8_UNORM:
2423 case WINED3DFMT_B10G10R10A2_UNORM:
2424 case WINED3DFMT_B5G5R5X1_UNORM:
2425 case WINED3DFMT_B5G5R5A1_UNORM:
2426 case WINED3DFMT_B5G6R5_UNORM:
2427 case WINED3DFMT_B4G4R4X4_UNORM:
2428 case WINED3DFMT_B4G4R4A4_UNORM:
2429 case WINED3DFMT_B2G3R3_UNORM:
2430 case WINED3DFMT_P8_UINT_A8_UNORM:
2431 case WINED3DFMT_P8_UINT:
2432 break;
2433 default:
2434 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
2435 return FALSE;
2438 *redSize = count_bits(format_desc->red_mask);
2439 *greenSize = count_bits(format_desc->green_mask);
2440 *blueSize = count_bits(format_desc->blue_mask);
2441 *alphaSize = count_bits(format_desc->alpha_mask);
2442 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2444 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
2445 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
2446 return TRUE;
2449 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2450 BOOL getDepthStencilBits(const struct wined3d_format_desc *format_desc, short *depthSize, short *stencilSize)
2452 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2453 switch(format_desc->format)
2455 case WINED3DFMT_D16_LOCKABLE:
2456 case WINED3DFMT_D16_UNORM:
2457 case WINED3DFMT_S1_UINT_D15_UNORM:
2458 case WINED3DFMT_X8D24_UNORM:
2459 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2460 case WINED3DFMT_D24_UNORM_S8_UINT:
2461 case WINED3DFMT_S8_UINT_D24_FLOAT:
2462 case WINED3DFMT_D32_UNORM:
2463 case WINED3DFMT_D32_FLOAT:
2464 break;
2465 default:
2466 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
2467 return FALSE;
2470 *depthSize = format_desc->depth_size;
2471 *stencilSize = format_desc->stencil_size;
2473 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
2474 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
2475 return TRUE;
2478 DWORD color_convert_argb_to_fmt(DWORD color, WINED3DFORMAT destfmt)
2480 unsigned int r, g, b, a;
2481 DWORD ret;
2483 if (destfmt == WINED3DFMT_B8G8R8A8_UNORM
2484 || destfmt == WINED3DFMT_B8G8R8X8_UNORM
2485 || destfmt == WINED3DFMT_B8G8R8_UNORM)
2486 return color;
2488 TRACE("Converting color %08x to format %s\n", color, debug_d3dformat(destfmt));
2490 a = (color & 0xff000000) >> 24;
2491 r = (color & 0x00ff0000) >> 16;
2492 g = (color & 0x0000ff00) >> 8;
2493 b = (color & 0x000000ff) >> 0;
2495 switch(destfmt)
2497 case WINED3DFMT_B5G6R5_UNORM:
2498 if(r == 0xff && g == 0xff && b == 0xff) return 0xffff;
2499 r = (r * 32) / 256;
2500 g = (g * 64) / 256;
2501 b = (b * 32) / 256;
2502 ret = r << 11;
2503 ret |= g << 5;
2504 ret |= b;
2505 TRACE("Returning %08x\n", ret);
2506 return ret;
2508 case WINED3DFMT_B5G5R5X1_UNORM:
2509 case WINED3DFMT_B5G5R5A1_UNORM:
2510 a = (a * 2) / 256;
2511 r = (r * 32) / 256;
2512 g = (g * 32) / 256;
2513 b = (b * 32) / 256;
2514 ret = a << 15;
2515 ret |= r << 10;
2516 ret |= g << 5;
2517 ret |= b << 0;
2518 TRACE("Returning %08x\n", ret);
2519 return ret;
2521 case WINED3DFMT_A8_UNORM:
2522 TRACE("Returning %08x\n", a);
2523 return a;
2525 case WINED3DFMT_B4G4R4X4_UNORM:
2526 case WINED3DFMT_B4G4R4A4_UNORM:
2527 a = (a * 16) / 256;
2528 r = (r * 16) / 256;
2529 g = (g * 16) / 256;
2530 b = (b * 16) / 256;
2531 ret = a << 12;
2532 ret |= r << 8;
2533 ret |= g << 4;
2534 ret |= b << 0;
2535 TRACE("Returning %08x\n", ret);
2536 return ret;
2538 case WINED3DFMT_B2G3R3_UNORM:
2539 r = (r * 8) / 256;
2540 g = (g * 8) / 256;
2541 b = (b * 4) / 256;
2542 ret = r << 5;
2543 ret |= g << 2;
2544 ret |= b << 0;
2545 TRACE("Returning %08x\n", ret);
2546 return ret;
2548 case WINED3DFMT_R8G8B8X8_UNORM:
2549 case WINED3DFMT_R8G8B8A8_UNORM:
2550 ret = a << 24;
2551 ret |= b << 16;
2552 ret |= g << 8;
2553 ret |= r << 0;
2554 TRACE("Returning %08x\n", ret);
2555 return ret;
2557 case WINED3DFMT_B10G10R10A2_UNORM:
2558 a = (a * 4) / 256;
2559 r = (r * 1024) / 256;
2560 g = (g * 1024) / 256;
2561 b = (b * 1024) / 256;
2562 ret = a << 30;
2563 ret |= r << 20;
2564 ret |= g << 10;
2565 ret |= b << 0;
2566 TRACE("Returning %08x\n", ret);
2567 return ret;
2569 case WINED3DFMT_R10G10B10A2_UNORM:
2570 a = (a * 4) / 256;
2571 r = (r * 1024) / 256;
2572 g = (g * 1024) / 256;
2573 b = (b * 1024) / 256;
2574 ret = a << 30;
2575 ret |= b << 20;
2576 ret |= g << 10;
2577 ret |= r << 0;
2578 TRACE("Returning %08x\n", ret);
2579 return ret;
2581 default:
2582 FIXME("Add a COLORFILL conversion for format %s\n", debug_d3dformat(destfmt));
2583 return 0;
2587 /* DirectDraw stuff */
2588 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2589 switch(depth) {
2590 case 8: return WINED3DFMT_P8_UINT;
2591 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2592 case 16: return WINED3DFMT_B5G6R5_UNORM;
2593 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2594 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2595 default: return WINED3DFMT_UNKNOWN;
2599 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2600 WINED3DMATRIX temp;
2602 /* Now do the multiplication 'by hand'.
2603 I know that all this could be optimised, but this will be done later :-) */
2604 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);
2605 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);
2606 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);
2607 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);
2609 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);
2610 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);
2611 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);
2612 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);
2614 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);
2615 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);
2616 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);
2617 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);
2619 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);
2620 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);
2621 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);
2622 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);
2624 /* And copy the new matrix in the good storage.. */
2625 memcpy(dest, &temp, 16 * sizeof(float));
2628 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2629 DWORD size = 0;
2630 int i;
2631 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2633 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2634 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2635 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2636 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2637 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2638 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2639 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2640 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2641 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2642 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2643 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2644 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2645 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2646 default: ERR("Unexpected position mask\n");
2648 for (i = 0; i < numTextures; i++) {
2649 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2652 return size;
2655 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2656 #define ARG1 0x01
2657 #define ARG2 0x02
2658 #define ARG0 0x04
2659 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2660 /* undefined */ 0,
2661 /* D3DTOP_DISABLE */ 0,
2662 /* D3DTOP_SELECTARG1 */ ARG1,
2663 /* D3DTOP_SELECTARG2 */ ARG2,
2664 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2665 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2666 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2667 /* D3DTOP_ADD */ ARG1 | ARG2,
2668 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2669 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2670 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2671 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2672 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2673 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2674 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2675 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2676 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2677 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2678 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2679 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2680 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2681 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2682 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2683 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2684 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2685 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2686 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2688 unsigned int i;
2689 DWORD ttff;
2690 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2691 IWineD3DDeviceImpl *device = stateblock->device;
2692 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2694 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2696 IWineD3DBaseTextureImpl *texture;
2697 settings->op[i].padding = 0;
2698 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2699 settings->op[i].cop = WINED3DTOP_DISABLE;
2700 settings->op[i].aop = WINED3DTOP_DISABLE;
2701 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2702 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2703 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2704 settings->op[i].dst = resultreg;
2705 settings->op[i].tex_type = tex_1d;
2706 settings->op[i].projected = proj_none;
2707 i++;
2708 break;
2711 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2712 if(texture) {
2713 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2714 if(ignore_textype) {
2715 settings->op[i].tex_type = tex_1d;
2716 } else {
2717 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2718 case GL_TEXTURE_1D:
2719 settings->op[i].tex_type = tex_1d;
2720 break;
2721 case GL_TEXTURE_2D:
2722 settings->op[i].tex_type = tex_2d;
2723 break;
2724 case GL_TEXTURE_3D:
2725 settings->op[i].tex_type = tex_3d;
2726 break;
2727 case GL_TEXTURE_CUBE_MAP_ARB:
2728 settings->op[i].tex_type = tex_cube;
2729 break;
2730 case GL_TEXTURE_RECTANGLE_ARB:
2731 settings->op[i].tex_type = tex_rect;
2732 break;
2735 } else {
2736 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2737 settings->op[i].tex_type = tex_1d;
2740 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2741 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2743 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2744 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2745 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2747 if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2748 carg0 = ARG_UNUSED;
2749 carg2 = ARG_UNUSED;
2750 carg1 = WINED3DTA_CURRENT;
2751 cop = WINED3DTOP_SELECTARG1;
2754 if(cop == WINED3DTOP_DOTPRODUCT3) {
2755 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2756 * the color result to the alpha component of the destination
2758 aop = cop;
2759 aarg1 = carg1;
2760 aarg2 = carg2;
2761 aarg0 = carg0;
2762 } else {
2763 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2764 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2765 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2768 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2770 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2772 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2774 IWineD3DSurfaceImpl *surf;
2775 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2777 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2779 if (aop == WINED3DTOP_DISABLE)
2781 aarg1 = WINED3DTA_TEXTURE;
2782 aop = WINED3DTOP_SELECTARG1;
2784 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2786 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2788 aarg2 = WINED3DTA_TEXTURE;
2789 aop = WINED3DTOP_MODULATE;
2791 else aarg1 = WINED3DTA_TEXTURE;
2793 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2795 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2797 aarg1 = WINED3DTA_TEXTURE;
2798 aop = WINED3DTOP_MODULATE;
2800 else aarg2 = WINED3DTA_TEXTURE;
2806 if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2807 aarg0 = ARG_UNUSED;
2808 aarg2 = ARG_UNUSED;
2809 aarg1 = WINED3DTA_CURRENT;
2810 aop = WINED3DTOP_SELECTARG1;
2813 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2814 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2815 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2816 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2817 settings->op[i].projected = proj_count3;
2818 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2819 settings->op[i].projected = proj_count4;
2820 } else {
2821 settings->op[i].projected = proj_none;
2823 } else {
2824 settings->op[i].projected = proj_none;
2827 settings->op[i].cop = cop;
2828 settings->op[i].aop = aop;
2829 settings->op[i].carg0 = carg0;
2830 settings->op[i].carg1 = carg1;
2831 settings->op[i].carg2 = carg2;
2832 settings->op[i].aarg0 = aarg0;
2833 settings->op[i].aarg1 = aarg1;
2834 settings->op[i].aarg2 = aarg2;
2836 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2837 settings->op[i].dst = tempreg;
2838 } else {
2839 settings->op[i].dst = resultreg;
2843 /* Clear unsupported stages */
2844 for(; i < MAX_TEXTURES; i++) {
2845 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2848 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2849 settings->fog = FOG_OFF;
2850 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2851 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2852 settings->fog = FOG_LINEAR;
2853 } else {
2854 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2855 case WINED3DFOG_NONE:
2856 case WINED3DFOG_LINEAR:
2857 settings->fog = FOG_LINEAR;
2858 break;
2859 case WINED3DFOG_EXP:
2860 settings->fog = FOG_EXP;
2861 break;
2862 case WINED3DFOG_EXP2:
2863 settings->fog = FOG_EXP2;
2864 break;
2867 } else {
2868 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2869 case WINED3DFOG_LINEAR:
2870 settings->fog = FOG_LINEAR;
2871 break;
2872 case WINED3DFOG_EXP:
2873 settings->fog = FOG_EXP;
2874 break;
2875 case WINED3DFOG_EXP2:
2876 settings->fog = FOG_EXP2;
2877 break;
2880 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2881 settings->sRGB_write = 1;
2882 } else {
2883 settings->sRGB_write = 0;
2885 if(device->vs_clipping || !use_vs(stateblock) || !stateblock->renderState[WINED3DRS_CLIPPING] ||
2886 !stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
2887 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2888 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2889 * if no clipplane is enabled
2891 settings->emul_clipplanes = 0;
2892 } else {
2893 settings->emul_clipplanes = 1;
2897 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2898 const struct ffp_frag_settings *settings)
2900 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2901 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2904 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2906 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2907 * whereas desc points to an extended structure with implementation specific parts. */
2908 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2910 ERR("Failed to insert ffp frag shader.\n");
2914 /* Activates the texture dimension according to the bound D3D texture.
2915 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2916 * Requires the caller to activate the correct unit before
2918 /* GL locking is done by the caller (state handler) */
2919 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2921 const struct wined3d_gl_info *gl_info = context->gl_info;
2923 if (stateblock->textures[stage])
2925 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2926 case GL_TEXTURE_2D:
2927 glDisable(GL_TEXTURE_3D);
2928 checkGLcall("glDisable(GL_TEXTURE_3D)");
2929 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2931 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2932 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2934 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2936 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2937 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2939 glEnable(GL_TEXTURE_2D);
2940 checkGLcall("glEnable(GL_TEXTURE_2D)");
2941 break;
2942 case GL_TEXTURE_RECTANGLE_ARB:
2943 glDisable(GL_TEXTURE_2D);
2944 checkGLcall("glDisable(GL_TEXTURE_2D)");
2945 glDisable(GL_TEXTURE_3D);
2946 checkGLcall("glDisable(GL_TEXTURE_3D)");
2947 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2949 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2950 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2952 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2953 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2954 break;
2955 case GL_TEXTURE_3D:
2956 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2958 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2959 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2961 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2963 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2964 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2966 glDisable(GL_TEXTURE_2D);
2967 checkGLcall("glDisable(GL_TEXTURE_2D)");
2968 glEnable(GL_TEXTURE_3D);
2969 checkGLcall("glEnable(GL_TEXTURE_3D)");
2970 break;
2971 case GL_TEXTURE_CUBE_MAP_ARB:
2972 glDisable(GL_TEXTURE_2D);
2973 checkGLcall("glDisable(GL_TEXTURE_2D)");
2974 glDisable(GL_TEXTURE_3D);
2975 checkGLcall("glDisable(GL_TEXTURE_3D)");
2976 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2978 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2979 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2981 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2982 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2983 break;
2985 } else {
2986 glEnable(GL_TEXTURE_2D);
2987 checkGLcall("glEnable(GL_TEXTURE_2D)");
2988 glDisable(GL_TEXTURE_3D);
2989 checkGLcall("glDisable(GL_TEXTURE_3D)");
2990 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2992 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2993 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2995 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2997 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2998 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3000 /* Binding textures is done by samplers. A dummy texture will be bound */
3004 /* GL locking is done by the caller (state handler) */
3005 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3007 DWORD sampler = state - STATE_SAMPLER(0);
3008 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3010 /* No need to enable / disable anything here for unused samplers. The tex_colorop
3011 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3012 * will take care of this business
3014 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3015 if(sampler >= stateblock->lowest_disabled_stage) return;
3016 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3018 texture_activate_dimensions(sampler, stateblock, context);
3021 void *wined3d_rb_alloc(size_t size)
3023 return HeapAlloc(GetProcessHeap(), 0, size);
3026 void *wined3d_rb_realloc(void *ptr, size_t size)
3028 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3031 void wined3d_rb_free(void *ptr)
3033 HeapFree(GetProcessHeap(), 0, ptr);
3036 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3038 const struct ffp_frag_settings *ka = key;
3039 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3041 return memcmp(ka, kb, sizeof(*ka));
3044 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3046 wined3d_rb_alloc,
3047 wined3d_rb_realloc,
3048 wined3d_rb_free,
3049 ffp_frag_program_key_compare,
3052 UINT wined3d_log2i(UINT32 x)
3054 static const UINT l[] =
3056 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3057 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3058 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3059 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3060 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3061 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
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 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3065 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
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,
3073 UINT32 i;
3075 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3078 /* Set the shader type for this device, depending on the given capabilities
3079 * and the user preferences in wined3d_settings. */
3080 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3082 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3084 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3085 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3087 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3088 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3089 * shaders only on this card. */
3090 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3091 else *vs_selected = SHADER_GLSL;
3093 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3094 else *vs_selected = SHADER_NONE;
3096 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3097 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3098 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3099 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3100 else *ps_selected = SHADER_NONE;