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-2010 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 BYTE 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_NVDB, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
133 {WINED3DFMT_INTZ, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
134 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
135 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
136 {WINED3DFMT_NULL, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
137 /* Unsure about them, could not find a Windows driver that supports them */
138 {WINED3DFMT_R16, 0x0, 0x0000ffff, 0x0, 0x0, 2, 0, 0},
139 {WINED3DFMT_AL16, 0xffff0000, 0x0, 0x0, 0x0, 4, 0, 0},
142 struct wined3d_format_base_flags
144 enum wined3d_format_id id;
148 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
149 * still needs to use the correct block based calculation for e.g. the
151 static const struct wined3d_format_base_flags format_base_flags[] =
153 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
156 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
157 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
158 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
159 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
160 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
161 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
162 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
163 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
164 {WINED3DFMT_INTZ, WINED3DFMT_FLAG_FOURCC},
165 {WINED3DFMT_NULL, WINED3DFMT_FLAG_FOURCC},
166 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
171 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
172 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
173 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
174 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
175 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
176 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
177 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
178 {WINED3DFMT_NVDB, WINED3DFMT_FLAG_FOURCC},
179 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
180 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
181 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
182 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
184 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
185 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
186 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
187 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
188 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
189 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
192 struct wined3d_format_compression_info
194 enum wined3d_format_id id;
197 UINT block_byte_count;
200 static const struct wined3d_format_compression_info format_compression_info[] =
202 {WINED3DFMT_DXT1, 4, 4, 8},
203 {WINED3DFMT_DXT2, 4, 4, 16},
204 {WINED3DFMT_DXT3, 4, 4, 16},
205 {WINED3DFMT_DXT4, 4, 4, 16},
206 {WINED3DFMT_DXT5, 4, 4, 16},
207 {WINED3DFMT_ATI2N, 4, 4, 16},
210 struct wined3d_format_vertex_info
212 enum wined3d_format_id id;
213 enum wined3d_ffp_emit_idx emit_idx;
214 GLint component_count;
217 GLboolean gl_normalized;
218 unsigned int component_size;
221 static const struct wined3d_format_vertex_info format_vertex_info[] =
223 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
224 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
225 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
226 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
227 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
228 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
229 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
230 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
231 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
232 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
233 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
234 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
235 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
236 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
237 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
238 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
239 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
242 struct wined3d_format_texture_info
244 enum wined3d_format_id id;
246 GLint gl_srgb_internal;
247 GLint gl_rt_internal;
250 unsigned int conv_byte_count;
252 GL_SupportedExt extension;
253 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
256 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
258 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
259 * format+type combination to load it. Thus convert it to A8L8, then load it
260 * with A4L4 internal, but A8L8 format+type
263 const unsigned char *Source;
265 UINT outpitch = pitch * 2;
267 for(y = 0; y < height; y++) {
268 Source = src + y * pitch;
269 Dest = dst + y * outpitch;
270 for (x = 0; x < width; x++ ) {
271 unsigned char color = (*Source++);
272 /* A */ Dest[1] = (color & 0xf0) << 0;
273 /* L */ Dest[0] = (color & 0x0f) << 4;
279 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
284 for(y = 0; y < height; y++)
286 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
287 Source = (const WORD *)(src + y * pitch);
288 for (x = 0; x < width; x++ )
290 short color = (*Source++);
291 unsigned char l = ((color >> 10) & 0xfc);
292 short v = ((color >> 5) & 0x3e);
293 short u = ((color ) & 0x1f);
294 short v_conv = v + 16;
295 short u_conv = u + 16;
297 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
303 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
308 UINT outpitch = (pitch * 3)/2;
310 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
311 * fixed function and shaders without further conversion once the surface is
314 for(y = 0; y < height; y++) {
315 Source = (const WORD *)(src + y * pitch);
316 Dest = dst + y * outpitch;
317 for (x = 0; x < width; x++ ) {
318 short color = (*Source++);
319 unsigned char l = ((color >> 10) & 0xfc);
320 char v = ((color >> 5) & 0x3e);
321 char u = ((color ) & 0x1f);
323 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
324 * and doubles the positive range. Thus shift left only once, gl does the 2nd
325 * shift. GL reads a signed value and converts it into an unsigned value.
327 /* M */ Dest[2] = l << 1;
329 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
330 * from 5 bit values to 8 bit values.
332 /* V */ Dest[1] = v << 3;
333 /* U */ Dest[0] = u << 3;
339 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
344 UINT outpitch = (pitch * 3)/2;
346 for(y = 0; y < height; y++)
348 Source = (const short *)(src + y * pitch);
349 Dest = dst + y * outpitch;
350 for (x = 0; x < width; x++ )
352 const short color = (*Source++);
353 /* B */ Dest[0] = 0xff;
354 /* G */ Dest[1] = (color >> 8) + 128; /* V */
355 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
361 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
367 /* Doesn't work correctly with the fixed function pipeline, but can work in
368 * shaders if the shader is adjusted. (There's no use for this format in gl's
369 * standard fixed function pipeline anyway).
371 for(y = 0; y < height; y++)
373 Source = (const DWORD *)(src + y * pitch);
374 Dest = dst + y * pitch;
375 for (x = 0; x < width; x++ )
377 LONG color = (*Source++);
378 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
379 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
380 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
386 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
392 /* This implementation works with the fixed function pipeline and shaders
393 * without further modification after converting the surface.
395 for(y = 0; y < height; y++)
397 Source = (const DWORD *)(src + y * pitch);
398 Dest = dst + y * pitch;
399 for (x = 0; x < width; x++ )
401 LONG color = (*Source++);
402 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
403 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
404 /* U */ Dest[0] = (color & 0xff); /* U */
405 /* I */ Dest[3] = 255; /* X */
411 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
417 for(y = 0; y < height; y++)
419 Source = (const DWORD *)(src + y * pitch);
420 Dest = dst + y * pitch;
421 for (x = 0; x < width; x++ )
423 LONG color = (*Source++);
424 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
425 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
426 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
427 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
433 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
437 unsigned short *Dest;
438 UINT outpitch = (pitch * 3)/2;
440 for(y = 0; y < height; y++)
442 Source = (const DWORD *)(src + y * pitch);
443 Dest = (unsigned short *) (dst + y * outpitch);
444 for (x = 0; x < width; x++ )
446 const DWORD color = (*Source++);
447 /* B */ Dest[0] = 0xffff;
448 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
449 /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */
455 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
460 UINT outpitch = (pitch * 3)/2;
462 for(y = 0; y < height; y++)
464 Source = (const WORD *)(src + y * pitch);
465 Dest = (WORD *) (dst + y * outpitch);
466 for (x = 0; x < width; x++ )
468 WORD green = (*Source++);
469 WORD red = (*Source++);
472 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
473 * shader overwrites it anyway
481 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
486 UINT outpitch = (pitch * 3)/2;
488 for(y = 0; y < height; y++)
490 Source = (const float *)(src + y * pitch);
491 Dest = (float *) (dst + y * outpitch);
492 for (x = 0; x < width; x++ )
494 float green = (*Source++);
495 float red = (*Source++);
504 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
507 UINT outpitch = pitch * 2;
509 for (y = 0; y < height; ++y)
511 const WORD *source = (const WORD *)(src + y * pitch);
512 DWORD *dest = (DWORD *)(dst + y * outpitch);
514 for (x = 0; x < width; ++x)
516 /* The depth data is normalized, so needs to be scaled,
517 * the stencil data isn't. Scale depth data by
518 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
519 WORD d15 = source[x] >> 1;
520 DWORD d24 = (d15 << 9) + (d15 >> 6);
521 dest[x] = (d24 << 8) | (source[x] & 0x1);
526 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
530 for (y = 0; y < height; ++y)
532 const DWORD *source = (const DWORD *)(src + y * pitch);
533 DWORD *dest = (DWORD *)(dst + y * pitch);
535 for (x = 0; x < width; ++x)
537 /* Just need to clear out the X4 part. */
538 dest[x] = source[x] & ~0xf0;
543 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
546 UINT outpitch = pitch * 2;
548 for (y = 0; y < height; ++y)
550 const DWORD *source = (const DWORD *)(src + y * pitch);
551 float *dest_f = (float *)(dst + y * outpitch);
552 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
554 for (x = 0; x < width; ++x)
556 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
557 dest_s[x * 2 + 1] = source[x] & 0xff;
562 static const struct wined3d_format_texture_info format_texture_info[] =
564 /* format id internal srgbInternal rtInternal
569 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
570 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
571 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
572 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
575 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
576 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
577 WINED3DFMT_FLAG_FILTERING,
578 WINED3D_GL_EXT_NONE, NULL},
579 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
580 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
581 WINED3DFMT_FLAG_FILTERING,
582 APPLE_YCBCR_422, NULL},
583 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
584 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
585 WINED3DFMT_FLAG_FILTERING,
586 WINED3D_GL_EXT_NONE, NULL},
587 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
588 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
589 WINED3DFMT_FLAG_FILTERING,
590 APPLE_YCBCR_422, NULL},
591 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
592 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
593 WINED3DFMT_FLAG_FILTERING,
594 WINED3D_GL_EXT_NONE, NULL},
595 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
596 GL_RGBA, GL_UNSIGNED_BYTE, 0,
597 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
598 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
599 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
600 GL_RGBA, GL_UNSIGNED_BYTE, 0,
601 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
602 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
603 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
604 GL_RGBA, GL_UNSIGNED_BYTE, 0,
605 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
606 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
607 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
608 GL_RGBA, GL_UNSIGNED_BYTE, 0,
609 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
610 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
611 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
612 GL_RGBA, GL_UNSIGNED_BYTE, 0,
613 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
614 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
616 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
618 WINED3DFMT_FLAG_RENDERTARGET,
619 ARB_TEXTURE_FLOAT, NULL},
620 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
622 WINED3DFMT_FLAG_RENDERTARGET,
623 ARB_TEXTURE_RG, NULL},
624 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
625 GL_RGB, GL_FLOAT, 12,
626 WINED3DFMT_FLAG_RENDERTARGET,
627 ARB_TEXTURE_FLOAT, &convert_r32g32_float},
628 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
630 WINED3DFMT_FLAG_RENDERTARGET,
631 ARB_TEXTURE_RG, NULL},
632 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
633 GL_RGBA, GL_FLOAT, 0,
634 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
635 ARB_TEXTURE_FLOAT, NULL},
637 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
638 GL_RED, GL_HALF_FLOAT_ARB, 0,
639 WINED3DFMT_FLAG_RENDERTARGET,
640 ARB_TEXTURE_FLOAT, NULL},
641 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
642 GL_RED, GL_HALF_FLOAT_ARB, 0,
643 WINED3DFMT_FLAG_RENDERTARGET,
644 ARB_TEXTURE_RG, NULL},
645 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
646 GL_RGB, GL_HALF_FLOAT_ARB, 6,
647 WINED3DFMT_FLAG_RENDERTARGET,
648 ARB_TEXTURE_FLOAT, &convert_r16g16},
649 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
650 GL_RG, GL_HALF_FLOAT_ARB, 0,
651 WINED3DFMT_FLAG_RENDERTARGET,
652 ARB_TEXTURE_RG, NULL},
653 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
654 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
655 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
656 ARB_TEXTURE_FLOAT, NULL},
657 /* Palettized formats */
658 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
659 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
661 ARB_FRAGMENT_PROGRAM, NULL},
662 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
663 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
665 EXT_PALETTED_TEXTURE, NULL},
666 /* Standard ARGB formats */
667 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
668 GL_BGR, GL_UNSIGNED_BYTE, 0,
669 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
670 WINED3D_GL_EXT_NONE, NULL},
671 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
672 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
673 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
674 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
675 WINED3D_GL_EXT_NONE, NULL},
676 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
677 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
678 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
679 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
680 WINED3D_GL_EXT_NONE, NULL},
681 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
682 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
683 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
684 WINED3D_GL_EXT_NONE, NULL},
685 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
686 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
687 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
688 WINED3D_GL_EXT_NONE, NULL},
689 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
690 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
691 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
692 WINED3D_GL_EXT_NONE, NULL},
693 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
694 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
695 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
696 WINED3D_GL_EXT_NONE, NULL},
697 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
698 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
699 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
700 WINED3D_GL_EXT_NONE, NULL},
701 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
702 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
703 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
704 WINED3D_GL_EXT_NONE, NULL},
705 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
706 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
707 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
708 WINED3D_GL_EXT_NONE, NULL},
709 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
710 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
711 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
712 WINED3D_GL_EXT_NONE, NULL},
713 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
714 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
715 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
716 WINED3D_GL_EXT_NONE, NULL},
717 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
718 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
719 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
720 WINED3D_GL_EXT_NONE, NULL},
721 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
722 GL_RGB, GL_UNSIGNED_SHORT, 6,
723 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
724 WINED3D_GL_EXT_NONE, &convert_r16g16},
725 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
726 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
727 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
728 WINED3D_GL_EXT_NONE, NULL},
729 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
730 GL_RGBA, GL_UNSIGNED_SHORT, 0,
731 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
732 WINED3D_GL_EXT_NONE, NULL},
734 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
735 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
736 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
737 WINED3D_GL_EXT_NONE, NULL},
738 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
739 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
740 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
741 WINED3D_GL_EXT_NONE, NULL},
742 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
743 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
744 WINED3DFMT_FLAG_FILTERING,
745 WINED3D_GL_EXT_NONE, &convert_l4a4_unorm},
746 /* Bump mapping stuff */
747 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
748 GL_BGR, GL_UNSIGNED_BYTE, 3,
749 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
750 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm},
751 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
752 GL_DSDT_NV, GL_BYTE, 0,
753 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
754 NV_TEXTURE_SHADER, NULL},
755 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
756 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
757 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
758 WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm},
759 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
760 GL_DSDT_MAG_NV, GL_BYTE, 3,
761 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
762 NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv},
763 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
764 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
765 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
766 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm},
767 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
768 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
769 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
770 NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv},
771 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
772 GL_BGRA, GL_UNSIGNED_BYTE, 4,
773 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
774 WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm},
775 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
777 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
778 NV_TEXTURE_SHADER, NULL},
779 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
780 GL_BGR, GL_UNSIGNED_SHORT, 6,
781 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
782 WINED3D_GL_EXT_NONE, &convert_r16g16_snorm},
783 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
784 GL_HILO_NV, GL_SHORT, 0,
785 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
786 NV_TEXTURE_SHADER, NULL},
787 /* Depth stencil formats */
788 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
789 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
790 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
791 ARB_DEPTH_TEXTURE, NULL},
792 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
793 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
794 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
795 ARB_DEPTH_TEXTURE, NULL},
796 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
797 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
798 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
799 ARB_DEPTH_TEXTURE, NULL},
800 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
801 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
802 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
803 EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm},
804 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
805 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
806 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
807 ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm},
808 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
809 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
810 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
811 | WINED3DFMT_FLAG_SHADOW,
812 ARB_DEPTH_TEXTURE, NULL},
813 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
814 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
815 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
816 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
817 EXT_PACKED_DEPTH_STENCIL, NULL},
818 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
819 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
820 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
821 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
822 ARB_FRAMEBUFFER_OBJECT, NULL},
823 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
824 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
825 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
826 | WINED3DFMT_FLAG_SHADOW,
827 ARB_DEPTH_TEXTURE, NULL},
828 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
829 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
830 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
831 ARB_DEPTH_TEXTURE, NULL},
832 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
833 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
834 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
835 EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm},
836 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
837 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
838 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
839 ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm},
840 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
841 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
842 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
843 | WINED3DFMT_FLAG_SHADOW,
844 ARB_DEPTH_TEXTURE, NULL},
845 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
846 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
847 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
848 WINED3D_GL_EXT_NONE, NULL},
849 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
850 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
851 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
852 ARB_DEPTH_BUFFER_FLOAT, NULL},
853 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
854 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
855 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
856 ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float},
857 /* Vendor-specific formats */
858 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
859 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
860 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
861 ATI_TEXTURE_COMPRESSION_3DC, NULL},
862 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2, GL_COMPRESSED_RED_GREEN_RGTC2, 0,
863 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
864 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
865 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
866 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
867 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
868 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
869 | WINED3DFMT_FLAG_STENCIL,
870 EXT_PACKED_DEPTH_STENCIL, NULL},
871 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
872 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
873 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
874 | WINED3DFMT_FLAG_STENCIL,
875 ARB_FRAMEBUFFER_OBJECT, NULL},
876 {WINED3DFMT_NULL, GL_RGBA8, GL_RGBA8, 0,
877 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
878 WINED3DFMT_FLAG_RENDERTARGET,
879 ARB_FRAMEBUFFER_OBJECT, NULL},
882 static inline int getFmtIdx(enum wined3d_format_id format_id)
884 /* First check if the format is at the position of its value.
885 * This will catch the argb formats before the loop is entered. */
886 if (format_id < (sizeof(formats) / sizeof(*formats))
887 && formats[format_id].id == format_id)
895 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
897 if (formats[i].id == format_id) return i;
903 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
905 UINT format_count = sizeof(formats) / sizeof(*formats);
908 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
909 if (!gl_info->formats)
911 ERR("Failed to allocate memory.\n");
915 for (i = 0; i < format_count; ++i)
917 struct wined3d_format *format = &gl_info->formats[i];
918 format->id = formats[i].id;
919 format->red_mask = formats[i].redMask;
920 format->green_mask = formats[i].greenMask;
921 format->blue_mask = formats[i].blueMask;
922 format->alpha_mask = formats[i].alphaMask;
923 format->byte_count = formats[i].bpp;
924 format->depth_size = formats[i].depthSize;
925 format->stencil_size = formats[i].stencilSize;
928 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
930 int fmt_idx = getFmtIdx(format_base_flags[i].id);
934 ERR("Format %s (%#x) not found.\n",
935 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
936 HeapFree(GetProcessHeap(), 0, gl_info->formats);
940 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
946 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
950 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
952 struct wined3d_format *format;
953 int fmt_idx = getFmtIdx(format_compression_info[i].id);
957 ERR("Format %s (%#x) not found.\n",
958 debug_d3dformat(format_compression_info[i].id), format_compression_info[i].id);
962 format = &gl_info->formats[fmt_idx];
963 format->block_width = format_compression_info[i].block_width;
964 format->block_height = format_compression_info[i].block_height;
965 format->block_byte_count = format_compression_info[i].block_byte_count;
966 format->flags |= WINED3DFMT_FLAG_COMPRESSED;
972 /* Context activation is done by the caller. */
973 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
975 /* Check if the default internal format is supported as a frame buffer
976 * target, otherwise fall back to the render target internal.
978 * Try to stick to the standard format if possible, this limits precision differences. */
987 glGenTextures(1, &tex);
988 glBindTexture(GL_TEXTURE_2D, tex);
990 glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
991 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
992 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
994 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
996 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
997 checkGLcall("Framebuffer format check");
999 if (status == GL_FRAMEBUFFER_COMPLETE)
1001 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1002 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1003 format->rtInternal = format->glInternal;
1007 if (!format->rtInternal)
1009 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1011 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1012 " and no fallback specified.\n", debug_d3dformat(format->id));
1013 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1017 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1019 format->rtInternal = format->glInternal;
1023 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1024 debug_d3dformat(format->id));
1026 while(glGetError());
1028 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1030 glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1031 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1032 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1034 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1036 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1037 checkGLcall("Framebuffer format check");
1039 if (status == GL_FRAMEBUFFER_COMPLETE)
1041 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1042 debug_d3dformat(format->id));
1046 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1047 debug_d3dformat(format->id));
1048 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1053 if (status == GL_FRAMEBUFFER_COMPLETE && format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1057 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1058 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1060 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1061 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1062 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1063 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1064 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1065 checkGLcall("RB attachment");
1069 glClear(GL_COLOR_BUFFER_BIT);
1070 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1072 while(glGetError());
1073 TRACE("Format doesn't support post-pixelshader blending.\n");
1074 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1077 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1078 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1080 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1081 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1082 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1083 checkGLcall("RB cleanup");
1087 if (format->glInternal != format->glGammaInternal)
1089 glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1090 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1092 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1093 checkGLcall("Framebuffer format check");
1095 if (status == GL_FRAMEBUFFER_COMPLETE)
1097 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1098 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1102 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1106 glDeleteTextures(1, &tex);
1111 /* Context activation is done by the caller. */
1112 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1117 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1121 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1122 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1127 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1129 struct wined3d_format *format = &gl_info->formats[i];
1131 if (!format->glInternal) continue;
1133 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1135 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1136 debug_d3dformat(format->id));
1140 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1142 TRACE("Skipping format %s because it's a compressed format.\n",
1143 debug_d3dformat(format->id));
1147 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1149 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1150 check_fbo_compat(gl_info, format);
1154 format->rtInternal = format->glInternal;
1158 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1162 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1168 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1172 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1174 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1175 struct wined3d_format *format;
1179 ERR("Format %s (%#x) not found.\n",
1180 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1184 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1186 format = &gl_info->formats[fmt_idx];
1188 /* ARB_texture_rg defines floating point formats, but only if
1189 * ARB_texture_float is also supported. */
1190 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1191 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1194 format->glInternal = format_texture_info[i].gl_internal;
1195 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1196 format->rtInternal = format_texture_info[i].gl_rt_internal;
1197 format->glFormat = format_texture_info[i].gl_format;
1198 format->glType = format_texture_info[i].gl_type;
1199 format->color_fixup = COLOR_FIXUP_IDENTITY;
1200 format->flags |= format_texture_info[i].flags;
1201 format->heightscale = 1.0f;
1203 if (format->glGammaInternal != format->glInternal)
1205 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1206 if (!gl_info->supported[EXT_TEXTURE_SRGB])
1208 format->glGammaInternal = format->glInternal;
1209 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1211 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1213 format->glInternal = format->glGammaInternal;
1217 /* Texture conversion stuff */
1218 format->convert = format_texture_info[i].convert;
1219 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1225 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1227 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1229 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1231 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1233 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1237 /* A context is provided by the caller */
1238 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1240 static const DWORD data[] = {0x00000000, 0xffffffff};
1241 GLuint tex, fbo, buffer;
1242 DWORD readback[16 * 1];
1245 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1246 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1247 * falling back to software. If this changes in the future this code will get fooled and
1248 * apps might hit the software path due to incorrectly advertised caps.
1250 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1251 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1252 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1256 while(glGetError());
1258 glGenTextures(1, &buffer);
1259 glBindTexture(GL_TEXTURE_2D, buffer);
1260 memset(readback, 0x7e, sizeof(readback));
1261 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1264 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1265 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1266 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1268 glGenTextures(1, &tex);
1269 glBindTexture(GL_TEXTURE_2D, tex);
1270 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1271 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1272 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1273 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1274 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1275 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1276 glEnable(GL_TEXTURE_2D);
1278 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1279 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1280 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1281 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1283 glViewport(0, 0, 16, 1);
1284 glDisable(GL_LIGHTING);
1285 glMatrixMode(GL_MODELVIEW);
1287 glMatrixMode(GL_PROJECTION);
1290 glClearColor(0, 1, 0, 0);
1291 glClear(GL_COLOR_BUFFER_BIT);
1293 glBegin(GL_TRIANGLE_STRIP);
1294 glTexCoord2f(0.0, 0.0);
1295 glVertex2f(-1.0f, -1.0f);
1296 glTexCoord2f(1.0, 0.0);
1297 glVertex2f(1.0f, -1.0f);
1298 glTexCoord2f(0.0, 1.0);
1299 glVertex2f(-1.0f, 1.0f);
1300 glTexCoord2f(1.0, 1.0);
1301 glVertex2f(1.0f, 1.0f);
1304 glBindTexture(GL_TEXTURE_2D, buffer);
1305 memset(readback, 0x7f, sizeof(readback));
1306 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1307 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1308 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1310 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1311 readback[6], readback[9]);
1316 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1317 readback[6], readback[9]);
1321 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1322 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1323 glDeleteTextures(1, &tex);
1324 glDeleteTextures(1, &buffer);
1328 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1335 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1337 struct wined3d_format *format;
1338 unsigned int fmt_idx, i;
1339 static const enum wined3d_format_id fmts16[] =
1341 WINED3DFMT_R16_FLOAT,
1342 WINED3DFMT_R16G16_FLOAT,
1343 WINED3DFMT_R16G16B16A16_FLOAT,
1347 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1349 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1350 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1352 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1355 else if (gl_info->limits.glsl_varyings > 44)
1357 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1362 TRACE("Assuming no float16 blending\n");
1368 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1370 fmt_idx = getFmtIdx(fmts16[i]);
1371 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1377 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1379 fmt_idx = getFmtIdx(fmts16[i]);
1380 format = &gl_info->formats[fmt_idx];
1381 if (!format->glInternal) continue; /* Not supported by GL */
1383 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1386 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1387 format->flags |= WINED3DFMT_FLAG_FILTERING;
1391 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1396 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1400 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1401 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1402 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1404 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1405 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1406 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1408 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1409 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1410 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1412 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1413 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1414 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1416 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1417 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1418 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1420 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1421 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1422 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1423 * the only driver that implements it(fglrx) has a buggy implementation.
1425 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1426 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1427 * conversion for this format.
1429 if (!gl_info->supported[NV_TEXTURE_SHADER])
1431 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1432 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1433 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1434 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1435 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1436 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1440 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1441 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1442 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1444 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1445 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1446 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1449 if (!gl_info->supported[NV_TEXTURE_SHADER])
1451 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1454 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1455 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1456 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1457 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1458 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1459 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1460 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1461 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1462 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1466 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1467 * are converted at surface loading time, but they do not need any modification in
1468 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1469 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1473 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1475 idx = getFmtIdx(WINED3DFMT_ATI2N);
1476 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1477 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1479 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1481 idx = getFmtIdx(WINED3DFMT_ATI2N);
1482 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1483 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1486 if (!gl_info->supported[APPLE_YCBCR_422])
1488 idx = getFmtIdx(WINED3DFMT_YUY2);
1489 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1491 idx = getFmtIdx(WINED3DFMT_UYVY);
1492 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1495 idx = getFmtIdx(WINED3DFMT_YV12);
1496 gl_info->formats[idx].heightscale = 1.5f;
1497 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1499 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1501 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1502 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1505 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1507 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1508 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1511 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1513 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1514 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1515 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1516 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1518 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1519 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1523 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1527 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1529 struct wined3d_format *format;
1530 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1534 ERR("Format %s (%#x) not found.\n",
1535 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1539 format = &gl_info->formats[fmt_idx];
1540 format->emit_idx = format_vertex_info[i].emit_idx;
1541 format->component_count = format_vertex_info[i].component_count;
1542 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1543 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1544 format->gl_normalized = format_vertex_info[i].gl_normalized;
1545 format->component_size = format_vertex_info[i].component_size;
1551 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1553 if (!init_format_base_info(gl_info)) return FALSE;
1555 if (!init_format_compression_info(gl_info))
1557 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1558 gl_info->formats = NULL;
1565 /* Context activation is done by the caller. */
1566 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1568 if (!init_format_base_info(gl_info)) return FALSE;
1570 if (!init_format_compression_info(gl_info)) goto fail;
1571 if (!init_format_texture_info(gl_info)) goto fail;
1572 if (!init_format_vertex_info(gl_info)) goto fail;
1574 apply_format_fixups(gl_info);
1575 init_format_fbo_compat_info(gl_info);
1576 init_format_filter_info(gl_info, vendor);
1581 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1582 gl_info->formats = NULL;
1586 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1587 enum wined3d_format_id format_id)
1589 int idx = getFmtIdx(format_id);
1593 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1594 debug_d3dformat(format_id), format_id);
1595 /* Get the caller a valid pointer */
1596 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1599 return &gl_info->formats[idx];
1602 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1606 if (format->id == WINED3DFMT_UNKNOWN)
1610 else if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1612 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1613 UINT row_count = (height + format->block_height - 1) / format->block_height;
1614 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1618 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1621 if (format->heightscale != 0.0f)
1623 /* The D3D format requirements make sure that the resulting format is an integer again */
1624 size = (UINT) (size * format->heightscale);
1630 /*****************************************************************************
1631 * Trace formatting of useful values
1633 const char *debug_d3dformat(enum wined3d_format_id format_id)
1637 #define FMT_TO_STR(format_id) case format_id: return #format_id
1638 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1639 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1640 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1641 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1642 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1643 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1644 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1645 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1646 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1647 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1648 FMT_TO_STR(WINED3DFMT_P8_UINT);
1649 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1650 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1651 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1652 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1653 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1654 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1655 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1656 FMT_TO_STR(WINED3DFMT_UYVY);
1657 FMT_TO_STR(WINED3DFMT_YUY2);
1658 FMT_TO_STR(WINED3DFMT_YV12);
1659 FMT_TO_STR(WINED3DFMT_DXT1);
1660 FMT_TO_STR(WINED3DFMT_DXT2);
1661 FMT_TO_STR(WINED3DFMT_DXT3);
1662 FMT_TO_STR(WINED3DFMT_DXT4);
1663 FMT_TO_STR(WINED3DFMT_DXT5);
1664 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1665 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1666 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1667 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1668 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1669 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1670 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1671 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1672 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1673 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1674 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1675 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1676 FMT_TO_STR(WINED3DFMT_ATI2N);
1677 FMT_TO_STR(WINED3DFMT_NVDB);
1678 FMT_TO_STR(WINED3DFMT_NVHU);
1679 FMT_TO_STR(WINED3DFMT_NVHS);
1680 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1681 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1682 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1683 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1684 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1685 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1686 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1687 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1688 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1689 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1690 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1691 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1692 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1693 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1694 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1695 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1696 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1697 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1698 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1699 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1700 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1701 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1702 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1703 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1704 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1705 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1706 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1707 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1708 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1709 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1710 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1711 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1712 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1713 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1714 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1715 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1716 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1717 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1718 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1719 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1720 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1721 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1722 FMT_TO_STR(WINED3DFMT_R32_UINT);
1723 FMT_TO_STR(WINED3DFMT_R32_SINT);
1724 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1725 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1726 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1727 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1728 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1729 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1730 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1731 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1732 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1733 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1734 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1735 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1736 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1737 FMT_TO_STR(WINED3DFMT_R16_UINT);
1738 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1739 FMT_TO_STR(WINED3DFMT_R16_SINT);
1740 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1741 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1742 FMT_TO_STR(WINED3DFMT_R8_UINT);
1743 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1744 FMT_TO_STR(WINED3DFMT_R8_SINT);
1745 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1746 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1747 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1748 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1749 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1750 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1751 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1752 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1753 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1754 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1755 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1756 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1757 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1758 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1759 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1760 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1761 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1762 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1763 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1764 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1765 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1766 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1767 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1768 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1769 FMT_TO_STR(WINED3DFMT_INTZ);
1770 FMT_TO_STR(WINED3DFMT_NULL);
1771 FMT_TO_STR(WINED3DFMT_R16);
1772 FMT_TO_STR(WINED3DFMT_AL16);
1777 fourcc[0] = (char)(format_id);
1778 fourcc[1] = (char)(format_id >> 8);
1779 fourcc[2] = (char)(format_id >> 16);
1780 fourcc[3] = (char)(format_id >> 24);
1782 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1783 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1785 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1787 return "unrecognized";
1791 const char *debug_d3ddevicetype(WINED3DDEVTYPE devtype)
1795 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1796 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1797 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1798 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1799 #undef DEVTYPE_TO_STR
1801 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1802 return "unrecognized";
1806 const char *debug_d3dusage(DWORD usage)
1811 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1812 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1813 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1814 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1815 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1816 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1817 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1818 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1819 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1820 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1821 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1822 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1823 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1824 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1825 #undef WINED3DUSAGE_TO_STR
1826 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1828 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1831 const char *debug_d3dusagequery(DWORD usagequery)
1836 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1837 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1838 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1839 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1840 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1841 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1842 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1843 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1844 #undef WINED3DUSAGEQUERY_TO_STR
1845 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1847 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1850 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1852 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1853 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1854 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1855 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1856 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1857 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1858 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1859 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1860 #undef WINED3DDECLMETHOD_TO_STR
1862 FIXME("Unrecognized %u declaration method!\n", method);
1863 return "unrecognized";
1867 const char* debug_d3ddeclusage(BYTE usage) {
1869 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1870 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1871 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1872 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1873 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1874 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1875 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1876 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1877 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1878 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1879 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1880 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1881 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1882 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1883 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1884 #undef WINED3DDECLUSAGE_TO_STR
1886 FIXME("Unrecognized %u declaration usage!\n", usage);
1887 return "unrecognized";
1891 const char *debug_d3dresourcetype(WINED3DRESOURCETYPE res)
1895 #define RES_TO_STR(res) case res: return #res
1896 RES_TO_STR(WINED3DRTYPE_SURFACE);
1897 RES_TO_STR(WINED3DRTYPE_VOLUME);
1898 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1899 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1900 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1901 RES_TO_STR(WINED3DRTYPE_BUFFER);
1904 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1905 return "unrecognized";
1909 const char *debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType)
1911 switch (PrimitiveType)
1913 #define PRIM_TO_STR(prim) case prim: return #prim
1914 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1915 PRIM_TO_STR(WINED3DPT_POINTLIST);
1916 PRIM_TO_STR(WINED3DPT_LINELIST);
1917 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1918 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1919 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1920 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1921 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1922 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1923 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1924 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1927 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1928 return "unrecognized";
1932 const char *debug_d3drenderstate(WINED3DRENDERSTATETYPE state)
1936 #define D3DSTATE_TO_STR(u) case u: return #u
1937 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS);
1938 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE);
1939 D3DSTATE_TO_STR(WINED3DRS_WRAPU);
1940 D3DSTATE_TO_STR(WINED3DRS_WRAPV);
1941 D3DSTATE_TO_STR(WINED3DRS_ZENABLE);
1942 D3DSTATE_TO_STR(WINED3DRS_FILLMODE);
1943 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE);
1944 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN);
1945 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE);
1946 D3DSTATE_TO_STR(WINED3DRS_ROP2);
1947 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK);
1948 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE);
1949 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE);
1950 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL);
1951 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND);
1952 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND);
1953 D3DSTATE_TO_STR(WINED3DRS_CULLMODE);
1954 D3DSTATE_TO_STR(WINED3DRS_ZFUNC);
1955 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF);
1956 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC);
1957 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE);
1958 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE);
1959 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE);
1960 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE);
1961 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE);
1962 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL);
1963 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX);
1964 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA);
1965 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR);
1966 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE);
1967 D3DSTATE_TO_STR(WINED3DRS_FOGSTART);
1968 D3DSTATE_TO_STR(WINED3DRS_FOGEND);
1969 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY);
1970 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE);
1971 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS);
1972 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE);
1973 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS);
1974 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE);
1975 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY);
1976 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH);
1977 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1978 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE);
1979 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL);
1980 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL);
1981 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS);
1982 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC);
1983 D3DSTATE_TO_STR(WINED3DRS_STENCILREF);
1984 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK);
1985 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK);
1986 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR);
1987 D3DSTATE_TO_STR(WINED3DRS_WRAP0);
1988 D3DSTATE_TO_STR(WINED3DRS_WRAP1);
1989 D3DSTATE_TO_STR(WINED3DRS_WRAP2);
1990 D3DSTATE_TO_STR(WINED3DRS_WRAP3);
1991 D3DSTATE_TO_STR(WINED3DRS_WRAP4);
1992 D3DSTATE_TO_STR(WINED3DRS_WRAP5);
1993 D3DSTATE_TO_STR(WINED3DRS_WRAP6);
1994 D3DSTATE_TO_STR(WINED3DRS_WRAP7);
1995 D3DSTATE_TO_STR(WINED3DRS_CLIPPING);
1996 D3DSTATE_TO_STR(WINED3DRS_LIGHTING);
1997 D3DSTATE_TO_STR(WINED3DRS_EXTENTS);
1998 D3DSTATE_TO_STR(WINED3DRS_AMBIENT);
1999 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE);
2000 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX);
2001 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER);
2002 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS);
2003 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE);
2004 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE);
2005 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE);
2006 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE);
2007 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE);
2008 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND);
2009 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE);
2010 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING);
2011 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE);
2012 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN);
2013 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE);
2014 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE);
2015 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A);
2016 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B);
2017 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C);
2018 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS);
2019 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK);
2020 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE);
2021 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS);
2022 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN);
2023 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX);
2024 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE);
2025 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE);
2026 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR);
2027 D3DSTATE_TO_STR(WINED3DRS_BLENDOP);
2028 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE);
2029 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE);
2030 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE);
2031 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS);
2032 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE);
2033 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL);
2034 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL);
2035 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X);
2036 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y);
2037 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z);
2038 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W);
2039 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
2040 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE);
2041 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL);
2042 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL);
2043 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS);
2044 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC);
2045 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1);
2046 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2);
2047 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3);
2048 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR);
2049 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE);
2050 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS);
2051 D3DSTATE_TO_STR(WINED3DRS_WRAP8);
2052 D3DSTATE_TO_STR(WINED3DRS_WRAP9);
2053 D3DSTATE_TO_STR(WINED3DRS_WRAP10);
2054 D3DSTATE_TO_STR(WINED3DRS_WRAP11);
2055 D3DSTATE_TO_STR(WINED3DRS_WRAP12);
2056 D3DSTATE_TO_STR(WINED3DRS_WRAP13);
2057 D3DSTATE_TO_STR(WINED3DRS_WRAP14);
2058 D3DSTATE_TO_STR(WINED3DRS_WRAP15);
2059 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE);
2060 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA);
2061 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA);
2062 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA);
2063 #undef D3DSTATE_TO_STR
2065 FIXME("Unrecognized %u render state!\n", state);
2066 return "unrecognized";
2070 const char *debug_d3dsamplerstate(DWORD state)
2074 #define D3DSTATE_TO_STR(u) case u: return #u
2075 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR);
2076 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU);
2077 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV);
2078 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW);
2079 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER);
2080 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER);
2081 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER);
2082 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
2083 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL);
2084 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
2085 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE);
2086 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX);
2087 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET);
2088 #undef D3DSTATE_TO_STR
2090 FIXME("Unrecognized %u sampler state!\n", state);
2091 return "unrecognized";
2095 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2096 switch (filter_type) {
2097 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2098 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2099 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2100 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2101 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2102 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2103 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2104 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2105 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2106 #undef D3DTEXTUREFILTERTYPE_TO_STR
2108 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2109 return "unrecognized";
2113 const char *debug_d3dtexturestate(DWORD state)
2117 #define D3DSTATE_TO_STR(u) case u: return #u
2118 D3DSTATE_TO_STR(WINED3DTSS_COLOROP);
2119 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1);
2120 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2);
2121 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP);
2122 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1);
2123 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2);
2124 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00);
2125 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01);
2126 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10);
2127 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11);
2128 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX);
2129 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE);
2130 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET);
2131 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS);
2132 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0);
2133 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0);
2134 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG);
2135 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT);
2136 #undef D3DSTATE_TO_STR
2138 FIXME("Unrecognized %u texture state!\n", state);
2139 return "unrecognized";
2143 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2145 #define D3DTOP_TO_STR(u) case u: return #u
2146 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2147 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2148 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2149 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2150 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2151 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2152 D3DTOP_TO_STR(WINED3DTOP_ADD);
2153 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2154 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2155 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2156 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2157 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2158 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2159 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2160 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2161 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2162 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2163 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2164 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2165 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2166 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2167 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2168 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2169 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2170 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2171 D3DTOP_TO_STR(WINED3DTOP_LERP);
2172 #undef D3DTOP_TO_STR
2174 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2175 return "unrecognized";
2179 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2181 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2182 TSTYPE_TO_STR(WINED3DTS_VIEW);
2183 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2184 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2185 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2186 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2187 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2188 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2189 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2190 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2191 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2192 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2193 #undef TSTYPE_TO_STR
2195 if (tstype > 256 && tstype < 512) {
2196 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2197 return ("WINED3DTS_WORLDMATRIX > 0");
2199 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2200 return "unrecognized";
2204 const char *debug_d3dstate(DWORD state)
2206 if (STATE_IS_RENDER(state))
2207 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2208 if (STATE_IS_TEXTURESTAGE(state))
2210 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2211 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2212 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2213 texture_stage, debug_d3dtexturestate(texture_state));
2215 if (STATE_IS_SAMPLER(state))
2216 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2217 if (STATE_IS_PIXELSHADER(state))
2218 return "STATE_PIXELSHADER";
2219 if (STATE_IS_TRANSFORM(state))
2220 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2221 if (STATE_IS_STREAMSRC(state))
2222 return "STATE_STREAMSRC";
2223 if (STATE_IS_INDEXBUFFER(state))
2224 return "STATE_INDEXBUFFER";
2225 if (STATE_IS_VDECL(state))
2226 return "STATE_VDECL";
2227 if (STATE_IS_VSHADER(state))
2228 return "STATE_VSHADER";
2229 if (STATE_IS_VIEWPORT(state))
2230 return "STATE_VIEWPORT";
2231 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2232 return "STATE_VERTEXSHADERCONSTANT";
2233 if (STATE_IS_PIXELSHADERCONSTANT(state))
2234 return "STATE_PIXELSHADERCONSTANT";
2235 if (STATE_IS_ACTIVELIGHT(state))
2236 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2237 if (STATE_IS_SCISSORRECT(state))
2238 return "STATE_SCISSORRECT";
2239 if (STATE_IS_CLIPPLANE(state))
2240 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2241 if (STATE_IS_MATERIAL(state))
2242 return "STATE_MATERIAL";
2243 if (STATE_IS_FRONTFACE(state))
2244 return "STATE_FRONTFACE";
2245 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2246 return "STATE_POINTSPRITECOORDORIGIN";
2247 if (STATE_IS_BASEVERTEXINDEX(state))
2248 return "STATE_BASEVERTEXINDEX";
2250 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2253 const char *debug_d3dpool(WINED3DPOOL pool)
2257 #define POOL_TO_STR(p) case p: return #p
2258 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2259 POOL_TO_STR(WINED3DPOOL_MANAGED);
2260 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2261 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2264 FIXME("Unrecognized %u WINED3DPOOL!\n", pool);
2265 return "unrecognized";
2269 const char *debug_fbostatus(GLenum status) {
2271 #define FBOSTATUS_TO_STR(u) case u: return #u
2272 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2273 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2274 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2275 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2276 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2277 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2278 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2279 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2280 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2281 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2282 #undef FBOSTATUS_TO_STR
2284 FIXME("Unrecognied FBO status 0x%08x\n", status);
2285 return "unrecognized";
2289 const char *debug_glerror(GLenum error) {
2291 #define GLERROR_TO_STR(u) case u: return #u
2292 GLERROR_TO_STR(GL_NO_ERROR);
2293 GLERROR_TO_STR(GL_INVALID_ENUM);
2294 GLERROR_TO_STR(GL_INVALID_VALUE);
2295 GLERROR_TO_STR(GL_INVALID_OPERATION);
2296 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2297 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2298 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2299 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2300 #undef GLERROR_TO_STR
2302 FIXME("Unrecognied GL error 0x%08x\n", error);
2303 return "unrecognized";
2307 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2309 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2310 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2311 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2312 default: return "unrecognized";
2316 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2318 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2319 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2320 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2321 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2322 default: return "unrecognized";
2326 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2330 #define WINED3D_TO_STR(x) case x: return #x
2331 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2332 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2333 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2334 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2335 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2336 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2337 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2338 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2339 #undef WINED3D_TO_STR
2341 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2342 return "unrecognized";
2346 static const char *debug_complex_fixup(enum complex_fixup fixup)
2350 #define WINED3D_TO_STR(x) case x: return #x
2351 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2352 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2353 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2354 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2355 #undef WINED3D_TO_STR
2357 FIXME("Unrecognized complex fixup %#x\n", fixup);
2358 return "unrecognized";
2362 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2364 if (is_complex_fixup(fixup))
2366 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2370 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2371 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2372 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2373 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2376 const char *debug_surflocation(DWORD flag) {
2380 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2381 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2382 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2383 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2384 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2387 /*****************************************************************************
2388 * Useful functions mapping GL <-> D3D values
2390 GLenum StencilOp(DWORD op) {
2392 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2393 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2394 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2395 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2396 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2397 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2398 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2399 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2401 FIXME("Unrecognized stencil op %d\n", op);
2406 GLenum CompareFunc(DWORD func) {
2407 switch ((WINED3DCMPFUNC)func) {
2408 case WINED3DCMP_NEVER : return GL_NEVER;
2409 case WINED3DCMP_LESS : return GL_LESS;
2410 case WINED3DCMP_EQUAL : return GL_EQUAL;
2411 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2412 case WINED3DCMP_GREATER : return GL_GREATER;
2413 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2414 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2415 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2417 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2422 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2423 WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
2425 if (op == WINED3DTOP_DISABLE) return FALSE;
2426 if (state->textures[stage]) return FALSE;
2428 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2429 && op != WINED3DTOP_SELECTARG2) return TRUE;
2430 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2431 && op != WINED3DTOP_SELECTARG1) return TRUE;
2432 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2433 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2438 /* Setup this textures matrix according to the texture flags*/
2439 /* GL locking is done by the caller (state handler) */
2440 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2441 enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2445 glMatrixMode(GL_TEXTURE);
2446 checkGLcall("glMatrixMode(GL_TEXTURE)");
2448 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2450 checkGLcall("glLoadIdentity()");
2454 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2455 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2459 memcpy(mat, smat, 16 * sizeof(float));
2461 if (flags & WINED3DTTFF_PROJECTED) {
2462 if(!ffp_proj_control) {
2463 switch (flags & ~WINED3DTTFF_PROJECTED) {
2464 case WINED3DTTFF_COUNT2:
2465 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2466 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2468 case WINED3DTTFF_COUNT3:
2469 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2470 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2474 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2475 if(!calculatedCoords) {
2478 case WINED3DFMT_R32_FLOAT:
2479 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2480 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2481 * the input value to the transformation will be 0, so the matrix value is irrelevant
2488 case WINED3DFMT_R32G32_FLOAT:
2489 /* See above, just 3rd and 4th coord
2496 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2497 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2499 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2500 * into a bad place. The division elimination below will apply to make sure the
2501 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2503 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2506 FIXME("Unexpected fixed function texture coord input\n");
2509 if(!ffp_proj_control) {
2510 switch (flags & ~WINED3DTTFF_PROJECTED) {
2511 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2512 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2513 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2514 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2515 * the 4th coord evaluates to 1.0 to eliminate that.
2517 * If the fixed function pipeline is used, the 4th value remains unused,
2518 * so there is no danger in doing this. With vertex shaders we have a
2519 * problem. Should an app hit that problem, the code here would have to
2520 * check for pixel shaders, and the shader has to undo the default gl divide.
2522 * A more serious problem occurs if the app passes 4 coordinates in, and the
2523 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2524 * or a replacement shader
2526 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2532 checkGLcall("glLoadMatrixf(mat)");
2535 /* This small helper function is used to convert a bitmask into the number of masked bits */
2536 unsigned int count_bits(unsigned int mask)
2539 for (count = 0; mask; ++count)
2546 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2547 * The later function requires individual color components. */
2548 BOOL getColorBits(const struct wined3d_format *format,
2549 BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2551 TRACE("format %s.\n", debug_d3dformat(format->id));
2555 case WINED3DFMT_B10G10R10A2_UNORM:
2556 case WINED3DFMT_R10G10B10A2_UNORM:
2557 case WINED3DFMT_B8G8R8X8_UNORM:
2558 case WINED3DFMT_B8G8R8_UNORM:
2559 case WINED3DFMT_B8G8R8A8_UNORM:
2560 case WINED3DFMT_R8G8B8A8_UNORM:
2561 case WINED3DFMT_B5G5R5X1_UNORM:
2562 case WINED3DFMT_B5G5R5A1_UNORM:
2563 case WINED3DFMT_B5G6R5_UNORM:
2564 case WINED3DFMT_B4G4R4X4_UNORM:
2565 case WINED3DFMT_B4G4R4A4_UNORM:
2566 case WINED3DFMT_B2G3R3_UNORM:
2567 case WINED3DFMT_P8_UINT_A8_UNORM:
2568 case WINED3DFMT_P8_UINT:
2571 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2575 *redSize = count_bits(format->red_mask);
2576 *greenSize = count_bits(format->green_mask);
2577 *blueSize = count_bits(format->blue_mask);
2578 *alphaSize = count_bits(format->alpha_mask);
2579 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2581 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2582 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2586 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2587 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
2589 TRACE("format %s.\n", debug_d3dformat(format->id));
2593 case WINED3DFMT_D16_LOCKABLE:
2594 case WINED3DFMT_D16_UNORM:
2595 case WINED3DFMT_S1_UINT_D15_UNORM:
2596 case WINED3DFMT_X8D24_UNORM:
2597 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2598 case WINED3DFMT_D24_UNORM_S8_UINT:
2599 case WINED3DFMT_S8_UINT_D24_FLOAT:
2600 case WINED3DFMT_D32_UNORM:
2601 case WINED3DFMT_D32_FLOAT:
2602 case WINED3DFMT_INTZ:
2605 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2609 *depthSize = format->depth_size;
2610 *stencilSize = format->stencil_size;
2612 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2613 *depthSize, *stencilSize, debug_d3dformat(format->id));
2617 /* Note: It's the caller's responsibility to ensure values can be expressed
2618 * in the requested format. UNORM formats for example can only express values
2619 * in the range 0.0f -> 1.0f. */
2620 DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, const WINED3DCOLORVALUE *color)
2624 enum wined3d_format_id format_id;
2636 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2637 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2638 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2639 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2640 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2641 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2642 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2643 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2644 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2645 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2646 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2647 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2648 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2649 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2653 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2654 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2656 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2660 if (format->id != conv[i].format_id) continue;
2662 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2663 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2664 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2665 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2667 TRACE("Returning 0x%08x.\n", ret);
2672 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2677 /* DirectDraw stuff */
2678 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2682 case 8: return WINED3DFMT_P8_UINT;
2683 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2684 case 16: return WINED3DFMT_B5G6R5_UNORM;
2685 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2686 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2687 default: return WINED3DFMT_UNKNOWN;
2691 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2694 /* Now do the multiplication 'by hand'.
2695 I know that all this could be optimised, but this will be done later :-) */
2696 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);
2697 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);
2698 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);
2699 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);
2701 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);
2702 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);
2703 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);
2704 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);
2706 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);
2707 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);
2708 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);
2709 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);
2711 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);
2712 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);
2713 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);
2714 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);
2716 /* And copy the new matrix in the good storage.. */
2717 memcpy(dest, &temp, 16 * sizeof(float));
2720 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2723 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2725 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2726 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2727 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2728 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2729 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2730 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2731 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2732 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2733 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2734 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2735 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2736 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2737 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2738 default: ERR("Unexpected position mask\n");
2740 for (i = 0; i < numTextures; i++) {
2741 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2747 void gen_ffp_frag_op(struct wined3d_stateblock *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype)
2752 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2754 /* D3DTOP_DISABLE */ 0,
2755 /* D3DTOP_SELECTARG1 */ ARG1,
2756 /* D3DTOP_SELECTARG2 */ ARG2,
2757 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2758 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2759 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2760 /* D3DTOP_ADD */ ARG1 | ARG2,
2761 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2762 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2763 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2764 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2765 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2766 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2767 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2768 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2769 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2770 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2771 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2772 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2773 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2774 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2775 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2776 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2777 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2778 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2779 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2783 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2784 struct wined3d_device *device = stateblock->device;
2785 struct wined3d_surface *rt = device->fb.render_targets[0];
2786 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2788 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2790 const struct wined3d_texture *texture;
2792 settings->op[i].padding = 0;
2793 if (stateblock->state.texture_states[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE)
2795 settings->op[i].cop = WINED3DTOP_DISABLE;
2796 settings->op[i].aop = WINED3DTOP_DISABLE;
2797 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2798 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2799 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2800 settings->op[i].dst = resultreg;
2801 settings->op[i].tex_type = tex_1d;
2802 settings->op[i].projected = proj_none;
2807 if ((texture = stateblock->state.textures[i]))
2809 settings->op[i].color_fixup = texture->resource.format->color_fixup;
2812 settings->op[i].tex_type = tex_1d;
2816 switch (texture->target)
2819 settings->op[i].tex_type = tex_1d;
2822 settings->op[i].tex_type = tex_2d;
2825 settings->op[i].tex_type = tex_3d;
2827 case GL_TEXTURE_CUBE_MAP_ARB:
2828 settings->op[i].tex_type = tex_cube;
2830 case GL_TEXTURE_RECTANGLE_ARB:
2831 settings->op[i].tex_type = tex_rect;
2836 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2837 settings->op[i].tex_type = tex_1d;
2840 cop = stateblock->state.texture_states[i][WINED3DTSS_COLOROP];
2841 aop = stateblock->state.texture_states[i][WINED3DTSS_ALPHAOP];
2843 carg1 = (args[cop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2844 carg2 = (args[cop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2845 carg0 = (args[cop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2847 if (is_invalid_op(&stateblock->state, i, cop, carg1, carg2, carg0))
2851 carg1 = WINED3DTA_CURRENT;
2852 cop = WINED3DTOP_SELECTARG1;
2855 if(cop == WINED3DTOP_DOTPRODUCT3) {
2856 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2857 * the color result to the alpha component of the destination
2866 aarg1 = (args[aop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2867 aarg2 = (args[aop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2868 aarg0 = (args[aop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2871 if (!i && stateblock->state.textures[0] && stateblock->state.render_states[WINED3DRS_COLORKEYENABLE])
2873 GLenum texture_dimensions;
2875 texture = stateblock->state.textures[0];
2876 texture_dimensions = texture->target;
2878 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2880 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
2882 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
2884 if (aop == WINED3DTOP_DISABLE)
2886 aarg1 = WINED3DTA_TEXTURE;
2887 aop = WINED3DTOP_SELECTARG1;
2889 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2891 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2893 aarg2 = WINED3DTA_TEXTURE;
2894 aop = WINED3DTOP_MODULATE;
2896 else aarg1 = WINED3DTA_TEXTURE;
2898 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2900 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2902 aarg1 = WINED3DTA_TEXTURE;
2903 aop = WINED3DTOP_MODULATE;
2905 else aarg2 = WINED3DTA_TEXTURE;
2911 if (is_invalid_op(&stateblock->state, i, aop, aarg1, aarg2, aarg0))
2915 aarg1 = WINED3DTA_CURRENT;
2916 aop = WINED3DTOP_SELECTARG1;
2919 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
2920 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
2922 ttff = stateblock->state.texture_states[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2923 if (ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3))
2925 settings->op[i].projected = proj_count3;
2926 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2927 settings->op[i].projected = proj_count4;
2929 settings->op[i].projected = proj_none;
2932 settings->op[i].projected = proj_none;
2935 settings->op[i].cop = cop;
2936 settings->op[i].aop = aop;
2937 settings->op[i].carg0 = carg0;
2938 settings->op[i].carg1 = carg1;
2939 settings->op[i].carg2 = carg2;
2940 settings->op[i].aarg0 = aarg0;
2941 settings->op[i].aarg1 = aarg1;
2942 settings->op[i].aarg2 = aarg2;
2944 if (stateblock->state.texture_states[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP)
2946 settings->op[i].dst = tempreg;
2948 settings->op[i].dst = resultreg;
2952 /* Clear unsupported stages */
2953 for(; i < MAX_TEXTURES; i++) {
2954 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2957 if (!stateblock->state.render_states[WINED3DRS_FOGENABLE])
2959 settings->fog = FOG_OFF;
2961 else if (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
2963 if (use_vs(&stateblock->state) || stateblock->state.vertex_declaration->position_transformed)
2965 settings->fog = FOG_LINEAR;
2969 switch (stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE])
2971 case WINED3DFOG_NONE:
2972 case WINED3DFOG_LINEAR:
2973 settings->fog = FOG_LINEAR;
2975 case WINED3DFOG_EXP:
2976 settings->fog = FOG_EXP;
2978 case WINED3DFOG_EXP2:
2979 settings->fog = FOG_EXP2;
2986 switch (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE])
2988 case WINED3DFOG_LINEAR:
2989 settings->fog = FOG_LINEAR;
2991 case WINED3DFOG_EXP:
2992 settings->fog = FOG_EXP;
2994 case WINED3DFOG_EXP2:
2995 settings->fog = FOG_EXP2;
2999 if (stateblock->state.render_states[WINED3DRS_SRGBWRITEENABLE]
3000 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
3002 settings->sRGB_write = 1;
3004 settings->sRGB_write = 0;
3006 if (device->vs_clipping || !use_vs(&stateblock->state) || !stateblock->state.render_states[WINED3DRS_CLIPPING]
3007 || !stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE])
3009 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3010 * the fixed function vertex pipeline is used(which always supports clipplanes), or
3011 * if no clipplane is enabled
3013 settings->emul_clipplanes = 0;
3015 settings->emul_clipplanes = 1;
3019 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3020 const struct ffp_frag_settings *settings)
3022 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3023 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3026 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3028 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3029 * whereas desc points to an extended structure with implementation specific parts. */
3030 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3032 ERR("Failed to insert ffp frag shader.\n");
3036 /* Activates the texture dimension according to the bound D3D texture.
3037 * Does not care for the colorop or correct gl texture unit(when using nvrc)
3038 * Requires the caller to activate the correct unit before
3040 /* GL locking is done by the caller (state handler) */
3041 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3045 switch (texture->target)
3048 glDisable(GL_TEXTURE_3D);
3049 checkGLcall("glDisable(GL_TEXTURE_3D)");
3050 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3052 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3053 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3055 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3057 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3058 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3060 glEnable(GL_TEXTURE_2D);
3061 checkGLcall("glEnable(GL_TEXTURE_2D)");
3063 case GL_TEXTURE_RECTANGLE_ARB:
3064 glDisable(GL_TEXTURE_2D);
3065 checkGLcall("glDisable(GL_TEXTURE_2D)");
3066 glDisable(GL_TEXTURE_3D);
3067 checkGLcall("glDisable(GL_TEXTURE_3D)");
3068 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3070 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3071 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3073 glEnable(GL_TEXTURE_RECTANGLE_ARB);
3074 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3077 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3079 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3080 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3082 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3084 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3085 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3087 glDisable(GL_TEXTURE_2D);
3088 checkGLcall("glDisable(GL_TEXTURE_2D)");
3089 glEnable(GL_TEXTURE_3D);
3090 checkGLcall("glEnable(GL_TEXTURE_3D)");
3092 case GL_TEXTURE_CUBE_MAP_ARB:
3093 glDisable(GL_TEXTURE_2D);
3094 checkGLcall("glDisable(GL_TEXTURE_2D)");
3095 glDisable(GL_TEXTURE_3D);
3096 checkGLcall("glDisable(GL_TEXTURE_3D)");
3097 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3099 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3100 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3102 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3103 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3107 glEnable(GL_TEXTURE_2D);
3108 checkGLcall("glEnable(GL_TEXTURE_2D)");
3109 glDisable(GL_TEXTURE_3D);
3110 checkGLcall("glDisable(GL_TEXTURE_3D)");
3111 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3113 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3114 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3116 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3118 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3119 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3121 /* Binding textures is done by samplers. A dummy texture will be bound */
3125 /* GL locking is done by the caller (state handler) */
3126 void sampler_texdim(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3128 DWORD sampler = state - STATE_SAMPLER(0);
3129 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3131 /* No need to enable / disable anything here for unused samplers. The tex_colorop
3132 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3133 * will take care of this business
3135 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3136 if (sampler >= stateblock->state.lowest_disabled_stage) return;
3137 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3139 texture_activate_dimensions(stateblock->state.textures[sampler], context->gl_info);
3142 void *wined3d_rb_alloc(size_t size)
3144 return HeapAlloc(GetProcessHeap(), 0, size);
3147 void *wined3d_rb_realloc(void *ptr, size_t size)
3149 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3152 void wined3d_rb_free(void *ptr)
3154 HeapFree(GetProcessHeap(), 0, ptr);
3157 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3159 const struct ffp_frag_settings *ka = key;
3160 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3162 return memcmp(ka, kb, sizeof(*ka));
3165 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3170 ffp_frag_program_key_compare,
3173 UINT wined3d_log2i(UINT32 x)
3175 static const UINT l[] =
3177 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3178 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3179 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3180 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3181 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3182 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3183 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3184 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3185 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3186 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3187 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3188 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3189 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3190 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3191 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3192 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3196 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3199 /* Set the shader type for this device, depending on the given capabilities
3200 * and the user preferences in wined3d_settings. */
3201 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3203 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3205 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3206 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3208 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3209 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3210 * shaders only on this card. */
3211 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3212 else *vs_selected = SHADER_GLSL;
3214 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3215 else *vs_selected = SHADER_NONE;
3217 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3218 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3219 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3220 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3221 else *ps_selected = SHADER_NONE;
3224 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3225 const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format *src_format,
3226 const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format *dst_format)
3228 static const struct blit_shader * const blitters[] =
3236 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3238 if (blitters[i]->blit_supported(gl_info, blit_op,
3239 src_rect, src_usage, src_pool, src_format,
3240 dst_rect, dst_usage, dst_pool, dst_format))