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
28 #include "wined3d_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
32 struct StaticPixelFormatDesc
34 enum wined3d_format_id id;
35 DWORD alphaMask, redMask, greenMask, blueMask;
37 short depthSize, stencilSize;
40 /*****************************************************************************
43 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
44 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
45 * high masks do not fit into the 32 bit values needed for ddraw. It is only
46 * used for ddraw mostly, and to figure out if the format has alpha at all, so
47 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
48 * formats are not usable in 2D rendering because ddraw doesn't support them.
50 static const struct StaticPixelFormatDesc formats[] =
52 /* format id alphamask redmask greenmask bluemask bpp depth stencil */
53 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
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},
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},
72 {WINED3DFMT_R8G8_SNORM_Cx, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
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},
104 {WINED3DFMT_L8_UNORM, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
105 {WINED3DFMT_L8A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
106 {WINED3DFMT_L4A4_UNORM, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0},
107 {WINED3DFMT_L16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
108 /* Bump mapping stuff */
109 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
110 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
111 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
112 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
113 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
114 {WINED3DFMT_R10G11B11_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
115 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0},
116 /* Depth stencil formats */
117 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
118 {WINED3DFMT_D32_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
119 {WINED3DFMT_S1_UINT_D15_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 15, 1},
120 {WINED3DFMT_D24_UNORM_S8_UINT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
121 {WINED3DFMT_X8D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 0},
122 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 4},
123 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
124 {WINED3DFMT_D32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
125 {WINED3DFMT_S8_UINT_D24_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
126 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
127 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
128 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
129 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
130 /* Vendor-specific formats */
131 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
132 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
133 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
136 struct wined3d_format_base_flags
138 enum wined3d_format_id id;
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
145 static const struct wined3d_format_base_flags format_base_flags[] =
147 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
148 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
149 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
150 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
151 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
152 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
153 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
156 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
157 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
158 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
159 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
160 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
161 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
162 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
163 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
164 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
165 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
166 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
170 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
171 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
172 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
173 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
174 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
175 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
176 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
177 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
178 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
179 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 struct wined3d_format_compression_info
185 enum wined3d_format_id id;
188 UINT block_byte_count;
191 static const struct wined3d_format_compression_info format_compression_info[] =
193 {WINED3DFMT_DXT1, 4, 4, 8},
194 {WINED3DFMT_DXT2, 4, 4, 16},
195 {WINED3DFMT_DXT3, 4, 4, 16},
196 {WINED3DFMT_DXT4, 4, 4, 16},
197 {WINED3DFMT_DXT5, 4, 4, 16},
198 {WINED3DFMT_ATI2N, 4, 4, 16},
201 struct wined3d_format_vertex_info
203 enum wined3d_format_id id;
204 enum wined3d_ffp_emit_idx emit_idx;
205 GLint component_count;
208 GLboolean gl_normalized;
209 unsigned int component_size;
212 static const struct wined3d_format_vertex_info format_vertex_info[] =
214 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
215 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
216 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
217 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
218 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
219 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
220 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
221 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
222 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
223 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
224 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
225 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
226 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
227 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
228 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
229 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
230 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
233 struct wined3d_format_texture_info
235 enum wined3d_format_id id;
237 GLint gl_srgb_internal;
238 GLint gl_rt_internal;
241 unsigned int conv_byte_count;
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
254 const unsigned char *Source;
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;
270 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
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);
294 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
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
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;
330 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
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 */
352 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
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 */
377 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
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 */
402 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
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 */
424 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
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 */
446 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
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++);
463 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
464 * shader overwrites it anyway
472 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
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++);
495 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
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)
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)
537 UINT outpitch = pitch * 2;
539 for (y = 0; y < height; ++y)
541 const DWORD *source = (const DWORD *)(src + y * pitch);
542 float *dest_f = (float *)(dst + y * outpitch);
543 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
545 for (x = 0; x < width; ++x)
547 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
548 dest_s[x * 2 + 1] = source[x] & 0xff;
553 static const struct wined3d_format_texture_info format_texture_info[] =
555 /* format id internal srgbInternal rtInternal
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
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},
607 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
609 WINED3DFMT_FLAG_RENDERTARGET,
610 ARB_TEXTURE_FLOAT, NULL},
611 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 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,
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},
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},
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,
768 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
769 NV_TEXTURE_SHADER, NULL},
770 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
771 GL_BGR, GL_UNSIGNED_SHORT, 6,
772 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
773 WINED3D_GL_EXT_NONE, &convert_r16g16_snorm},
774 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
775 GL_HILO_NV, GL_SHORT, 0,
776 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
777 NV_TEXTURE_SHADER, NULL},
778 /* Depth stencil formats */
779 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
780 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
781 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
782 ARB_DEPTH_TEXTURE, NULL},
783 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
784 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
785 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
786 ARB_DEPTH_TEXTURE, NULL},
787 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
788 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
789 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
790 ARB_DEPTH_TEXTURE, NULL},
791 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
792 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
793 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
794 EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm},
795 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
796 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
797 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
798 ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm},
799 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
800 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
801 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
802 | WINED3DFMT_FLAG_SHADOW,
803 ARB_DEPTH_TEXTURE, NULL},
804 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
805 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
806 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
807 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
808 EXT_PACKED_DEPTH_STENCIL, NULL},
809 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
810 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
811 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
812 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
813 ARB_FRAMEBUFFER_OBJECT, NULL},
814 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
815 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
816 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
817 | WINED3DFMT_FLAG_SHADOW,
818 ARB_DEPTH_TEXTURE, NULL},
819 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
820 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
821 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
822 ARB_DEPTH_TEXTURE, NULL},
823 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
824 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
825 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
826 EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm},
827 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
828 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
829 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
830 ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm},
831 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
832 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
833 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
834 | WINED3DFMT_FLAG_SHADOW,
835 ARB_DEPTH_TEXTURE, NULL},
836 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
837 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
838 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
839 WINED3D_GL_EXT_NONE, NULL},
840 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
841 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
842 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
843 ARB_DEPTH_BUFFER_FLOAT, NULL},
844 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
845 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
846 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
847 ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float},
848 /* Vendor-specific formats */
849 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
850 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
851 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
852 ATI_TEXTURE_COMPRESSION_3DC, NULL},
853 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2, GL_COMPRESSED_RED_GREEN_RGTC2, 0,
854 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
855 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
856 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
859 static inline int getFmtIdx(enum wined3d_format_id format_id)
861 /* First check if the format is at the position of its value.
862 * This will catch the argb formats before the loop is entered. */
863 if (format_id < (sizeof(formats) / sizeof(*formats))
864 && formats[format_id].id == format_id)
872 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
874 if (formats[i].id == format_id) return i;
880 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
882 UINT format_count = sizeof(formats) / sizeof(*formats);
885 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
886 if (!gl_info->formats)
888 ERR("Failed to allocate memory.\n");
892 for (i = 0; i < format_count; ++i)
894 struct wined3d_format *format = &gl_info->formats[i];
895 format->id = formats[i].id;
896 format->red_mask = formats[i].redMask;
897 format->green_mask = formats[i].greenMask;
898 format->blue_mask = formats[i].blueMask;
899 format->alpha_mask = formats[i].alphaMask;
900 format->byte_count = formats[i].bpp;
901 format->depth_size = formats[i].depthSize;
902 format->stencil_size = formats[i].stencilSize;
905 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
907 int fmt_idx = getFmtIdx(format_base_flags[i].id);
911 ERR("Format %s (%#x) not found.\n",
912 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
913 HeapFree(GetProcessHeap(), 0, gl_info->formats);
917 gl_info->formats[fmt_idx].Flags |= format_base_flags[i].flags;
923 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
927 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
929 struct wined3d_format *format;
930 int fmt_idx = getFmtIdx(format_compression_info[i].id);
934 ERR("Format %s (%#x) not found.\n",
935 debug_d3dformat(format_compression_info[i].id), format_compression_info[i].id);
939 format = &gl_info->formats[fmt_idx];
940 format->block_width = format_compression_info[i].block_width;
941 format->block_height = format_compression_info[i].block_height;
942 format->block_byte_count = format_compression_info[i].block_byte_count;
943 format->Flags |= WINED3DFMT_FLAG_COMPRESSED;
949 /* Context activation is done by the caller. */
950 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
952 /* Check if the default internal format is supported as a frame buffer
953 * target, otherwise fall back to the render target internal.
955 * Try to stick to the standard format if possible, this limits precision differences. */
964 glGenTextures(1, &tex);
965 glBindTexture(GL_TEXTURE_2D, tex);
967 glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
968 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
969 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
971 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
973 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
974 checkGLcall("Framebuffer format check");
976 if (status == GL_FRAMEBUFFER_COMPLETE)
978 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
979 format->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
980 format->rtInternal = format->glInternal;
984 if (!format->rtInternal)
986 if (format->Flags & WINED3DFMT_FLAG_RENDERTARGET)
988 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
989 " and no fallback specified.\n", debug_d3dformat(format->id));
990 format->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
994 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
996 format->rtInternal = format->glInternal;
1000 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1001 debug_d3dformat(format->id));
1003 while(glGetError());
1005 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1007 glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1008 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1009 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1011 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1013 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1014 checkGLcall("Framebuffer format check");
1016 if (status == GL_FRAMEBUFFER_COMPLETE)
1018 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1019 debug_d3dformat(format->id));
1023 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1024 debug_d3dformat(format->id));
1025 format->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1030 if (status == GL_FRAMEBUFFER_COMPLETE && format->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1034 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1035 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1037 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1038 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1039 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1040 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1041 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1042 checkGLcall("RB attachment");
1046 glClear(GL_COLOR_BUFFER_BIT);
1047 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1049 while(glGetError());
1050 TRACE("Format doesn't support post-pixelshader blending.\n");
1051 format->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1054 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1055 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1057 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1058 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1059 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1060 checkGLcall("RB cleanup");
1064 if (format->glInternal != format->glGammaInternal)
1066 glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1067 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1069 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1070 checkGLcall("Framebuffer format check");
1072 if (status == GL_FRAMEBUFFER_COMPLETE)
1074 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1075 format->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1079 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1083 glDeleteTextures(1, &tex);
1088 /* Context activation is done by the caller. */
1089 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1094 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1098 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1099 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1104 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1106 struct wined3d_format *format = &gl_info->formats[i];
1108 if (!format->glInternal) continue;
1110 if (format->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1112 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1113 debug_d3dformat(format->id));
1117 if (format->Flags & WINED3DFMT_FLAG_COMPRESSED)
1119 TRACE("Skipping format %s because it's a compressed format.\n",
1120 debug_d3dformat(format->id));
1124 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1126 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1127 check_fbo_compat(gl_info, format);
1131 format->rtInternal = format->glInternal;
1135 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1139 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1145 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1149 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1151 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1152 struct wined3d_format *format;
1156 ERR("Format %s (%#x) not found.\n",
1157 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1161 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1163 format = &gl_info->formats[fmt_idx];
1164 format->glInternal = format_texture_info[i].gl_internal;
1165 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1166 format->rtInternal = format_texture_info[i].gl_rt_internal;
1167 format->glFormat = format_texture_info[i].gl_format;
1168 format->glType = format_texture_info[i].gl_type;
1169 format->color_fixup = COLOR_FIXUP_IDENTITY;
1170 format->Flags |= format_texture_info[i].flags;
1171 format->heightscale = 1.0f;
1173 /* Texture conversion stuff */
1174 format->convert = format_texture_info[i].convert;
1175 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1181 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1183 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1185 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1187 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1189 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1193 /* A context is provided by the caller */
1194 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1196 static const DWORD data[] = {0x00000000, 0xffffffff};
1197 GLuint tex, fbo, buffer;
1198 DWORD readback[16 * 1];
1201 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1202 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1203 * falling back to software. If this changes in the future this code will get fooled and
1204 * apps might hit the software path due to incorrectly advertised caps.
1206 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1207 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1208 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1212 while(glGetError());
1214 glGenTextures(1, &buffer);
1215 glBindTexture(GL_TEXTURE_2D, buffer);
1216 memset(readback, 0x7e, sizeof(readback));
1217 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1218 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1219 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1220 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1221 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1222 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1224 glGenTextures(1, &tex);
1225 glBindTexture(GL_TEXTURE_2D, tex);
1226 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1227 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1230 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1231 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1232 glEnable(GL_TEXTURE_2D);
1234 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1235 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1236 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1237 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1239 glViewport(0, 0, 16, 1);
1240 glDisable(GL_LIGHTING);
1241 glMatrixMode(GL_MODELVIEW);
1243 glMatrixMode(GL_PROJECTION);
1246 glClearColor(0, 1, 0, 0);
1247 glClear(GL_COLOR_BUFFER_BIT);
1249 glBegin(GL_TRIANGLE_STRIP);
1250 glTexCoord2f(0.0, 0.0);
1251 glVertex2f(-1.0f, -1.0f);
1252 glTexCoord2f(1.0, 0.0);
1253 glVertex2f(1.0f, -1.0f);
1254 glTexCoord2f(0.0, 1.0);
1255 glVertex2f(-1.0f, 1.0f);
1256 glTexCoord2f(1.0, 1.0);
1257 glVertex2f(1.0f, 1.0f);
1260 glBindTexture(GL_TEXTURE_2D, buffer);
1261 memset(readback, 0x7f, sizeof(readback));
1262 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1263 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1264 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1266 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1267 readback[6], readback[9]);
1272 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1273 readback[6], readback[9]);
1277 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1278 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1279 glDeleteTextures(1, &tex);
1280 glDeleteTextures(1, &buffer);
1284 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1291 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1293 struct wined3d_format *format;
1294 unsigned int fmt_idx, i;
1295 static const enum wined3d_format_id fmts16[] =
1297 WINED3DFMT_R16_FLOAT,
1298 WINED3DFMT_R16G16_FLOAT,
1299 WINED3DFMT_R16G16B16A16_FLOAT,
1303 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1305 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1306 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1308 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1311 else if (gl_info->limits.glsl_varyings > 44)
1313 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1318 TRACE("Assuming no float16 blending\n");
1324 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1326 fmt_idx = getFmtIdx(fmts16[i]);
1327 gl_info->formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
1333 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1335 fmt_idx = getFmtIdx(fmts16[i]);
1336 format = &gl_info->formats[fmt_idx];
1337 if (!format->glInternal) continue; /* Not supported by GL */
1339 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1342 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1343 format->Flags |= WINED3DFMT_FLAG_FILTERING;
1347 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1352 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1356 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1357 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1358 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1360 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1361 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1362 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1364 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1365 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1366 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1368 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1369 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1370 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1372 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1373 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1374 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1376 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1377 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1378 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1379 * the only driver that implements it(fglrx) has a buggy implementation.
1381 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1382 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1383 * conversion for this format.
1385 if (!gl_info->supported[NV_TEXTURE_SHADER])
1387 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1388 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1389 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1390 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1391 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1392 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1396 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1397 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1398 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1400 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1401 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1402 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1405 if (!gl_info->supported[NV_TEXTURE_SHADER])
1407 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1410 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1411 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1412 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1413 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1414 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1415 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1416 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1417 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1418 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1422 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1423 * are converted at surface loading time, but they do not need any modification in
1424 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1425 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1429 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1431 idx = getFmtIdx(WINED3DFMT_ATI2N);
1432 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1433 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1435 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1437 idx = getFmtIdx(WINED3DFMT_ATI2N);
1438 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1439 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1442 if (!gl_info->supported[APPLE_YCBCR_422])
1444 idx = getFmtIdx(WINED3DFMT_YUY2);
1445 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1447 idx = getFmtIdx(WINED3DFMT_UYVY);
1448 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1451 idx = getFmtIdx(WINED3DFMT_YV12);
1452 gl_info->formats[idx].heightscale = 1.5f;
1453 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1455 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1457 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1458 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1461 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1463 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1464 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1467 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1469 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1470 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1471 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1472 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1474 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1475 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1479 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1483 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1485 struct wined3d_format *format;
1486 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1490 ERR("Format %s (%#x) not found.\n",
1491 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1495 format = &gl_info->formats[fmt_idx];
1496 format->emit_idx = format_vertex_info[i].emit_idx;
1497 format->component_count = format_vertex_info[i].component_count;
1498 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1499 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1500 format->gl_normalized = format_vertex_info[i].gl_normalized;
1501 format->component_size = format_vertex_info[i].component_size;
1507 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1509 if (!init_format_base_info(gl_info)) return FALSE;
1511 if (!init_format_compression_info(gl_info))
1513 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1514 gl_info->formats = NULL;
1521 /* Context activation is done by the caller. */
1522 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1524 if (!init_format_base_info(gl_info)) return FALSE;
1526 if (!init_format_compression_info(gl_info)) goto fail;
1527 if (!init_format_texture_info(gl_info)) goto fail;
1528 if (!init_format_vertex_info(gl_info)) goto fail;
1530 apply_format_fixups(gl_info);
1531 init_format_fbo_compat_info(gl_info);
1532 init_format_filter_info(gl_info, vendor);
1537 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1538 gl_info->formats = NULL;
1542 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1543 enum wined3d_format_id format_id)
1545 int idx = getFmtIdx(format_id);
1549 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1550 debug_d3dformat(format_id), format_id);
1551 /* Get the caller a valid pointer */
1552 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1555 return &gl_info->formats[idx];
1558 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1562 if (format->id == WINED3DFMT_UNKNOWN)
1566 else if (format->Flags & WINED3DFMT_FLAG_COMPRESSED)
1568 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1569 UINT row_count = (height + format->block_height - 1) / format->block_height;
1570 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1574 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1577 if (format->heightscale != 0.0f) size *= format->heightscale;
1582 /*****************************************************************************
1583 * Trace formatting of useful values
1585 const char *debug_d3dformat(enum wined3d_format_id format_id)
1589 #define FMT_TO_STR(format_id) case format_id: return #format_id
1590 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1591 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1592 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1593 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1594 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1595 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1596 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1597 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1598 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1599 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1600 FMT_TO_STR(WINED3DFMT_P8_UINT);
1601 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1602 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1603 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1604 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1605 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1606 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1607 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1608 FMT_TO_STR(WINED3DFMT_UYVY);
1609 FMT_TO_STR(WINED3DFMT_YUY2);
1610 FMT_TO_STR(WINED3DFMT_YV12);
1611 FMT_TO_STR(WINED3DFMT_DXT1);
1612 FMT_TO_STR(WINED3DFMT_DXT2);
1613 FMT_TO_STR(WINED3DFMT_DXT3);
1614 FMT_TO_STR(WINED3DFMT_DXT4);
1615 FMT_TO_STR(WINED3DFMT_DXT5);
1616 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1617 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1618 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1619 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1620 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1621 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1622 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1623 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1624 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1625 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1626 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1627 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1628 FMT_TO_STR(WINED3DFMT_ATI2N);
1629 FMT_TO_STR(WINED3DFMT_NVHU);
1630 FMT_TO_STR(WINED3DFMT_NVHS);
1631 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1632 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1633 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1634 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1635 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1636 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1637 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1638 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1639 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1640 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1641 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1642 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1643 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1644 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1645 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1646 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1647 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1648 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1649 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1650 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1651 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1652 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1653 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1654 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1655 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1656 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1657 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1658 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1659 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1660 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1661 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1662 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1663 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1664 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1665 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1666 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1667 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1668 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1669 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1670 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1671 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1672 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1673 FMT_TO_STR(WINED3DFMT_R32_UINT);
1674 FMT_TO_STR(WINED3DFMT_R32_SINT);
1675 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1676 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1677 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1678 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1679 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1680 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1681 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1682 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1683 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1684 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1685 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1686 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1687 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1688 FMT_TO_STR(WINED3DFMT_R16_UINT);
1689 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1690 FMT_TO_STR(WINED3DFMT_R16_SINT);
1691 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1692 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1693 FMT_TO_STR(WINED3DFMT_R8_UINT);
1694 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1695 FMT_TO_STR(WINED3DFMT_R8_SINT);
1696 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1697 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1698 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1699 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1700 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1701 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1702 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1703 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1704 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1705 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1706 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1707 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1708 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1709 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1710 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1711 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1712 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1713 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1714 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1715 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1716 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1717 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1718 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1719 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1724 fourcc[0] = (char)(format_id);
1725 fourcc[1] = (char)(format_id >> 8);
1726 fourcc[2] = (char)(format_id >> 16);
1727 fourcc[3] = (char)(format_id >> 24);
1729 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1730 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1732 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1734 return "unrecognized";
1738 const char *debug_d3ddevicetype(WINED3DDEVTYPE devtype)
1742 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1743 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1744 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1745 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1746 #undef DEVTYPE_TO_STR
1748 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1749 return "unrecognized";
1753 const char *debug_d3dusage(DWORD usage)
1758 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1759 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1760 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1761 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1762 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1763 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1764 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1765 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1766 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1767 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1768 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1769 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1770 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1771 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1772 #undef WINED3DUSAGE_TO_STR
1773 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1775 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1778 const char *debug_d3dusagequery(DWORD usagequery)
1783 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1784 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1785 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1786 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1787 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1788 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1789 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1790 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1791 #undef WINED3DUSAGEQUERY_TO_STR
1792 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1794 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1797 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1799 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1800 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1801 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1802 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1803 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1804 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1805 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1806 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1807 #undef WINED3DDECLMETHOD_TO_STR
1809 FIXME("Unrecognized %u declaration method!\n", method);
1810 return "unrecognized";
1814 const char* debug_d3ddeclusage(BYTE usage) {
1816 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1817 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1818 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1819 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1820 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1821 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1822 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1823 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1824 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1825 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1826 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1827 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1828 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1829 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1830 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1831 #undef WINED3DDECLUSAGE_TO_STR
1833 FIXME("Unrecognized %u declaration usage!\n", usage);
1834 return "unrecognized";
1838 const char *debug_d3dresourcetype(WINED3DRESOURCETYPE res)
1842 #define RES_TO_STR(res) case res: return #res
1843 RES_TO_STR(WINED3DRTYPE_SURFACE);
1844 RES_TO_STR(WINED3DRTYPE_VOLUME);
1845 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1846 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1847 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1848 RES_TO_STR(WINED3DRTYPE_BUFFER);
1851 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1852 return "unrecognized";
1856 const char *debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType)
1858 switch (PrimitiveType)
1860 #define PRIM_TO_STR(prim) case prim: return #prim
1861 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1862 PRIM_TO_STR(WINED3DPT_POINTLIST);
1863 PRIM_TO_STR(WINED3DPT_LINELIST);
1864 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1865 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1866 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1867 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1868 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1869 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1870 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1871 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1874 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1875 return "unrecognized";
1879 const char *debug_d3drenderstate(WINED3DRENDERSTATETYPE state)
1883 #define D3DSTATE_TO_STR(u) case u: return #u
1884 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS);
1885 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE);
1886 D3DSTATE_TO_STR(WINED3DRS_WRAPU);
1887 D3DSTATE_TO_STR(WINED3DRS_WRAPV);
1888 D3DSTATE_TO_STR(WINED3DRS_ZENABLE);
1889 D3DSTATE_TO_STR(WINED3DRS_FILLMODE);
1890 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE);
1891 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN);
1892 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE);
1893 D3DSTATE_TO_STR(WINED3DRS_ROP2);
1894 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK);
1895 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE);
1896 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE);
1897 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL);
1898 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND);
1899 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND);
1900 D3DSTATE_TO_STR(WINED3DRS_CULLMODE);
1901 D3DSTATE_TO_STR(WINED3DRS_ZFUNC);
1902 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF);
1903 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC);
1904 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE);
1905 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE);
1906 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE);
1907 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE);
1908 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE);
1909 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL);
1910 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX);
1911 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA);
1912 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR);
1913 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE);
1914 D3DSTATE_TO_STR(WINED3DRS_FOGSTART);
1915 D3DSTATE_TO_STR(WINED3DRS_FOGEND);
1916 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY);
1917 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE);
1918 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS);
1919 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE);
1920 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS);
1921 D3DSTATE_TO_STR(WINED3DRS_ZBIAS);
1922 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE);
1923 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY);
1924 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH);
1925 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1926 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE);
1927 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL);
1928 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL);
1929 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS);
1930 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC);
1931 D3DSTATE_TO_STR(WINED3DRS_STENCILREF);
1932 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK);
1933 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK);
1934 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR);
1935 D3DSTATE_TO_STR(WINED3DRS_WRAP0);
1936 D3DSTATE_TO_STR(WINED3DRS_WRAP1);
1937 D3DSTATE_TO_STR(WINED3DRS_WRAP2);
1938 D3DSTATE_TO_STR(WINED3DRS_WRAP3);
1939 D3DSTATE_TO_STR(WINED3DRS_WRAP4);
1940 D3DSTATE_TO_STR(WINED3DRS_WRAP5);
1941 D3DSTATE_TO_STR(WINED3DRS_WRAP6);
1942 D3DSTATE_TO_STR(WINED3DRS_WRAP7);
1943 D3DSTATE_TO_STR(WINED3DRS_CLIPPING);
1944 D3DSTATE_TO_STR(WINED3DRS_LIGHTING);
1945 D3DSTATE_TO_STR(WINED3DRS_EXTENTS);
1946 D3DSTATE_TO_STR(WINED3DRS_AMBIENT);
1947 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE);
1948 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX);
1949 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER);
1950 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS);
1951 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE);
1952 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE);
1953 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE);
1954 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE);
1955 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE);
1956 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND);
1957 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE);
1958 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING);
1959 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE);
1960 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN);
1961 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE);
1962 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE);
1963 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A);
1964 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B);
1965 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C);
1966 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS);
1967 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK);
1968 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE);
1969 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS);
1970 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN);
1971 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX);
1972 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE);
1973 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE);
1974 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR);
1975 D3DSTATE_TO_STR(WINED3DRS_BLENDOP);
1976 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE);
1977 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE);
1978 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE);
1979 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS);
1980 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE);
1981 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL);
1982 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL);
1983 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X);
1984 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y);
1985 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z);
1986 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W);
1987 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1988 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE);
1989 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL);
1990 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL);
1991 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS);
1992 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC);
1993 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1);
1994 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2);
1995 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3);
1996 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR);
1997 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE);
1998 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS);
1999 D3DSTATE_TO_STR(WINED3DRS_WRAP8);
2000 D3DSTATE_TO_STR(WINED3DRS_WRAP9);
2001 D3DSTATE_TO_STR(WINED3DRS_WRAP10);
2002 D3DSTATE_TO_STR(WINED3DRS_WRAP11);
2003 D3DSTATE_TO_STR(WINED3DRS_WRAP12);
2004 D3DSTATE_TO_STR(WINED3DRS_WRAP13);
2005 D3DSTATE_TO_STR(WINED3DRS_WRAP14);
2006 D3DSTATE_TO_STR(WINED3DRS_WRAP15);
2007 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE);
2008 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA);
2009 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA);
2010 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA);
2011 #undef D3DSTATE_TO_STR
2013 FIXME("Unrecognized %u render state!\n", state);
2014 return "unrecognized";
2018 const char *debug_d3dsamplerstate(DWORD state)
2022 #define D3DSTATE_TO_STR(u) case u: return #u
2023 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR);
2024 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU);
2025 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV);
2026 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW);
2027 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER);
2028 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER);
2029 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER);
2030 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
2031 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL);
2032 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
2033 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE);
2034 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX);
2035 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET);
2036 #undef D3DSTATE_TO_STR
2038 FIXME("Unrecognized %u sampler state!\n", state);
2039 return "unrecognized";
2043 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2044 switch (filter_type) {
2045 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2046 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2047 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2048 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2049 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2050 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2051 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2052 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2053 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2054 #undef D3DTEXTUREFILTERTYPE_TO_STR
2056 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2057 return "unrecognized";
2061 const char *debug_d3dtexturestate(DWORD state)
2065 #define D3DSTATE_TO_STR(u) case u: return #u
2066 D3DSTATE_TO_STR(WINED3DTSS_COLOROP);
2067 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1);
2068 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2);
2069 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP);
2070 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1);
2071 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2);
2072 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00);
2073 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01);
2074 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10);
2075 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11);
2076 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX);
2077 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE);
2078 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET);
2079 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS);
2080 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0);
2081 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0);
2082 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG);
2083 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT);
2084 #undef D3DSTATE_TO_STR
2086 FIXME("Unrecognized %u texture state!\n", state);
2087 return "unrecognized";
2091 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2093 #define D3DTOP_TO_STR(u) case u: return #u
2094 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2095 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2096 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2097 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2098 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2099 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2100 D3DTOP_TO_STR(WINED3DTOP_ADD);
2101 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2102 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2103 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2104 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2105 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2106 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2107 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2108 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2109 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2110 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2111 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2112 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2113 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2114 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2115 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2116 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2117 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2118 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2119 D3DTOP_TO_STR(WINED3DTOP_LERP);
2120 #undef D3DTOP_TO_STR
2122 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2123 return "unrecognized";
2127 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2129 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2130 TSTYPE_TO_STR(WINED3DTS_VIEW);
2131 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2132 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2133 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2134 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2135 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2136 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2137 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2138 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2139 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2140 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2141 #undef TSTYPE_TO_STR
2143 if (tstype > 256 && tstype < 512) {
2144 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2145 return ("WINED3DTS_WORLDMATRIX > 0");
2147 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2148 return "unrecognized";
2152 const char *debug_d3dstate(DWORD state)
2154 if (STATE_IS_RENDER(state))
2155 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2156 if (STATE_IS_TEXTURESTAGE(state))
2158 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2159 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2160 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2161 texture_stage, debug_d3dtexturestate(texture_state));
2163 if (STATE_IS_SAMPLER(state))
2164 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2165 if (STATE_IS_PIXELSHADER(state))
2166 return "STATE_PIXELSHADER";
2167 if (STATE_IS_TRANSFORM(state))
2168 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2169 if (STATE_IS_STREAMSRC(state))
2170 return "STATE_STREAMSRC";
2171 if (STATE_IS_INDEXBUFFER(state))
2172 return "STATE_INDEXBUFFER";
2173 if (STATE_IS_VDECL(state))
2174 return "STATE_VDECL";
2175 if (STATE_IS_VSHADER(state))
2176 return "STATE_VSHADER";
2177 if (STATE_IS_VIEWPORT(state))
2178 return "STATE_VIEWPORT";
2179 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2180 return "STATE_VERTEXSHADERCONSTANT";
2181 if (STATE_IS_PIXELSHADERCONSTANT(state))
2182 return "STATE_PIXELSHADERCONSTANT";
2183 if (STATE_IS_ACTIVELIGHT(state))
2184 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2185 if (STATE_IS_SCISSORRECT(state))
2186 return "STATE_SCISSORRECT";
2187 if (STATE_IS_CLIPPLANE(state))
2188 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2189 if (STATE_IS_MATERIAL(state))
2190 return "STATE_MATERIAL";
2191 if (STATE_IS_FRONTFACE(state))
2192 return "STATE_FRONTFACE";
2194 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2197 const char *debug_d3dpool(WINED3DPOOL pool)
2201 #define POOL_TO_STR(p) case p: return #p
2202 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2203 POOL_TO_STR(WINED3DPOOL_MANAGED);
2204 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2205 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2208 FIXME("Unrecognized %u WINED3DPOOL!\n", pool);
2209 return "unrecognized";
2213 const char *debug_fbostatus(GLenum status) {
2215 #define FBOSTATUS_TO_STR(u) case u: return #u
2216 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2217 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2218 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2219 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2220 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2221 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2222 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2223 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2224 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2225 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2226 #undef FBOSTATUS_TO_STR
2228 FIXME("Unrecognied FBO status 0x%08x\n", status);
2229 return "unrecognized";
2233 const char *debug_glerror(GLenum error) {
2235 #define GLERROR_TO_STR(u) case u: return #u
2236 GLERROR_TO_STR(GL_NO_ERROR);
2237 GLERROR_TO_STR(GL_INVALID_ENUM);
2238 GLERROR_TO_STR(GL_INVALID_VALUE);
2239 GLERROR_TO_STR(GL_INVALID_OPERATION);
2240 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2241 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2242 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2243 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2244 #undef GLERROR_TO_STR
2246 FIXME("Unrecognied GL error 0x%08x\n", error);
2247 return "unrecognized";
2251 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2253 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2254 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2255 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2256 default: return "unrecognized";
2260 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2262 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2263 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2264 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2265 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2266 default: return "unrecognized";
2270 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2274 #define WINED3D_TO_STR(x) case x: return #x
2275 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2276 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2277 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2278 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2279 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2280 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2281 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2282 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2283 #undef WINED3D_TO_STR
2285 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2286 return "unrecognized";
2290 static const char *debug_complex_fixup(enum complex_fixup fixup)
2294 #define WINED3D_TO_STR(x) case x: return #x
2295 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2296 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2297 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2298 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2299 #undef WINED3D_TO_STR
2301 FIXME("Unrecognized complex fixup %#x\n", fixup);
2302 return "unrecognized";
2306 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2308 if (is_complex_fixup(fixup))
2310 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2314 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2315 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2316 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2317 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2320 const char *debug_surflocation(DWORD flag) {
2324 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2325 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2326 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2327 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2328 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2331 /*****************************************************************************
2332 * Useful functions mapping GL <-> D3D values
2334 GLenum StencilOp(DWORD op) {
2336 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2337 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2338 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2339 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2340 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2341 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2342 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2343 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2345 FIXME("Unrecognized stencil op %d\n", op);
2350 GLenum CompareFunc(DWORD func) {
2351 switch ((WINED3DCMPFUNC)func) {
2352 case WINED3DCMP_NEVER : return GL_NEVER;
2353 case WINED3DCMP_LESS : return GL_LESS;
2354 case WINED3DCMP_EQUAL : return GL_EQUAL;
2355 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2356 case WINED3DCMP_GREATER : return GL_GREATER;
2357 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2358 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2359 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2361 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2366 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
2367 if (op == WINED3DTOP_DISABLE) return FALSE;
2368 if (This->stateBlock->textures[stage]) return FALSE;
2370 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2371 && op != WINED3DTOP_SELECTARG2) return TRUE;
2372 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2373 && op != WINED3DTOP_SELECTARG1) return TRUE;
2374 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2375 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2380 /* Setup this textures matrix according to the texture flags*/
2381 /* GL locking is done by the caller (state handler) */
2382 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2383 enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2387 glMatrixMode(GL_TEXTURE);
2388 checkGLcall("glMatrixMode(GL_TEXTURE)");
2390 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2392 checkGLcall("glLoadIdentity()");
2396 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2397 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2401 memcpy(mat, smat, 16 * sizeof(float));
2403 if (flags & WINED3DTTFF_PROJECTED) {
2404 if(!ffp_proj_control) {
2405 switch (flags & ~WINED3DTTFF_PROJECTED) {
2406 case WINED3DTTFF_COUNT2:
2407 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2408 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2410 case WINED3DTTFF_COUNT3:
2411 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2412 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2416 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2417 if(!calculatedCoords) {
2420 case WINED3DFMT_R32_FLOAT:
2421 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2422 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2423 * the input value to the transformation will be 0, so the matrix value is irrelevant
2430 case WINED3DFMT_R32G32_FLOAT:
2431 /* See above, just 3rd and 4th coord
2438 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2439 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2441 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2442 * into a bad place. The division elimination below will apply to make sure the
2443 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2445 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2448 FIXME("Unexpected fixed function texture coord input\n");
2451 if(!ffp_proj_control) {
2452 switch (flags & ~WINED3DTTFF_PROJECTED) {
2453 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2454 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2455 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2456 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2457 * the 4th coord evaluates to 1.0 to eliminate that.
2459 * If the fixed function pipeline is used, the 4th value remains unused,
2460 * so there is no danger in doing this. With vertex shaders we have a
2461 * problem. Should an app hit that problem, the code here would have to
2462 * check for pixel shaders, and the shader has to undo the default gl divide.
2464 * A more serious problem occurs if the app passes 4 coordinates in, and the
2465 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2466 * or a replacement shader
2468 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2474 checkGLcall("glLoadMatrixf(mat)");
2477 /* This small helper function is used to convert a bitmask into the number of masked bits */
2478 unsigned int count_bits(unsigned int mask)
2481 for (count = 0; mask; ++count)
2488 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2489 * The later function requires individual color components. */
2490 BOOL getColorBits(const struct wined3d_format *format,
2491 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2493 TRACE("format %s.\n", debug_d3dformat(format->id));
2497 case WINED3DFMT_B8G8R8X8_UNORM:
2498 case WINED3DFMT_B8G8R8_UNORM:
2499 case WINED3DFMT_B8G8R8A8_UNORM:
2500 case WINED3DFMT_R8G8B8A8_UNORM:
2501 case WINED3DFMT_B10G10R10A2_UNORM:
2502 case WINED3DFMT_B5G5R5X1_UNORM:
2503 case WINED3DFMT_B5G5R5A1_UNORM:
2504 case WINED3DFMT_B5G6R5_UNORM:
2505 case WINED3DFMT_B4G4R4X4_UNORM:
2506 case WINED3DFMT_B4G4R4A4_UNORM:
2507 case WINED3DFMT_B2G3R3_UNORM:
2508 case WINED3DFMT_P8_UINT_A8_UNORM:
2509 case WINED3DFMT_P8_UINT:
2512 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2516 *redSize = count_bits(format->red_mask);
2517 *greenSize = count_bits(format->green_mask);
2518 *blueSize = count_bits(format->blue_mask);
2519 *alphaSize = count_bits(format->alpha_mask);
2520 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2522 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2523 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2527 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2528 BOOL getDepthStencilBits(const struct wined3d_format *format, short *depthSize, short *stencilSize)
2530 TRACE("format %s.\n", debug_d3dformat(format->id));
2534 case WINED3DFMT_D16_LOCKABLE:
2535 case WINED3DFMT_D16_UNORM:
2536 case WINED3DFMT_S1_UINT_D15_UNORM:
2537 case WINED3DFMT_X8D24_UNORM:
2538 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2539 case WINED3DFMT_D24_UNORM_S8_UINT:
2540 case WINED3DFMT_S8_UINT_D24_FLOAT:
2541 case WINED3DFMT_D32_UNORM:
2542 case WINED3DFMT_D32_FLOAT:
2545 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2549 *depthSize = format->depth_size;
2550 *stencilSize = format->stencil_size;
2552 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2553 *depthSize, *stencilSize, debug_d3dformat(format->id));
2557 /* Note: It's the caller's responsibility to ensure values can be expressed
2558 * in the requested format. UNORM formats for example can only express values
2559 * in the range 0.0f -> 1.0f. */
2560 DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, const WINED3DCOLORVALUE *color)
2564 enum wined3d_format_id format_id;
2576 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2577 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2578 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2579 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2580 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2581 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2582 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2583 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2584 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2585 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2586 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2587 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2588 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2589 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2593 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2594 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2596 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2600 if (format->id != conv[i].format_id) continue;
2602 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2603 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2604 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2605 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2607 TRACE("Returning 0x%08x.\n", ret);
2612 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2617 /* DirectDraw stuff */
2618 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2622 case 8: return WINED3DFMT_P8_UINT;
2623 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2624 case 16: return WINED3DFMT_B5G6R5_UNORM;
2625 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2626 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2627 default: return WINED3DFMT_UNKNOWN;
2631 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2634 /* Now do the multiplication 'by hand'.
2635 I know that all this could be optimised, but this will be done later :-) */
2636 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);
2637 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);
2638 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);
2639 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);
2641 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);
2642 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);
2643 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);
2644 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);
2646 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);
2647 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);
2648 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);
2649 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);
2651 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);
2652 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);
2653 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);
2654 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);
2656 /* And copy the new matrix in the good storage.. */
2657 memcpy(dest, &temp, 16 * sizeof(float));
2660 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2663 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2665 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2666 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2667 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2668 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2669 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2670 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2671 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2672 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2673 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2674 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2675 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2676 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2677 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2678 default: ERR("Unexpected position mask\n");
2680 for (i = 0; i < numTextures; i++) {
2681 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2687 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2691 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2693 /* D3DTOP_DISABLE */ 0,
2694 /* D3DTOP_SELECTARG1 */ ARG1,
2695 /* D3DTOP_SELECTARG2 */ ARG2,
2696 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2697 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2698 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2699 /* D3DTOP_ADD */ ARG1 | ARG2,
2700 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2701 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2702 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2703 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2704 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2705 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2706 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2707 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2708 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2709 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2710 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2711 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2712 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2713 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2714 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2715 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2716 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2717 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2718 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2722 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2723 IWineD3DDeviceImpl *device = stateblock->device;
2724 IWineD3DSurfaceImpl *rt = device->render_targets[0];
2725 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2727 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2729 IWineD3DBaseTextureImpl *texture;
2730 settings->op[i].padding = 0;
2731 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2732 settings->op[i].cop = WINED3DTOP_DISABLE;
2733 settings->op[i].aop = WINED3DTOP_DISABLE;
2734 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2735 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2736 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2737 settings->op[i].dst = resultreg;
2738 settings->op[i].tex_type = tex_1d;
2739 settings->op[i].projected = proj_none;
2744 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2747 settings->op[i].color_fixup = texture->resource.format->color_fixup;
2750 settings->op[i].tex_type = tex_1d;
2752 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2754 settings->op[i].tex_type = tex_1d;
2757 settings->op[i].tex_type = tex_2d;
2760 settings->op[i].tex_type = tex_3d;
2762 case GL_TEXTURE_CUBE_MAP_ARB:
2763 settings->op[i].tex_type = tex_cube;
2765 case GL_TEXTURE_RECTANGLE_ARB:
2766 settings->op[i].tex_type = tex_rect;
2771 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2772 settings->op[i].tex_type = tex_1d;
2775 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2776 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2778 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2779 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2780 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2782 if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2785 carg1 = WINED3DTA_CURRENT;
2786 cop = WINED3DTOP_SELECTARG1;
2789 if(cop == WINED3DTOP_DOTPRODUCT3) {
2790 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2791 * the color result to the alpha component of the destination
2798 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2799 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2800 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2803 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2805 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2807 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2809 IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)stateblock->textures[0];
2810 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
2812 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
2814 if (aop == WINED3DTOP_DISABLE)
2816 aarg1 = WINED3DTA_TEXTURE;
2817 aop = WINED3DTOP_SELECTARG1;
2819 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2821 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2823 aarg2 = WINED3DTA_TEXTURE;
2824 aop = WINED3DTOP_MODULATE;
2826 else aarg1 = WINED3DTA_TEXTURE;
2828 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2830 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2832 aarg1 = WINED3DTA_TEXTURE;
2833 aop = WINED3DTOP_MODULATE;
2835 else aarg2 = WINED3DTA_TEXTURE;
2841 if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2844 aarg1 = WINED3DTA_CURRENT;
2845 aop = WINED3DTOP_SELECTARG1;
2848 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2849 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2850 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2851 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2852 settings->op[i].projected = proj_count3;
2853 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2854 settings->op[i].projected = proj_count4;
2856 settings->op[i].projected = proj_none;
2859 settings->op[i].projected = proj_none;
2862 settings->op[i].cop = cop;
2863 settings->op[i].aop = aop;
2864 settings->op[i].carg0 = carg0;
2865 settings->op[i].carg1 = carg1;
2866 settings->op[i].carg2 = carg2;
2867 settings->op[i].aarg0 = aarg0;
2868 settings->op[i].aarg1 = aarg1;
2869 settings->op[i].aarg2 = aarg2;
2871 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2872 settings->op[i].dst = tempreg;
2874 settings->op[i].dst = resultreg;
2878 /* Clear unsupported stages */
2879 for(; i < MAX_TEXTURES; i++) {
2880 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2883 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2884 settings->fog = FOG_OFF;
2885 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2886 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2887 settings->fog = FOG_LINEAR;
2889 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2890 case WINED3DFOG_NONE:
2891 case WINED3DFOG_LINEAR:
2892 settings->fog = FOG_LINEAR;
2894 case WINED3DFOG_EXP:
2895 settings->fog = FOG_EXP;
2897 case WINED3DFOG_EXP2:
2898 settings->fog = FOG_EXP2;
2903 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2904 case WINED3DFOG_LINEAR:
2905 settings->fog = FOG_LINEAR;
2907 case WINED3DFOG_EXP:
2908 settings->fog = FOG_EXP;
2910 case WINED3DFOG_EXP2:
2911 settings->fog = FOG_EXP2;
2915 if (stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]
2916 && rt->resource.format->Flags & WINED3DFMT_FLAG_SRGB_WRITE)
2918 settings->sRGB_write = 1;
2920 settings->sRGB_write = 0;
2922 if(device->vs_clipping || !use_vs(stateblock) || !stateblock->renderState[WINED3DRS_CLIPPING] ||
2923 !stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
2924 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2925 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2926 * if no clipplane is enabled
2928 settings->emul_clipplanes = 0;
2930 settings->emul_clipplanes = 1;
2934 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2935 const struct ffp_frag_settings *settings)
2937 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2938 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2941 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2943 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2944 * whereas desc points to an extended structure with implementation specific parts. */
2945 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2947 ERR("Failed to insert ffp frag shader.\n");
2951 /* Activates the texture dimension according to the bound D3D texture.
2952 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2953 * Requires the caller to activate the correct unit before
2955 /* GL locking is done by the caller (state handler) */
2956 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2958 const struct wined3d_gl_info *gl_info = context->gl_info;
2960 if (stateblock->textures[stage])
2962 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2964 glDisable(GL_TEXTURE_3D);
2965 checkGLcall("glDisable(GL_TEXTURE_3D)");
2966 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2968 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2969 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2971 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2973 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2974 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2976 glEnable(GL_TEXTURE_2D);
2977 checkGLcall("glEnable(GL_TEXTURE_2D)");
2979 case GL_TEXTURE_RECTANGLE_ARB:
2980 glDisable(GL_TEXTURE_2D);
2981 checkGLcall("glDisable(GL_TEXTURE_2D)");
2982 glDisable(GL_TEXTURE_3D);
2983 checkGLcall("glDisable(GL_TEXTURE_3D)");
2984 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2986 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2987 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2989 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2990 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2993 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2995 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2996 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2998 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3000 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3001 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3003 glDisable(GL_TEXTURE_2D);
3004 checkGLcall("glDisable(GL_TEXTURE_2D)");
3005 glEnable(GL_TEXTURE_3D);
3006 checkGLcall("glEnable(GL_TEXTURE_3D)");
3008 case GL_TEXTURE_CUBE_MAP_ARB:
3009 glDisable(GL_TEXTURE_2D);
3010 checkGLcall("glDisable(GL_TEXTURE_2D)");
3011 glDisable(GL_TEXTURE_3D);
3012 checkGLcall("glDisable(GL_TEXTURE_3D)");
3013 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3015 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3016 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3018 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3019 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3023 glEnable(GL_TEXTURE_2D);
3024 checkGLcall("glEnable(GL_TEXTURE_2D)");
3025 glDisable(GL_TEXTURE_3D);
3026 checkGLcall("glDisable(GL_TEXTURE_3D)");
3027 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3029 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3030 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3032 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3034 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3035 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3037 /* Binding textures is done by samplers. A dummy texture will be bound */
3041 /* GL locking is done by the caller (state handler) */
3042 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3044 DWORD sampler = state - STATE_SAMPLER(0);
3045 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3047 /* No need to enable / disable anything here for unused samplers. The tex_colorop
3048 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3049 * will take care of this business
3051 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3052 if(sampler >= stateblock->lowest_disabled_stage) return;
3053 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3055 texture_activate_dimensions(sampler, stateblock, context);
3058 void *wined3d_rb_alloc(size_t size)
3060 return HeapAlloc(GetProcessHeap(), 0, size);
3063 void *wined3d_rb_realloc(void *ptr, size_t size)
3065 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3068 void wined3d_rb_free(void *ptr)
3070 HeapFree(GetProcessHeap(), 0, ptr);
3073 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3075 const struct ffp_frag_settings *ka = key;
3076 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3078 return memcmp(ka, kb, sizeof(*ka));
3081 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3086 ffp_frag_program_key_compare,
3089 UINT wined3d_log2i(UINT32 x)
3091 static const UINT l[] =
3093 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3094 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3095 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3096 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3097 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3098 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3099 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3100 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3101 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3102 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3103 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3104 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3105 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3106 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3107 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3108 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3112 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3115 /* Set the shader type for this device, depending on the given capabilities
3116 * and the user preferences in wined3d_settings. */
3117 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3119 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3121 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3122 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3124 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3125 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3126 * shaders only on this card. */
3127 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3128 else *vs_selected = SHADER_GLSL;
3130 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3131 else *vs_selected = SHADER_NONE;
3133 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3134 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3135 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3136 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3137 else *ps_selected = SHADER_NONE;
3140 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
3141 const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format *src_format,
3142 const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format *dst_format)
3144 static const struct blit_shader * const blitters[] =
3152 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3154 if (blitters[i]->blit_supported(gl_info, blit_op,
3155 src_rect, src_usage, src_pool, src_format,
3156 dst_rect, dst_usage, dst_pool, dst_format))