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