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 "wine/port.h"
30 #include "wined3d_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
34 struct wined3d_format_channels
36 enum wined3d_format_id id;
37 DWORD red_size, green_size, blue_size, alpha_size;
38 DWORD red_offset, green_offset, blue_offset, alpha_offset;
40 BYTE depth_size, stencil_size;
43 static const struct wined3d_format_channels formats[] =
46 * format id r g b a r g b a bpp depth stencil */
47 {WINED3DFMT_UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
49 {WINED3DFMT_UYVY, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
50 {WINED3DFMT_YUY2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
51 {WINED3DFMT_YV12, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
52 {WINED3DFMT_DXT1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
53 {WINED3DFMT_DXT2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
54 {WINED3DFMT_DXT3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
55 {WINED3DFMT_DXT4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
56 {WINED3DFMT_DXT5, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
57 {WINED3DFMT_MULTI2_ARGB8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
58 {WINED3DFMT_G8R8_G8B8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
59 {WINED3DFMT_R8G8_B8G8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
61 {WINED3DFMT_R32_FLOAT, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
62 {WINED3DFMT_R32G32_FLOAT, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0},
63 {WINED3DFMT_R32G32B32_FLOAT, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0},
64 {WINED3DFMT_R32G32B32A32_FLOAT, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0},
66 {WINED3DFMT_R8G8_SNORM_Cx, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
68 {WINED3DFMT_R16_FLOAT, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
69 {WINED3DFMT_R16G16_FLOAT, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
70 {WINED3DFMT_R16G16_SINT, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
71 {WINED3DFMT_R16G16B16A16_FLOAT, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
72 {WINED3DFMT_R16G16B16A16_SINT, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
73 /* Palettized formats */
74 {WINED3DFMT_P8_UINT_A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 8, 2, 0, 0},
75 {WINED3DFMT_P8_UINT, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
76 /* Standard ARGB formats. */
77 {WINED3DFMT_B8G8R8_UNORM, 8, 8, 8, 0, 16, 8, 0, 0, 3, 0, 0},
78 {WINED3DFMT_B8G8R8A8_UNORM, 8, 8, 8, 8, 16, 8, 0, 24, 4, 0, 0},
79 {WINED3DFMT_B8G8R8X8_UNORM, 8, 8, 8, 0, 16, 8, 0, 0, 4, 0, 0},
80 {WINED3DFMT_B5G6R5_UNORM, 5, 6, 5, 0, 11, 5, 0, 0, 2, 0, 0},
81 {WINED3DFMT_B5G5R5X1_UNORM, 5, 5, 5, 0, 10, 5, 0, 0, 2, 0, 0},
82 {WINED3DFMT_B5G5R5A1_UNORM, 5, 5, 5, 1, 10, 5, 0, 15, 2, 0, 0},
83 {WINED3DFMT_B4G4R4A4_UNORM, 4, 4, 4, 4, 8, 4, 0, 12, 2, 0, 0},
84 {WINED3DFMT_B2G3R3_UNORM, 3, 3, 2, 0, 5, 2, 0, 0, 1, 0, 0},
85 {WINED3DFMT_A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 0, 1, 0, 0},
86 {WINED3DFMT_B2G3R3A8_UNORM, 3, 3, 2, 8, 5, 2, 0, 8, 2, 0, 0},
87 {WINED3DFMT_B4G4R4X4_UNORM, 4, 4, 4, 0, 8, 4, 0, 0, 2, 0, 0},
88 {WINED3DFMT_R10G10B10A2_UNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
89 {WINED3DFMT_R10G10B10A2_UINT, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
90 {WINED3DFMT_R10G10B10A2_SNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
91 {WINED3DFMT_R8G8B8A8_UNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
92 {WINED3DFMT_R8G8B8A8_UINT, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
93 {WINED3DFMT_R8G8B8X8_UNORM, 8, 8, 8, 0, 0, 8, 16, 0, 4, 0, 0},
94 {WINED3DFMT_R16G16_UNORM, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
95 {WINED3DFMT_B10G10R10A2_UNORM, 10, 10, 10, 2, 20, 10, 0, 30, 4, 0, 0},
96 {WINED3DFMT_R16G16B16A16_UNORM, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
98 {WINED3DFMT_L8_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
99 {WINED3DFMT_L8A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 8, 2, 0, 0},
100 {WINED3DFMT_L4A4_UNORM, 0, 0, 0, 4, 0, 0, 0, 4, 1, 0, 0},
101 {WINED3DFMT_L16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
102 /* Bump mapping stuff */
103 {WINED3DFMT_R8G8_SNORM, 8, 8, 0, 0, 0, 8, 0, 0, 2, 0, 0},
104 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 5, 5, 0, 0, 0, 5, 0, 0, 2, 0, 0},
105 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 8, 8, 0, 0, 0, 8, 0, 0, 4, 0, 0},
106 {WINED3DFMT_R8G8B8A8_SNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
107 {WINED3DFMT_R16G16_SNORM, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
108 {WINED3DFMT_R10G11B11_SNORM, 10, 11, 11, 0, 0, 10, 21, 0, 4, 0, 0},
109 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
110 /* Depth stencil formats */
111 {WINED3DFMT_D16_LOCKABLE, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0},
112 {WINED3DFMT_D32_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0},
113 {WINED3DFMT_S1_UINT_D15_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 15, 1},
114 {WINED3DFMT_D24_UNORM_S8_UINT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
115 {WINED3DFMT_X8D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 0},
116 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 4},
117 {WINED3DFMT_D16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0},
118 {WINED3DFMT_D32_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0},
119 {WINED3DFMT_S8_UINT_D24_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
120 {WINED3DFMT_VERTEXDATA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
121 {WINED3DFMT_R16_UINT, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
122 {WINED3DFMT_R32_UINT, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
123 {WINED3DFMT_R16G16B16A16_SNORM, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
124 /* Vendor-specific formats */
125 {WINED3DFMT_ATI2N, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
126 {WINED3DFMT_NVDB, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
127 {WINED3DFMT_INTZ, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
128 {WINED3DFMT_NVHU, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
129 {WINED3DFMT_NVHS, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
130 {WINED3DFMT_NULL, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
131 /* Unsure about them, could not find a Windows driver that supports them */
132 {WINED3DFMT_R16, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
133 {WINED3DFMT_AL16, 0, 0, 0, 16, 0, 0, 0, 16, 4, 0, 0},
136 struct wined3d_format_base_flags
138 enum wined3d_format_id id;
142 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
143 * still needs to use the correct block based calculation for e.g. the
145 static const struct wined3d_format_base_flags format_base_flags[] =
147 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
148 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
149 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
150 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
151 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
152 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
153 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
156 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
157 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
158 {WINED3DFMT_INTZ, WINED3DFMT_FLAG_FOURCC},
159 {WINED3DFMT_NULL, WINED3DFMT_FLAG_FOURCC},
160 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
161 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
162 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
163 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
164 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
165 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
166 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
171 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
172 {WINED3DFMT_NVDB, WINED3DFMT_FLAG_FOURCC},
173 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
174 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
175 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
176 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
177 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
178 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
179 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
181 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
182 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
186 struct wined3d_format_block_info
188 enum wined3d_format_id id;
191 UINT block_byte_count;
194 static const struct wined3d_format_block_info format_block_info[] =
196 {WINED3DFMT_DXT1, 4, 4, 8},
197 {WINED3DFMT_DXT2, 4, 4, 16},
198 {WINED3DFMT_DXT3, 4, 4, 16},
199 {WINED3DFMT_DXT4, 4, 4, 16},
200 {WINED3DFMT_DXT5, 4, 4, 16},
201 {WINED3DFMT_ATI2N, 4, 4, 16},
202 {WINED3DFMT_YUY2, 2, 1, 4},
203 {WINED3DFMT_UYVY, 2, 1, 4},
206 struct wined3d_format_vertex_info
208 enum wined3d_format_id id;
209 enum wined3d_ffp_emit_idx emit_idx;
210 GLint component_count;
213 GLboolean gl_normalized;
214 unsigned int component_size;
217 static const struct wined3d_format_vertex_info format_vertex_info[] =
219 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
220 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
221 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
222 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
223 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
224 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
225 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
226 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
227 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
228 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
229 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
230 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
231 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
232 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
233 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
234 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
235 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
238 struct wined3d_format_texture_info
240 enum wined3d_format_id id;
242 GLint gl_srgb_internal;
243 GLint gl_rt_internal;
246 unsigned int conv_byte_count;
248 enum wined3d_gl_extension extension;
249 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
252 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
254 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
255 * format+type combination to load it. Thus convert it to A8L8, then load it
256 * with A4L4 internal, but A8L8 format+type
259 const unsigned char *Source;
261 UINT outpitch = pitch * 2;
263 for(y = 0; y < height; y++) {
264 Source = src + y * pitch;
265 Dest = dst + y * outpitch;
266 for (x = 0; x < width; x++ ) {
267 unsigned char color = (*Source++);
268 /* A */ Dest[1] = (color & 0xf0) << 0;
269 /* L */ Dest[0] = (color & 0x0f) << 4;
275 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
280 for(y = 0; y < height; y++)
282 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
283 Source = (const WORD *)(src + y * pitch);
284 for (x = 0; x < width; x++ )
286 short color = (*Source++);
287 unsigned char l = ((color >> 10) & 0xfc);
288 short v = ((color >> 5) & 0x3e);
289 short u = ((color ) & 0x1f);
290 short v_conv = v + 16;
291 short u_conv = u + 16;
293 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
299 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
304 UINT outpitch = (pitch * 3)/2;
306 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
307 * fixed function and shaders without further conversion once the surface is
310 for(y = 0; y < height; y++) {
311 Source = (const WORD *)(src + y * pitch);
312 Dest = dst + y * outpitch;
313 for (x = 0; x < width; x++ ) {
314 short color = (*Source++);
315 unsigned char l = ((color >> 10) & 0xfc);
316 char v = ((color >> 5) & 0x3e);
317 char u = ((color ) & 0x1f);
319 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
320 * and doubles the positive range. Thus shift left only once, gl does the 2nd
321 * shift. GL reads a signed value and converts it into an unsigned value.
323 /* M */ Dest[2] = l << 1;
325 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
326 * from 5 bit values to 8 bit values.
328 /* V */ Dest[1] = v << 3;
329 /* U */ Dest[0] = u << 3;
335 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
340 UINT outpitch = (pitch * 3)/2;
342 for(y = 0; y < height; y++)
344 Source = (const short *)(src + y * pitch);
345 Dest = dst + y * outpitch;
346 for (x = 0; x < width; x++ )
348 const short color = (*Source++);
349 /* B */ Dest[0] = 0xff;
350 /* G */ Dest[1] = (color >> 8) + 128; /* V */
351 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
357 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
363 /* Doesn't work correctly with the fixed function pipeline, but can work in
364 * shaders if the shader is adjusted. (There's no use for this format in gl's
365 * standard fixed function pipeline anyway).
367 for(y = 0; y < height; y++)
369 Source = (const DWORD *)(src + y * pitch);
370 Dest = dst + y * pitch;
371 for (x = 0; x < width; x++ )
373 LONG color = (*Source++);
374 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
375 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
376 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
382 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
388 /* This implementation works with the fixed function pipeline and shaders
389 * without further modification after converting the surface.
391 for(y = 0; y < height; y++)
393 Source = (const DWORD *)(src + y * pitch);
394 Dest = dst + y * pitch;
395 for (x = 0; x < width; x++ )
397 LONG color = (*Source++);
398 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
399 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
400 /* U */ Dest[0] = (color & 0xff); /* U */
401 /* I */ Dest[3] = 255; /* X */
407 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
413 for(y = 0; y < height; y++)
415 Source = (const DWORD *)(src + y * pitch);
416 Dest = dst + y * pitch;
417 for (x = 0; x < width; x++ )
419 LONG color = (*Source++);
420 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
421 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
422 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
423 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
429 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
433 unsigned short *Dest;
434 UINT outpitch = (pitch * 3)/2;
436 for(y = 0; y < height; y++)
438 Source = (const DWORD *)(src + y * pitch);
439 Dest = (unsigned short *) (dst + y * outpitch);
440 for (x = 0; x < width; x++ )
442 const DWORD color = (*Source++);
443 /* B */ Dest[0] = 0xffff;
444 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
445 /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */
451 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
456 UINT outpitch = (pitch * 3)/2;
458 for(y = 0; y < height; y++)
460 Source = (const WORD *)(src + y * pitch);
461 Dest = (WORD *) (dst + y * outpitch);
462 for (x = 0; x < width; x++ )
464 WORD green = (*Source++);
465 WORD red = (*Source++);
468 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
469 * shader overwrites it anyway
477 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
482 UINT outpitch = (pitch * 3)/2;
484 for(y = 0; y < height; y++)
486 Source = (const float *)(src + y * pitch);
487 Dest = (float *) (dst + y * outpitch);
488 for (x = 0; x < width; x++ )
490 float green = (*Source++);
491 float red = (*Source++);
500 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
503 UINT outpitch = pitch * 2;
505 for (y = 0; y < height; ++y)
507 const WORD *source = (const WORD *)(src + y * pitch);
508 DWORD *dest = (DWORD *)(dst + y * outpitch);
510 for (x = 0; x < width; ++x)
512 /* The depth data is normalized, so needs to be scaled,
513 * the stencil data isn't. Scale depth data by
514 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
515 WORD d15 = source[x] >> 1;
516 DWORD d24 = (d15 << 9) + (d15 >> 6);
517 dest[x] = (d24 << 8) | (source[x] & 0x1);
522 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
526 for (y = 0; y < height; ++y)
528 const DWORD *source = (const DWORD *)(src + y * pitch);
529 DWORD *dest = (DWORD *)(dst + y * pitch);
531 for (x = 0; x < width; ++x)
533 /* Just need to clear out the X4 part. */
534 dest[x] = source[x] & ~0xf0;
539 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
542 UINT outpitch = pitch * 2;
544 for (y = 0; y < height; ++y)
546 const DWORD *source = (const DWORD *)(src + y * pitch);
547 float *dest_f = (float *)(dst + y * outpitch);
548 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
550 for (x = 0; x < width; ++x)
552 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
553 dest_s[x * 2 + 1] = source[x] & 0xff;
558 /* The following formats explicitly don't have WINED3DFMT_FLAG_TEXTURE set:
560 * These are never supported on native.
561 * WINED3DFMT_B8G8R8_UNORM
562 * WINED3DFMT_B2G3R3_UNORM
563 * WINED3DFMT_L4A4_UNORM
564 * WINED3DFMT_S1_UINT_D15_UNORM
565 * WINED3DFMT_S4X4_UINT_D24_UNORM
567 * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of ddraw.
568 * Since it is not widely available, don't offer it. Further no Windows driver
569 * offers WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either.
571 * WINED3DFMT_P8_UINT_A8_UNORM
573 * These formats seem to be similar to the HILO formats in
574 * GL_NV_texture_shader. NVHU is said to be GL_UNSIGNED_HILO16,
575 * NVHS GL_SIGNED_HILO16. Rumours say that D3D computes a 3rd channel
576 * similarly to D3DFMT_CxV8U8 (So NVHS could be called D3DFMT_CxV16U16). ATI
577 * refused to support formats which can easily be emulated with pixel shaders,
578 * so applications have to deal with not having NVHS and NVHU.
581 static const struct wined3d_format_texture_info format_texture_info[] =
583 /* format id internal srgbInternal rtInternal
588 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
589 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
590 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
591 * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
594 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
595 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
596 WINED3DFMT_FLAG_FILTERING,
597 WINED3D_GL_EXT_NONE, NULL},
598 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
599 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 0,
600 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
601 APPLE_YCBCR_422, NULL},
602 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
603 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
604 WINED3DFMT_FLAG_FILTERING,
605 WINED3D_GL_EXT_NONE, NULL},
606 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
607 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, 0,
608 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
609 APPLE_YCBCR_422, NULL},
610 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
611 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
612 WINED3DFMT_FLAG_FILTERING,
613 WINED3D_GL_EXT_NONE, NULL},
614 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
615 GL_RGBA, GL_UNSIGNED_BYTE, 0,
616 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
617 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
618 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
619 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
620 GL_RGBA, GL_UNSIGNED_BYTE, 0,
621 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
622 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
623 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
624 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
625 GL_RGBA, GL_UNSIGNED_BYTE, 0,
626 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
627 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
628 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
629 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
630 GL_RGBA, GL_UNSIGNED_BYTE, 0,
631 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
632 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
633 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
634 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
635 GL_RGBA, GL_UNSIGNED_BYTE, 0,
636 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
637 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
638 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
640 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
642 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
643 ARB_TEXTURE_FLOAT, NULL},
644 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
646 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
647 ARB_TEXTURE_RG, NULL},
648 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
649 GL_RGB, GL_FLOAT, 12,
650 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
651 ARB_TEXTURE_FLOAT, convert_r32g32_float},
652 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
654 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
655 ARB_TEXTURE_RG, NULL},
656 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
657 GL_RGBA, GL_FLOAT, 0,
658 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
659 ARB_TEXTURE_FLOAT, NULL},
661 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
662 GL_RED, GL_HALF_FLOAT_ARB, 0,
663 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
664 ARB_TEXTURE_FLOAT, NULL},
665 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
666 GL_RED, GL_HALF_FLOAT_ARB, 0,
667 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
668 ARB_TEXTURE_RG, NULL},
669 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
670 GL_RGB, GL_HALF_FLOAT_ARB, 6,
671 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
672 ARB_TEXTURE_FLOAT, convert_r16g16},
673 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
674 GL_RG, GL_HALF_FLOAT_ARB, 0,
675 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
676 ARB_TEXTURE_RG, NULL},
677 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
678 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
679 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET
680 | WINED3DFMT_FLAG_VTF,
681 ARB_TEXTURE_FLOAT, NULL},
682 /* Palettized formats */
683 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
684 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
686 ARB_FRAGMENT_PROGRAM, NULL},
687 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
688 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
690 EXT_PALETTED_TEXTURE, NULL},
691 /* Standard ARGB formats */
692 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
693 GL_BGR, GL_UNSIGNED_BYTE, 0,
694 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
695 WINED3D_GL_EXT_NONE, NULL},
696 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
697 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
698 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
699 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE
700 | WINED3DFMT_FLAG_VTF,
701 WINED3D_GL_EXT_NONE, NULL},
702 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
703 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
704 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
705 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
706 WINED3D_GL_EXT_NONE, NULL},
707 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
708 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
709 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
710 | WINED3DFMT_FLAG_RENDERTARGET,
711 WINED3D_GL_EXT_NONE, NULL},
712 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
713 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
714 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
715 WINED3D_GL_EXT_NONE, NULL},
716 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
717 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
718 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
719 WINED3D_GL_EXT_NONE, NULL},
720 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
721 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
722 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
723 | WINED3DFMT_FLAG_SRGB_READ,
724 WINED3D_GL_EXT_NONE, NULL},
725 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
726 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
727 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
728 WINED3D_GL_EXT_NONE, NULL},
729 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
730 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
731 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
732 WINED3D_GL_EXT_NONE, NULL},
733 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
734 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
735 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
736 WINED3D_GL_EXT_NONE, NULL},
737 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
738 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
739 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
740 | WINED3DFMT_FLAG_RENDERTARGET,
741 WINED3D_GL_EXT_NONE, NULL},
742 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
743 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
744 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
745 WINED3D_GL_EXT_NONE, NULL},
746 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
747 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
748 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
749 WINED3D_GL_EXT_NONE, NULL},
750 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
751 GL_RGB, GL_UNSIGNED_SHORT, 6,
752 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
753 WINED3D_GL_EXT_NONE, convert_r16g16},
754 {WINED3DFMT_R16G16_UNORM, GL_RG16, GL_RG16, 0,
755 GL_RG, GL_UNSIGNED_SHORT, 0,
756 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
757 | WINED3DFMT_FLAG_RENDERTARGET,
758 ARB_TEXTURE_RG, NULL},
759 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
760 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
761 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
762 | WINED3DFMT_FLAG_RENDERTARGET,
763 WINED3D_GL_EXT_NONE, NULL},
764 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
765 GL_RGBA, GL_UNSIGNED_SHORT, 0,
766 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
767 | WINED3DFMT_FLAG_RENDERTARGET,
768 WINED3D_GL_EXT_NONE, NULL},
770 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
771 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
772 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
773 | WINED3DFMT_FLAG_SRGB_READ,
774 WINED3D_GL_EXT_NONE, NULL},
775 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
776 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
777 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
778 | WINED3DFMT_FLAG_SRGB_READ,
779 WINED3D_GL_EXT_NONE, NULL},
780 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
781 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
782 WINED3DFMT_FLAG_FILTERING,
783 WINED3D_GL_EXT_NONE, convert_l4a4_unorm},
784 /* Bump mapping stuff */
785 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
786 GL_BGR, GL_UNSIGNED_BYTE, 3,
787 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
788 | WINED3DFMT_FLAG_BUMPMAP,
789 WINED3D_GL_EXT_NONE, convert_r8g8_snorm},
790 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
791 GL_DSDT_NV, GL_BYTE, 0,
792 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
793 | WINED3DFMT_FLAG_BUMPMAP,
794 NV_TEXTURE_SHADER, NULL},
795 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
796 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
797 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
798 | WINED3DFMT_FLAG_BUMPMAP,
799 WINED3D_GL_EXT_NONE, convert_r5g5_snorm_l6_unorm},
800 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
801 GL_DSDT_MAG_NV, GL_BYTE, 3,
802 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
803 | WINED3DFMT_FLAG_BUMPMAP,
804 NV_TEXTURE_SHADER, convert_r5g5_snorm_l6_unorm_nv},
805 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
806 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
807 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
808 | WINED3DFMT_FLAG_BUMPMAP,
809 WINED3D_GL_EXT_NONE, convert_r8g8_snorm_l8x8_unorm},
810 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
811 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
812 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
813 | WINED3DFMT_FLAG_BUMPMAP,
814 NV_TEXTURE_SHADER, convert_r8g8_snorm_l8x8_unorm_nv},
815 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
816 GL_BGRA, GL_UNSIGNED_BYTE, 4,
817 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
818 | WINED3DFMT_FLAG_BUMPMAP,
819 WINED3D_GL_EXT_NONE, convert_r8g8b8a8_snorm},
820 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
822 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
823 | WINED3DFMT_FLAG_BUMPMAP,
824 NV_TEXTURE_SHADER, NULL},
825 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
826 GL_BGR, GL_UNSIGNED_SHORT, 6,
827 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
828 | WINED3DFMT_FLAG_BUMPMAP,
829 WINED3D_GL_EXT_NONE, convert_r16g16_snorm},
830 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
831 GL_HILO_NV, GL_SHORT, 0,
832 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
833 | WINED3DFMT_FLAG_BUMPMAP,
834 NV_TEXTURE_SHADER, NULL},
835 /* Depth stencil formats */
836 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
837 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
838 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
839 ARB_DEPTH_TEXTURE, NULL},
840 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
841 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
842 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
843 ARB_DEPTH_TEXTURE, NULL},
844 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
845 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
846 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
847 ARB_DEPTH_TEXTURE, NULL},
848 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
849 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
850 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
851 EXT_PACKED_DEPTH_STENCIL, convert_s1_uint_d15_unorm},
852 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
853 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
854 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
855 ARB_FRAMEBUFFER_OBJECT, convert_s1_uint_d15_unorm},
856 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
857 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
858 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
859 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
860 ARB_DEPTH_TEXTURE, NULL},
861 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
862 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
863 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
864 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
865 EXT_PACKED_DEPTH_STENCIL, NULL},
866 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
867 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
868 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
869 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
870 ARB_FRAMEBUFFER_OBJECT, NULL},
871 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
872 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
873 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
874 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
875 ARB_DEPTH_TEXTURE, NULL},
876 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
877 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
878 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
879 ARB_DEPTH_TEXTURE, NULL},
880 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
881 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
882 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
883 EXT_PACKED_DEPTH_STENCIL, convert_s4x4_uint_d24_unorm},
884 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
885 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
886 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
887 ARB_FRAMEBUFFER_OBJECT, convert_s4x4_uint_d24_unorm},
888 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
889 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
890 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
891 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
892 ARB_DEPTH_TEXTURE, NULL},
893 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
894 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
895 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
896 WINED3D_GL_EXT_NONE, NULL},
897 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
898 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
899 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
900 ARB_DEPTH_BUFFER_FLOAT, NULL},
901 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
902 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
903 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
904 ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float},
905 /* Vendor-specific formats */
906 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
907 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
908 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
909 | WINED3DFMT_FLAG_COMPRESSED,
910 ATI_TEXTURE_COMPRESSION_3DC, NULL},
911 {WINED3DFMT_ATI2N, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0,
912 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
913 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
914 | WINED3DFMT_FLAG_COMPRESSED,
915 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
916 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
917 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
918 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
919 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
920 EXT_PACKED_DEPTH_STENCIL, NULL},
921 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
922 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
923 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
924 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
925 ARB_FRAMEBUFFER_OBJECT, NULL},
926 {WINED3DFMT_NULL, GL_RGBA8, GL_RGBA8, 0,
927 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
928 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET,
929 ARB_FRAMEBUFFER_OBJECT, NULL},
932 static inline int getFmtIdx(enum wined3d_format_id format_id)
934 /* First check if the format is at the position of its value.
935 * This will catch the argb formats before the loop is entered. */
936 if (format_id < (sizeof(formats) / sizeof(*formats))
937 && formats[format_id].id == format_id)
945 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
947 if (formats[i].id == format_id) return i;
953 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
955 UINT format_count = sizeof(formats) / sizeof(*formats);
958 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
959 if (!gl_info->formats)
961 ERR("Failed to allocate memory.\n");
965 for (i = 0; i < format_count; ++i)
967 struct wined3d_format *format = &gl_info->formats[i];
968 format->id = formats[i].id;
969 format->red_size = formats[i].red_size;
970 format->green_size = formats[i].green_size;
971 format->blue_size = formats[i].blue_size;
972 format->alpha_size = formats[i].alpha_size;
973 format->red_offset = formats[i].red_offset;
974 format->green_offset = formats[i].green_offset;
975 format->blue_offset = formats[i].blue_offset;
976 format->alpha_offset = formats[i].alpha_offset;
977 format->byte_count = formats[i].bpp;
978 format->depth_size = formats[i].depth_size;
979 format->stencil_size = formats[i].stencil_size;
980 format->block_width = 1;
981 format->block_height = 1;
982 format->block_byte_count = formats[i].bpp;
985 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
987 int fmt_idx = getFmtIdx(format_base_flags[i].id);
991 ERR("Format %s (%#x) not found.\n",
992 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
993 HeapFree(GetProcessHeap(), 0, gl_info->formats);
997 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
1003 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
1007 for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i)
1009 struct wined3d_format *format;
1010 int fmt_idx = getFmtIdx(format_block_info[i].id);
1014 ERR("Format %s (%#x) not found.\n",
1015 debug_d3dformat(format_block_info[i].id), format_block_info[i].id);
1019 format = &gl_info->formats[fmt_idx];
1020 format->block_width = format_block_info[i].block_width;
1021 format->block_height = format_block_info[i].block_height;
1022 format->block_byte_count = format_block_info[i].block_byte_count;
1023 format->flags |= WINED3DFMT_FLAG_BLOCKS;
1029 /* Context activation is done by the caller. */
1030 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
1032 /* Check if the default internal format is supported as a frame buffer
1033 * target, otherwise fall back to the render target internal.
1035 * Try to stick to the standard format if possible, this limits precision differences. */
1039 while (gl_info->gl_ops.gl.p_glGetError());
1040 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1042 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1043 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1045 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0,
1046 format->glFormat, format->glType, NULL);
1047 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1048 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1050 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1052 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1053 checkGLcall("Framebuffer format check");
1055 if (status == GL_FRAMEBUFFER_COMPLETE)
1057 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1058 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1059 format->rtInternal = format->glInternal;
1063 if (!format->rtInternal)
1065 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1067 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1068 " and no fallback specified.\n", debug_d3dformat(format->id));
1069 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1073 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1075 format->rtInternal = format->glInternal;
1079 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1080 debug_d3dformat(format->id));
1082 while (gl_info->gl_ops.gl.p_glGetError());
1084 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1086 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0,
1087 format->glFormat, format->glType, NULL);
1088 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1089 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1091 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1093 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1094 checkGLcall("Framebuffer format check");
1096 if (status == GL_FRAMEBUFFER_COMPLETE)
1098 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1099 debug_d3dformat(format->id));
1103 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1104 debug_d3dformat(format->id));
1105 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1110 if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1111 || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1112 && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
1113 && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA
1114 && (format->red_size || format->alpha_size))
1116 DWORD readback[16 * 16], color, r_range, a_range;
1121 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1122 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1124 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1125 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1126 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1127 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1128 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1129 checkGLcall("RB attachment");
1132 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1133 gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1134 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1135 if (gl_info->gl_ops.gl.p_glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1137 while (gl_info->gl_ops.gl.p_glGetError());
1138 TRACE("Format doesn't support post-pixelshader blending.\n");
1139 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1143 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1144 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16);
1145 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1146 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1147 gl_info->gl_ops.gl.p_glLoadIdentity();
1148 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1149 gl_info->gl_ops.gl.p_glLoadIdentity();
1151 gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1153 /* Draw a full-black quad */
1154 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1155 gl_info->gl_ops.gl.p_glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
1156 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1157 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1158 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1159 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1160 gl_info->gl_ops.gl.p_glEnd();
1162 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1163 /* Draw a half-transparent red quad */
1164 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1165 gl_info->gl_ops.gl.p_glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
1166 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1167 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1168 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1169 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1170 gl_info->gl_ops.gl.p_glEnd();
1172 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1174 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1175 checkGLcall("Post-pixelshader blending check");
1177 color = readback[7 * 16 + 7];
1179 r = (color & 0x00ff0000) >> 16;
1181 r_range = format->red_size < 8 ? 1 << (8 - format->red_size) : 1;
1182 a_range = format->alpha_size < 8 ? 1 << (8 - format->alpha_size) : 1;
1183 if (format->red_size && (r < 0x7f - r_range || r > 0x7f + r_range))
1185 else if (format->alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range))
1189 TRACE("Format doesn't support post-pixelshader blending.\n");
1190 TRACE("Color output: %#x\n", color);
1191 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1195 TRACE("Format supports post-pixelshader blending.\n");
1196 TRACE("Color output: %#x\n", color);
1197 format->flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1201 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1202 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1204 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1205 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1206 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1207 checkGLcall("RB cleanup");
1211 if (format->glInternal != format->glGammaInternal)
1213 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0,
1214 format->glFormat, format->glType, NULL);
1215 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1217 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1218 checkGLcall("Framebuffer format check");
1220 if (status == GL_FRAMEBUFFER_COMPLETE)
1222 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1223 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1227 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1230 else if (status == GL_FRAMEBUFFER_COMPLETE)
1231 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1233 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1236 /* Context activation is done by the caller. */
1237 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1242 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1244 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1245 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1246 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1247 gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0);
1250 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1252 struct wined3d_format *format = &gl_info->formats[i];
1254 if (!format->glInternal) continue;
1256 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1258 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1259 debug_d3dformat(format->id));
1263 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1265 TRACE("Skipping format %s because it's a compressed format.\n",
1266 debug_d3dformat(format->id));
1270 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1272 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1273 check_fbo_compat(gl_info, format);
1277 format->rtInternal = format->glInternal;
1281 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1282 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1285 static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1287 struct fragment_caps fragment_caps;
1288 struct shader_caps shader_caps;
1292 adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
1293 adapter->shader_backend->shader_get_caps(gl_info, &shader_caps);
1294 srgb_write = (fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_SRGB_WRITE)
1295 && (shader_caps.wined3d_caps & WINED3D_SHADER_CAP_SRGB_WRITE);
1297 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1299 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1300 struct wined3d_format *format;
1304 ERR("Format %s (%#x) not found.\n",
1305 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1309 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1311 format = &gl_info->formats[fmt_idx];
1313 /* ARB_texture_rg defines floating point formats, but only if
1314 * ARB_texture_float is also supported. */
1315 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1316 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1319 format->glInternal = format_texture_info[i].gl_internal;
1320 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1321 format->rtInternal = format_texture_info[i].gl_rt_internal;
1322 format->glFormat = format_texture_info[i].gl_format;
1323 format->glType = format_texture_info[i].gl_type;
1324 format->color_fixup = COLOR_FIXUP_IDENTITY;
1325 format->flags |= format_texture_info[i].flags;
1326 format->height_scale.numerator = 1;
1327 format->height_scale.denominator = 1;
1329 if (!gl_info->limits.vertex_samplers)
1330 format->flags &= ~WINED3DFMT_FLAG_VTF;
1332 if (!(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1333 format->flags |= WINED3DFMT_FLAG_FILTERING;
1334 else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT)
1335 format->flags &= ~WINED3DFMT_FLAG_VTF;
1337 if (format->glGammaInternal != format->glInternal)
1339 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1340 if (!gl_info->supported[EXT_TEXTURE_SRGB])
1342 format->glGammaInternal = format->glInternal;
1343 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1345 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1347 format->glInternal = format->glGammaInternal;
1351 if ((format->flags & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write)
1352 format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
1354 /* Texture conversion stuff */
1355 format->convert = format_texture_info[i].convert;
1356 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1362 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1364 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1366 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1368 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1370 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1374 /* A context is provided by the caller */
1375 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1377 static const DWORD data[] = {0x00000000, 0xffffffff};
1378 GLuint tex, fbo, buffer;
1379 DWORD readback[16 * 1];
1382 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1383 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1384 * falling back to software. If this changes in the future this code will get fooled and
1385 * apps might hit the software path due to incorrectly advertised caps.
1387 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1388 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1389 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1392 while (gl_info->gl_ops.gl.p_glGetError());
1394 gl_info->gl_ops.gl.p_glGenTextures(1, &buffer);
1395 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1396 memset(readback, 0x7e, sizeof(readback));
1397 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0,
1398 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1399 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1400 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1401 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1402 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1403 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1405 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1406 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1407 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0,
1408 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1409 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1410 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1411 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1412 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1413 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1414 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
1416 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1417 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1418 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1419 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1421 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1);
1422 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1423 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1424 gl_info->gl_ops.gl.p_glLoadIdentity();
1425 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1426 gl_info->gl_ops.gl.p_glLoadIdentity();
1428 gl_info->gl_ops.gl.p_glClearColor(0, 1, 0, 0);
1429 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1431 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1432 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 0.0);
1433 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, -1.0f);
1434 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 0.0);
1435 gl_info->gl_ops.gl.p_glVertex2f(1.0f, -1.0f);
1436 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 1.0);
1437 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, 1.0f);
1438 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 1.0);
1439 gl_info->gl_ops.gl.p_glVertex2f(1.0f, 1.0f);
1440 gl_info->gl_ops.gl.p_glEnd();
1442 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1443 memset(readback, 0x7f, sizeof(readback));
1444 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1445 if (color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5)
1446 || color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1448 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, assuming no filtering\n",
1449 readback[6], readback[9]);
1454 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1455 readback[6], readback[9]);
1459 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1460 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1461 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1462 gl_info->gl_ops.gl.p_glDeleteTextures(1, &buffer);
1464 if (gl_info->gl_ops.gl.p_glGetError())
1466 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1473 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1475 struct wined3d_format *format;
1476 unsigned int fmt_idx, i;
1477 static const enum wined3d_format_id fmts16[] =
1479 WINED3DFMT_R16_FLOAT,
1480 WINED3DFMT_R16G16_FLOAT,
1481 WINED3DFMT_R16G16B16A16_FLOAT,
1485 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1487 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1488 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1490 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1493 else if (gl_info->limits.glsl_varyings > 44)
1495 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1500 TRACE("Assuming no float16 blending\n");
1506 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1508 fmt_idx = getFmtIdx(fmts16[i]);
1509 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1515 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1517 fmt_idx = getFmtIdx(fmts16[i]);
1518 format = &gl_info->formats[fmt_idx];
1519 if (!format->glInternal) continue; /* Not supported by GL */
1521 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1524 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1525 format->flags |= WINED3DFMT_FLAG_FILTERING;
1529 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1534 static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1539 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1540 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1541 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1543 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1544 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1545 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1547 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1548 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1549 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1551 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1552 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1553 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1555 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1556 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1557 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1559 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1560 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1561 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1562 * the only driver that implements it(fglrx) has a buggy implementation.
1564 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1565 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1566 * conversion for this format.
1568 if (!gl_info->supported[NV_TEXTURE_SHADER])
1570 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1571 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1572 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1573 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1574 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1575 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1579 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1580 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1581 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1583 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1584 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1585 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1588 if (!gl_info->supported[NV_TEXTURE_SHADER])
1590 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1593 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1594 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1595 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1596 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1597 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1598 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1599 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1600 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1601 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1605 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1606 * are converted at surface loading time, but they do not need any modification in
1607 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1608 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1612 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1614 idx = getFmtIdx(WINED3DFMT_ATI2N);
1615 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1616 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1618 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1620 idx = getFmtIdx(WINED3DFMT_ATI2N);
1621 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1622 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1625 if (!gl_info->supported[APPLE_YCBCR_422])
1627 idx = getFmtIdx(WINED3DFMT_YUY2);
1628 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1630 idx = getFmtIdx(WINED3DFMT_UYVY);
1631 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1634 idx = getFmtIdx(WINED3DFMT_YV12);
1635 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
1636 gl_info->formats[idx].height_scale.numerator = 3;
1637 gl_info->formats[idx].height_scale.denominator = 2;
1638 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1640 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1642 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1643 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1646 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1648 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1649 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1652 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1654 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1655 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1656 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1657 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1659 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1660 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1663 if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
1665 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1666 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1668 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1669 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1671 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1672 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1675 if (gl_info->quirks & WINED3D_QUIRK_BROKEN_RGBA16)
1677 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_UNORM);
1678 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1681 /* ATI instancing hack: Although ATI cards do not support Shader Model
1682 * 3.0, they support instancing. To query if the card supports instancing
1683 * CheckDeviceFormat() with the special format MAKEFOURCC('I','N','S','T')
1684 * is used. Should an application check for this, provide a proper return
1685 * value. We can do instancing with all shader versions, but we need
1688 * Additionally applications have to set the D3DRS_POINTSIZE render state
1689 * to MAKEFOURCC('I','N','S','T') once to enable instancing. Wined3d
1690 * doesn't need that and just ignores it.
1692 * With Shader Model 3.0 capable cards Instancing 'just works' in Windows. */
1693 /* FIXME: This should just check the shader backend caps. */
1694 if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
1696 idx = getFmtIdx(WINED3DFMT_INST);
1697 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
1700 /* Depth bound test. To query if the card supports it CheckDeviceFormat()
1701 * with the special format MAKEFOURCC('N','V','D','B') is used. It is
1702 * enabled by setting D3DRS_ADAPTIVETESS_X render state to
1703 * MAKEFOURCC('N','V','D','B') and then controlled by setting
1704 * D3DRS_ADAPTIVETESS_Z (zMin) and D3DRS_ADAPTIVETESS_W (zMax) to test
1706 if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST])
1708 idx = getFmtIdx(WINED3DFMT_NVDB);
1709 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
1712 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1714 struct wined3d_format *format = &gl_info->formats[idx];
1716 if (!(format->flags & WINED3DFMT_FLAG_TEXTURE))
1719 if (!adapter->shader_backend->shader_color_fixup_supported(format->color_fixup)
1720 || !adapter->fragment_pipe->color_fixup_supported(format->color_fixup))
1721 format->flags &= ~WINED3DFMT_FLAG_TEXTURE;
1725 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1729 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1731 struct wined3d_format *format;
1732 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1736 ERR("Format %s (%#x) not found.\n",
1737 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1741 format = &gl_info->formats[fmt_idx];
1742 format->emit_idx = format_vertex_info[i].emit_idx;
1743 format->component_count = format_vertex_info[i].component_count;
1744 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1745 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1746 format->gl_normalized = format_vertex_info[i].gl_normalized;
1747 format->component_size = format_vertex_info[i].component_size;
1753 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1755 if (!init_format_base_info(gl_info)) return FALSE;
1757 if (!init_format_block_info(gl_info))
1759 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1760 gl_info->formats = NULL;
1767 /* Context activation is done by the caller. */
1768 BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter)
1770 struct wined3d_gl_info *gl_info = &adapter->gl_info;
1772 if (!init_format_base_info(gl_info)) return FALSE;
1774 if (!init_format_block_info(gl_info)) goto fail;
1775 if (!init_format_texture_info(adapter, gl_info)) goto fail;
1776 if (!init_format_vertex_info(gl_info)) goto fail;
1778 apply_format_fixups(adapter, gl_info);
1779 init_format_fbo_compat_info(gl_info);
1780 init_format_filter_info(gl_info, adapter->driver_info.vendor);
1785 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1786 gl_info->formats = NULL;
1790 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1791 enum wined3d_format_id format_id)
1793 int idx = getFmtIdx(format_id);
1797 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1798 debug_d3dformat(format_id), format_id);
1799 /* Get the caller a valid pointer */
1800 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1803 return &gl_info->formats[idx];
1806 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1810 if (format->id == WINED3DFMT_UNKNOWN)
1814 else if (format->flags & WINED3DFMT_FLAG_BLOCKS)
1816 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1817 UINT row_count = (height + format->block_height - 1) / format->block_height;
1818 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1822 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1825 if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
1827 /* The D3D format requirements make sure that the resulting format is an integer again */
1828 size *= format->height_scale.numerator;
1829 size /= format->height_scale.denominator;
1835 /*****************************************************************************
1836 * Trace formatting of useful values
1838 const char *debug_d3dformat(enum wined3d_format_id format_id)
1842 #define FMT_TO_STR(format_id) case format_id: return #format_id
1843 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1844 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1845 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1846 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1847 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1848 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1849 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1850 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1851 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1852 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1853 FMT_TO_STR(WINED3DFMT_P8_UINT);
1854 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1855 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1856 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1857 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1858 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1859 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1860 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1861 FMT_TO_STR(WINED3DFMT_UYVY);
1862 FMT_TO_STR(WINED3DFMT_YUY2);
1863 FMT_TO_STR(WINED3DFMT_YV12);
1864 FMT_TO_STR(WINED3DFMT_DXT1);
1865 FMT_TO_STR(WINED3DFMT_DXT2);
1866 FMT_TO_STR(WINED3DFMT_DXT3);
1867 FMT_TO_STR(WINED3DFMT_DXT4);
1868 FMT_TO_STR(WINED3DFMT_DXT5);
1869 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1870 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1871 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1872 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1873 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1874 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1875 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1876 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1877 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1878 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1879 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1880 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1881 FMT_TO_STR(WINED3DFMT_ATI2N);
1882 FMT_TO_STR(WINED3DFMT_NVDB);
1883 FMT_TO_STR(WINED3DFMT_NVHU);
1884 FMT_TO_STR(WINED3DFMT_NVHS);
1885 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1886 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1887 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1888 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1889 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1890 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1891 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1892 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1893 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1894 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1895 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1896 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1897 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1898 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1899 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1900 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1901 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1902 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1903 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1904 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1905 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1906 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1907 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1908 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1909 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1910 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1911 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1912 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1913 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1914 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1915 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1916 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1917 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1918 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1919 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1920 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1921 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1922 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1923 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1924 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1925 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1926 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1927 FMT_TO_STR(WINED3DFMT_R32_UINT);
1928 FMT_TO_STR(WINED3DFMT_R32_SINT);
1929 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1930 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1931 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1932 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1933 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1934 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1935 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1936 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1937 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1938 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1939 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1940 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1941 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1942 FMT_TO_STR(WINED3DFMT_R16_UINT);
1943 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1944 FMT_TO_STR(WINED3DFMT_R16_SINT);
1945 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1946 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1947 FMT_TO_STR(WINED3DFMT_R8_UINT);
1948 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1949 FMT_TO_STR(WINED3DFMT_R8_SINT);
1950 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1951 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1952 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1953 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1954 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1955 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1956 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1957 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1958 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1959 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1960 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1961 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1962 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1963 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1964 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1965 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1966 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1967 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1968 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1969 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1970 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1971 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1972 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1973 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1974 FMT_TO_STR(WINED3DFMT_INTZ);
1975 FMT_TO_STR(WINED3DFMT_NULL);
1976 FMT_TO_STR(WINED3DFMT_R16);
1977 FMT_TO_STR(WINED3DFMT_AL16);
1982 fourcc[0] = (char)(format_id);
1983 fourcc[1] = (char)(format_id >> 8);
1984 fourcc[2] = (char)(format_id >> 16);
1985 fourcc[3] = (char)(format_id >> 24);
1987 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1988 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1990 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1992 return "unrecognized";
1996 const char *debug_d3ddevicetype(enum wined3d_device_type device_type)
1998 switch (device_type)
2000 #define DEVTYPE_TO_STR(dev) case dev: return #dev
2001 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_HAL);
2002 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_REF);
2003 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_SW);
2004 #undef DEVTYPE_TO_STR
2006 FIXME("Unrecognized device type %#x.\n", device_type);
2007 return "unrecognized";
2011 const char *debug_d3dusage(DWORD usage)
2016 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
2017 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
2018 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
2019 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
2020 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
2021 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
2022 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
2023 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
2024 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
2025 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
2026 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
2027 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
2028 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
2029 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
2030 #undef WINED3DUSAGE_TO_STR
2031 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
2033 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2036 const char *debug_d3dusagequery(DWORD usagequery)
2041 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
2042 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
2043 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
2044 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
2045 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
2046 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
2047 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
2048 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
2049 #undef WINED3DUSAGEQUERY_TO_STR
2050 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
2052 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2055 const char *debug_d3ddeclmethod(enum wined3d_decl_method method)
2059 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
2060 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_DEFAULT);
2061 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_U);
2062 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_V);
2063 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_CROSS_UV);
2064 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_UV);
2065 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP);
2066 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP_PRESAMPLED);
2067 #undef WINED3DDECLMETHOD_TO_STR
2069 FIXME("Unrecognized declaration method %#x.\n", method);
2070 return "unrecognized";
2074 const char *debug_d3ddeclusage(enum wined3d_decl_usage usage)
2078 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
2079 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITION);
2080 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_WEIGHT);
2081 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_INDICES);
2082 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_NORMAL);
2083 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_PSIZE);
2084 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TEXCOORD);
2085 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TANGENT);
2086 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BINORMAL);
2087 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TESS_FACTOR);
2088 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITIONT);
2089 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_COLOR);
2090 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_FOG);
2091 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_DEPTH);
2092 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_SAMPLE);
2093 #undef WINED3DDECLUSAGE_TO_STR
2095 FIXME("Unrecognized %u declaration usage!\n", usage);
2096 return "unrecognized";
2100 const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
2102 switch (resource_type)
2104 #define RES_TO_STR(res) case res: return #res
2105 RES_TO_STR(WINED3D_RTYPE_SURFACE);
2106 RES_TO_STR(WINED3D_RTYPE_VOLUME);
2107 RES_TO_STR(WINED3D_RTYPE_TEXTURE);
2108 RES_TO_STR(WINED3D_RTYPE_VOLUME_TEXTURE);
2109 RES_TO_STR(WINED3D_RTYPE_CUBE_TEXTURE);
2110 RES_TO_STR(WINED3D_RTYPE_BUFFER);
2113 FIXME("Unrecognized resource type %#x.\n", resource_type);
2114 return "unrecognized";
2118 const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type)
2120 switch (primitive_type)
2122 #define PRIM_TO_STR(prim) case prim: return #prim
2123 PRIM_TO_STR(WINED3D_PT_UNDEFINED);
2124 PRIM_TO_STR(WINED3D_PT_POINTLIST);
2125 PRIM_TO_STR(WINED3D_PT_LINELIST);
2126 PRIM_TO_STR(WINED3D_PT_LINESTRIP);
2127 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST);
2128 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP);
2129 PRIM_TO_STR(WINED3D_PT_TRIANGLEFAN);
2130 PRIM_TO_STR(WINED3D_PT_LINELIST_ADJ);
2131 PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ);
2132 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ);
2133 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ);
2136 FIXME("Unrecognized %u primitive type!\n", primitive_type);
2137 return "unrecognized";
2141 const char *debug_d3drenderstate(enum wined3d_render_state state)
2145 #define D3DSTATE_TO_STR(u) case u: return #u
2146 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIAS);
2147 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREPERSPECTIVE);
2148 D3DSTATE_TO_STR(WINED3D_RS_WRAPU);
2149 D3DSTATE_TO_STR(WINED3D_RS_WRAPV);
2150 D3DSTATE_TO_STR(WINED3D_RS_ZENABLE);
2151 D3DSTATE_TO_STR(WINED3D_RS_FILLMODE);
2152 D3DSTATE_TO_STR(WINED3D_RS_SHADEMODE);
2153 D3DSTATE_TO_STR(WINED3D_RS_LINEPATTERN);
2154 D3DSTATE_TO_STR(WINED3D_RS_MONOENABLE);
2155 D3DSTATE_TO_STR(WINED3D_RS_ROP2);
2156 D3DSTATE_TO_STR(WINED3D_RS_PLANEMASK);
2157 D3DSTATE_TO_STR(WINED3D_RS_ZWRITEENABLE);
2158 D3DSTATE_TO_STR(WINED3D_RS_ALPHATESTENABLE);
2159 D3DSTATE_TO_STR(WINED3D_RS_LASTPIXEL);
2160 D3DSTATE_TO_STR(WINED3D_RS_SRCBLEND);
2161 D3DSTATE_TO_STR(WINED3D_RS_DESTBLEND);
2162 D3DSTATE_TO_STR(WINED3D_RS_CULLMODE);
2163 D3DSTATE_TO_STR(WINED3D_RS_ZFUNC);
2164 D3DSTATE_TO_STR(WINED3D_RS_ALPHAREF);
2165 D3DSTATE_TO_STR(WINED3D_RS_ALPHAFUNC);
2166 D3DSTATE_TO_STR(WINED3D_RS_DITHERENABLE);
2167 D3DSTATE_TO_STR(WINED3D_RS_ALPHABLENDENABLE);
2168 D3DSTATE_TO_STR(WINED3D_RS_FOGENABLE);
2169 D3DSTATE_TO_STR(WINED3D_RS_SPECULARENABLE);
2170 D3DSTATE_TO_STR(WINED3D_RS_ZVISIBLE);
2171 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXEL);
2172 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXELX);
2173 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEDALPHA);
2174 D3DSTATE_TO_STR(WINED3D_RS_FOGCOLOR);
2175 D3DSTATE_TO_STR(WINED3D_RS_FOGTABLEMODE);
2176 D3DSTATE_TO_STR(WINED3D_RS_FOGSTART);
2177 D3DSTATE_TO_STR(WINED3D_RS_FOGEND);
2178 D3DSTATE_TO_STR(WINED3D_RS_FOGDENSITY);
2179 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEENABLE);
2180 D3DSTATE_TO_STR(WINED3D_RS_EDGEANTIALIAS);
2181 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYENABLE);
2182 D3DSTATE_TO_STR(WINED3D_RS_MIPMAPLODBIAS);
2183 D3DSTATE_TO_STR(WINED3D_RS_RANGEFOGENABLE);
2184 D3DSTATE_TO_STR(WINED3D_RS_ANISOTROPY);
2185 D3DSTATE_TO_STR(WINED3D_RS_FLUSHBATCH);
2186 D3DSTATE_TO_STR(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT);
2187 D3DSTATE_TO_STR(WINED3D_RS_STENCILENABLE);
2188 D3DSTATE_TO_STR(WINED3D_RS_STENCILFAIL);
2189 D3DSTATE_TO_STR(WINED3D_RS_STENCILZFAIL);
2190 D3DSTATE_TO_STR(WINED3D_RS_STENCILPASS);
2191 D3DSTATE_TO_STR(WINED3D_RS_STENCILFUNC);
2192 D3DSTATE_TO_STR(WINED3D_RS_STENCILREF);
2193 D3DSTATE_TO_STR(WINED3D_RS_STENCILMASK);
2194 D3DSTATE_TO_STR(WINED3D_RS_STENCILWRITEMASK);
2195 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREFACTOR);
2196 D3DSTATE_TO_STR(WINED3D_RS_WRAP0);
2197 D3DSTATE_TO_STR(WINED3D_RS_WRAP1);
2198 D3DSTATE_TO_STR(WINED3D_RS_WRAP2);
2199 D3DSTATE_TO_STR(WINED3D_RS_WRAP3);
2200 D3DSTATE_TO_STR(WINED3D_RS_WRAP4);
2201 D3DSTATE_TO_STR(WINED3D_RS_WRAP5);
2202 D3DSTATE_TO_STR(WINED3D_RS_WRAP6);
2203 D3DSTATE_TO_STR(WINED3D_RS_WRAP7);
2204 D3DSTATE_TO_STR(WINED3D_RS_CLIPPING);
2205 D3DSTATE_TO_STR(WINED3D_RS_LIGHTING);
2206 D3DSTATE_TO_STR(WINED3D_RS_EXTENTS);
2207 D3DSTATE_TO_STR(WINED3D_RS_AMBIENT);
2208 D3DSTATE_TO_STR(WINED3D_RS_FOGVERTEXMODE);
2209 D3DSTATE_TO_STR(WINED3D_RS_COLORVERTEX);
2210 D3DSTATE_TO_STR(WINED3D_RS_LOCALVIEWER);
2211 D3DSTATE_TO_STR(WINED3D_RS_NORMALIZENORMALS);
2212 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYBLENDENABLE);
2213 D3DSTATE_TO_STR(WINED3D_RS_DIFFUSEMATERIALSOURCE);
2214 D3DSTATE_TO_STR(WINED3D_RS_SPECULARMATERIALSOURCE);
2215 D3DSTATE_TO_STR(WINED3D_RS_AMBIENTMATERIALSOURCE);
2216 D3DSTATE_TO_STR(WINED3D_RS_EMISSIVEMATERIALSOURCE);
2217 D3DSTATE_TO_STR(WINED3D_RS_VERTEXBLEND);
2218 D3DSTATE_TO_STR(WINED3D_RS_CLIPPLANEENABLE);
2219 D3DSTATE_TO_STR(WINED3D_RS_SOFTWAREVERTEXPROCESSING);
2220 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE);
2221 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MIN);
2222 D3DSTATE_TO_STR(WINED3D_RS_POINTSPRITEENABLE);
2223 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALEENABLE);
2224 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_A);
2225 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_B);
2226 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_C);
2227 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEANTIALIAS);
2228 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEMASK);
2229 D3DSTATE_TO_STR(WINED3D_RS_PATCHEDGESTYLE);
2230 D3DSTATE_TO_STR(WINED3D_RS_PATCHSEGMENTS);
2231 D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN);
2232 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX);
2233 D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE);
2234 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
2235 D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR);
2236 D3DSTATE_TO_STR(WINED3D_RS_BLENDOP);
2237 D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE);
2238 D3DSTATE_TO_STR(WINED3D_RS_NORMALDEGREE);
2239 D3DSTATE_TO_STR(WINED3D_RS_SCISSORTESTENABLE);
2240 D3DSTATE_TO_STR(WINED3D_RS_SLOPESCALEDEPTHBIAS);
2241 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIASEDLINEENABLE);
2242 D3DSTATE_TO_STR(WINED3D_RS_MINTESSELLATIONLEVEL);
2243 D3DSTATE_TO_STR(WINED3D_RS_MAXTESSELLATIONLEVEL);
2244 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_X);
2245 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Y);
2246 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Z);
2247 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_W);
2248 D3DSTATE_TO_STR(WINED3D_RS_ENABLEADAPTIVETESSELLATION);
2249 D3DSTATE_TO_STR(WINED3D_RS_TWOSIDEDSTENCILMODE);
2250 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFAIL);
2251 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILZFAIL);
2252 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILPASS);
2253 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFUNC);
2254 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1);
2255 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2);
2256 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3);
2257 D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR);
2258 D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE);
2259 D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS);
2260 D3DSTATE_TO_STR(WINED3D_RS_WRAP8);
2261 D3DSTATE_TO_STR(WINED3D_RS_WRAP9);
2262 D3DSTATE_TO_STR(WINED3D_RS_WRAP10);
2263 D3DSTATE_TO_STR(WINED3D_RS_WRAP11);
2264 D3DSTATE_TO_STR(WINED3D_RS_WRAP12);
2265 D3DSTATE_TO_STR(WINED3D_RS_WRAP13);
2266 D3DSTATE_TO_STR(WINED3D_RS_WRAP14);
2267 D3DSTATE_TO_STR(WINED3D_RS_WRAP15);
2268 D3DSTATE_TO_STR(WINED3D_RS_SEPARATEALPHABLENDENABLE);
2269 D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
2270 D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
2271 D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
2272 #undef D3DSTATE_TO_STR
2274 FIXME("Unrecognized %u render state!\n", state);
2275 return "unrecognized";
2279 const char *debug_d3dsamplerstate(enum wined3d_sampler_state state)
2283 #define D3DSTATE_TO_STR(u) case u: return #u
2284 D3DSTATE_TO_STR(WINED3D_SAMP_BORDER_COLOR);
2285 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_U);
2286 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_V);
2287 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_W);
2288 D3DSTATE_TO_STR(WINED3D_SAMP_MAG_FILTER);
2289 D3DSTATE_TO_STR(WINED3D_SAMP_MIN_FILTER);
2290 D3DSTATE_TO_STR(WINED3D_SAMP_MIP_FILTER);
2291 D3DSTATE_TO_STR(WINED3D_SAMP_MIPMAP_LOD_BIAS);
2292 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_MIP_LEVEL);
2293 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_ANISOTROPY);
2294 D3DSTATE_TO_STR(WINED3D_SAMP_SRGB_TEXTURE);
2295 D3DSTATE_TO_STR(WINED3D_SAMP_ELEMENT_INDEX);
2296 D3DSTATE_TO_STR(WINED3D_SAMP_DMAP_OFFSET);
2297 #undef D3DSTATE_TO_STR
2299 FIXME("Unrecognized %u sampler state!\n", state);
2300 return "unrecognized";
2304 const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type)
2306 switch (filter_type)
2308 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2309 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_NONE);
2310 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_POINT);
2311 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_LINEAR);
2312 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_ANISOTROPIC);
2313 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_FLAT_CUBIC);
2314 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_CUBIC);
2315 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_PYRAMIDAL_QUAD);
2316 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_QUAD);
2317 #undef D3DTEXTUREFILTERTYPE_TO_STR
2319 FIXME("Unrecognied texture filter type 0x%08x.\n", filter_type);
2320 return "unrecognized";
2324 const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state)
2328 #define D3DSTATE_TO_STR(u) case u: return #u
2329 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_OP);
2330 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG1);
2331 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG2);
2332 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_OP);
2333 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG1);
2334 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG2);
2335 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT00);
2336 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT01);
2337 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT10);
2338 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT11);
2339 D3DSTATE_TO_STR(WINED3D_TSS_TEXCOORD_INDEX);
2340 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LSCALE);
2341 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LOFFSET);
2342 D3DSTATE_TO_STR(WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS);
2343 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG0);
2344 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG0);
2345 D3DSTATE_TO_STR(WINED3D_TSS_RESULT_ARG);
2346 D3DSTATE_TO_STR(WINED3D_TSS_CONSTANT);
2347 #undef D3DSTATE_TO_STR
2349 FIXME("Unrecognized %u texture state!\n", state);
2350 return "unrecognized";
2354 const char *debug_d3dtop(enum wined3d_texture_op d3dtop)
2358 #define D3DTOP_TO_STR(u) case u: return #u
2359 D3DTOP_TO_STR(WINED3D_TOP_DISABLE);
2360 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG1);
2361 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG2);
2362 D3DTOP_TO_STR(WINED3D_TOP_MODULATE);
2363 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_2X);
2364 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_4X);
2365 D3DTOP_TO_STR(WINED3D_TOP_ADD);
2366 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED);
2367 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED_2X);
2368 D3DTOP_TO_STR(WINED3D_TOP_SUBTRACT);
2369 D3DTOP_TO_STR(WINED3D_TOP_ADD_SMOOTH);
2370 D3DTOP_TO_STR(WINED3D_TOP_BLEND_DIFFUSE_ALPHA);
2371 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA);
2372 D3DTOP_TO_STR(WINED3D_TOP_BLEND_FACTOR_ALPHA);
2373 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM);
2374 D3DTOP_TO_STR(WINED3D_TOP_BLEND_CURRENT_ALPHA);
2375 D3DTOP_TO_STR(WINED3D_TOP_PREMODULATE);
2376 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR);
2377 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA);
2378 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR);
2379 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA);
2380 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP);
2381 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP_LUMINANCE);
2382 D3DTOP_TO_STR(WINED3D_TOP_DOTPRODUCT3);
2383 D3DTOP_TO_STR(WINED3D_TOP_MULTIPLY_ADD);
2384 D3DTOP_TO_STR(WINED3D_TOP_LERP);
2385 #undef D3DTOP_TO_STR
2387 FIXME("Unrecognized texture op %#x.\n", d3dtop);
2388 return "unrecognized";
2392 const char *debug_d3dtstype(enum wined3d_transform_state tstype)
2396 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2397 TSTYPE_TO_STR(WINED3D_TS_VIEW);
2398 TSTYPE_TO_STR(WINED3D_TS_PROJECTION);
2399 TSTYPE_TO_STR(WINED3D_TS_TEXTURE0);
2400 TSTYPE_TO_STR(WINED3D_TS_TEXTURE1);
2401 TSTYPE_TO_STR(WINED3D_TS_TEXTURE2);
2402 TSTYPE_TO_STR(WINED3D_TS_TEXTURE3);
2403 TSTYPE_TO_STR(WINED3D_TS_TEXTURE4);
2404 TSTYPE_TO_STR(WINED3D_TS_TEXTURE5);
2405 TSTYPE_TO_STR(WINED3D_TS_TEXTURE6);
2406 TSTYPE_TO_STR(WINED3D_TS_TEXTURE7);
2407 TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(0));
2408 #undef TSTYPE_TO_STR
2410 if (tstype > 256 && tstype < 512)
2412 FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype);
2413 return ("WINED3D_TS_WORLD_MATRIX > 0");
2415 FIXME("Unrecognized transform state %#x.\n", tstype);
2416 return "unrecognized";
2420 const char *debug_d3dstate(DWORD state)
2422 if (STATE_IS_RENDER(state))
2423 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2424 if (STATE_IS_TEXTURESTAGE(state))
2426 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2427 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2428 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2429 texture_stage, debug_d3dtexturestate(texture_state));
2431 if (STATE_IS_SAMPLER(state))
2432 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2433 if (STATE_IS_PIXELSHADER(state))
2434 return "STATE_PIXELSHADER";
2435 if (STATE_IS_TRANSFORM(state))
2436 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2437 if (STATE_IS_STREAMSRC(state))
2438 return "STATE_STREAMSRC";
2439 if (STATE_IS_INDEXBUFFER(state))
2440 return "STATE_INDEXBUFFER";
2441 if (STATE_IS_VDECL(state))
2442 return "STATE_VDECL";
2443 if (STATE_IS_VSHADER(state))
2444 return "STATE_VSHADER";
2445 if (STATE_IS_GEOMETRY_SHADER(state))
2446 return "STATE_GEOMETRY_SHADER";
2447 if (STATE_IS_VIEWPORT(state))
2448 return "STATE_VIEWPORT";
2449 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2450 return "STATE_VERTEXSHADERCONSTANT";
2451 if (STATE_IS_PIXELSHADERCONSTANT(state))
2452 return "STATE_PIXELSHADERCONSTANT";
2453 if (STATE_IS_ACTIVELIGHT(state))
2454 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2455 if (STATE_IS_SCISSORRECT(state))
2456 return "STATE_SCISSORRECT";
2457 if (STATE_IS_CLIPPLANE(state))
2458 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2459 if (STATE_IS_MATERIAL(state))
2460 return "STATE_MATERIAL";
2461 if (STATE_IS_FRONTFACE(state))
2462 return "STATE_FRONTFACE";
2463 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2464 return "STATE_POINTSPRITECOORDORIGIN";
2465 if (STATE_IS_BASEVERTEXINDEX(state))
2466 return "STATE_BASEVERTEXINDEX";
2467 if (STATE_IS_FRAMEBUFFER(state))
2468 return "STATE_FRAMEBUFFER";
2470 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2473 const char *debug_d3dpool(enum wined3d_pool pool)
2477 #define POOL_TO_STR(p) case p: return #p
2478 POOL_TO_STR(WINED3D_POOL_DEFAULT);
2479 POOL_TO_STR(WINED3D_POOL_MANAGED);
2480 POOL_TO_STR(WINED3D_POOL_SYSTEM_MEM);
2481 POOL_TO_STR(WINED3D_POOL_SCRATCH);
2484 FIXME("Unrecognized pool %#x.\n", pool);
2485 return "unrecognized";
2489 const char *debug_fbostatus(GLenum status) {
2491 #define FBOSTATUS_TO_STR(u) case u: return #u
2492 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2493 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2494 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2495 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2496 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2497 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2498 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2499 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2500 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2501 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2502 #undef FBOSTATUS_TO_STR
2504 FIXME("Unrecognied FBO status 0x%08x\n", status);
2505 return "unrecognized";
2509 const char *debug_glerror(GLenum error) {
2511 #define GLERROR_TO_STR(u) case u: return #u
2512 GLERROR_TO_STR(GL_NO_ERROR);
2513 GLERROR_TO_STR(GL_INVALID_ENUM);
2514 GLERROR_TO_STR(GL_INVALID_VALUE);
2515 GLERROR_TO_STR(GL_INVALID_OPERATION);
2516 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2517 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2518 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2519 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2520 #undef GLERROR_TO_STR
2522 FIXME("Unrecognied GL error 0x%08x\n", error);
2523 return "unrecognized";
2527 const char *debug_d3dbasis(enum wined3d_basis_type basis)
2531 case WINED3D_BASIS_BEZIER: return "WINED3D_BASIS_BEZIER";
2532 case WINED3D_BASIS_BSPLINE: return "WINED3D_BASIS_BSPLINE";
2533 case WINED3D_BASIS_INTERPOLATE: return "WINED3D_BASIS_INTERPOLATE";
2534 default: return "unrecognized";
2538 const char *debug_d3ddegree(enum wined3d_degree_type degree)
2542 case WINED3D_DEGREE_LINEAR: return "WINED3D_DEGREE_LINEAR";
2543 case WINED3D_DEGREE_QUADRATIC: return "WINED3D_DEGREE_QUADRATIC";
2544 case WINED3D_DEGREE_CUBIC: return "WINED3D_DEGREE_CUBIC";
2545 case WINED3D_DEGREE_QUINTIC: return "WINED3D_DEGREE_QUINTIC";
2546 default: return "unrecognized";
2550 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2554 #define WINED3D_TO_STR(x) case x: return #x
2555 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2556 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2557 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2558 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2559 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2560 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2561 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2562 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2563 #undef WINED3D_TO_STR
2565 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2566 return "unrecognized";
2570 static const char *debug_complex_fixup(enum complex_fixup fixup)
2574 #define WINED3D_TO_STR(x) case x: return #x
2575 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2576 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2577 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2578 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2579 #undef WINED3D_TO_STR
2581 FIXME("Unrecognized complex fixup %#x\n", fixup);
2582 return "unrecognized";
2586 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2588 if (is_complex_fixup(fixup))
2590 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2594 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2595 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2596 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2597 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2600 const char *debug_surflocation(DWORD flag) {
2604 if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM"); /* 17 */
2605 if (flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE"); /* 19 */
2606 if (flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE"); /* 18 */
2607 if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX"); /* 18 */
2608 if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE"); /* 25 */
2609 if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED"); /* 22 */
2610 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2613 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2614 enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2616 if (op == WINED3D_TOP_DISABLE)
2618 if (state->textures[stage])
2621 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2622 && op != WINED3D_TOP_SELECT_ARG2)
2624 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2625 && op != WINED3D_TOP_SELECT_ARG1)
2627 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2628 && (op == WINED3D_TOP_MULTIPLY_ADD || op == WINED3D_TOP_LERP))
2634 /* Setup this textures matrix according to the texture flags. */
2635 /* Context activation is done by the caller (state handler). */
2636 void set_texture_matrix(const struct wined3d_gl_info *gl_info, const float *smat, DWORD flags,
2637 BOOL calculatedCoords, BOOL transformed, enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2641 gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
2642 checkGLcall("glMatrixMode(GL_TEXTURE)");
2644 if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed)
2646 gl_info->gl_ops.gl.p_glLoadIdentity();
2647 checkGLcall("glLoadIdentity()");
2651 if (flags == (WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED))
2653 ERR("Invalid texture transform flags: WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED.\n");
2657 memcpy(mat, smat, 16 * sizeof(float));
2659 if (flags & WINED3D_TTFF_PROJECTED)
2661 if (!ffp_proj_control)
2663 switch (flags & ~WINED3D_TTFF_PROJECTED)
2665 case WINED3D_TTFF_COUNT2:
2670 mat[ 1] = mat[ 5] = mat[ 9] = mat[13] = 0.0f;
2672 case WINED3D_TTFF_COUNT3:
2677 mat[ 2] = mat[ 6] = mat[10] = mat[14] = 0.0f;
2681 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2682 if(!calculatedCoords) {
2685 case WINED3DFMT_R32_FLOAT:
2686 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2687 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2688 * the input value to the transformation will be 0, so the matrix value is irrelevant
2695 case WINED3DFMT_R32G32_FLOAT:
2696 /* See above, just 3rd and 4th coord
2703 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2704 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2706 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2707 * into a bad place. The division elimination below will apply to make sure the
2708 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2710 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2713 FIXME("Unexpected fixed function texture coord input\n");
2716 if (!ffp_proj_control)
2718 switch (flags & ~WINED3D_TTFF_PROJECTED)
2720 /* case WINED3D_TTFF_COUNT1: Won't ever get here. */
2721 case WINED3D_TTFF_COUNT2:
2722 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2723 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2724 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2725 * the 4th coord evaluates to 1.0 to eliminate that.
2727 * If the fixed function pipeline is used, the 4th value remains unused,
2728 * so there is no danger in doing this. With vertex shaders we have a
2729 * problem. Should an app hit that problem, the code here would have to
2730 * check for pixel shaders, and the shader has to undo the default gl divide.
2732 * A more serious problem occurs if the app passes 4 coordinates in, and the
2733 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2734 * or a replacement shader. */
2736 mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2741 gl_info->gl_ops.gl.p_glLoadMatrixf(mat);
2742 checkGLcall("glLoadMatrixf(mat)");
2745 /* This small helper function is used to convert a bitmask into the number of masked bits */
2746 unsigned int count_bits(unsigned int mask)
2749 for (count = 0; mask; ++count)
2756 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2757 * The later function requires individual color components. */
2758 BOOL getColorBits(const struct wined3d_format *format,
2759 BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2761 TRACE("format %s.\n", debug_d3dformat(format->id));
2765 case WINED3DFMT_B10G10R10A2_UNORM:
2766 case WINED3DFMT_R10G10B10A2_UNORM:
2767 case WINED3DFMT_B8G8R8X8_UNORM:
2768 case WINED3DFMT_B8G8R8_UNORM:
2769 case WINED3DFMT_B8G8R8A8_UNORM:
2770 case WINED3DFMT_R8G8B8A8_UNORM:
2771 case WINED3DFMT_B5G5R5X1_UNORM:
2772 case WINED3DFMT_B5G5R5A1_UNORM:
2773 case WINED3DFMT_B5G6R5_UNORM:
2774 case WINED3DFMT_B4G4R4X4_UNORM:
2775 case WINED3DFMT_B4G4R4A4_UNORM:
2776 case WINED3DFMT_B2G3R3_UNORM:
2777 case WINED3DFMT_P8_UINT_A8_UNORM:
2778 case WINED3DFMT_P8_UINT:
2781 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2785 *redSize = format->red_size;
2786 *greenSize = format->green_size;
2787 *blueSize = format->blue_size;
2788 *alphaSize = format->alpha_size;
2789 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2791 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2792 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2796 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2797 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
2799 TRACE("format %s.\n", debug_d3dformat(format->id));
2803 case WINED3DFMT_D16_LOCKABLE:
2804 case WINED3DFMT_D16_UNORM:
2805 case WINED3DFMT_S1_UINT_D15_UNORM:
2806 case WINED3DFMT_X8D24_UNORM:
2807 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2808 case WINED3DFMT_D24_UNORM_S8_UINT:
2809 case WINED3DFMT_S8_UINT_D24_FLOAT:
2810 case WINED3DFMT_D32_UNORM:
2811 case WINED3DFMT_D32_FLOAT:
2812 case WINED3DFMT_INTZ:
2815 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2819 *depthSize = format->depth_size;
2820 *stencilSize = format->stencil_size;
2822 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2823 *depthSize, *stencilSize, debug_d3dformat(format->id));
2827 /* Note: It's the caller's responsibility to ensure values can be expressed
2828 * in the requested format. UNORM formats for example can only express values
2829 * in the range 0.0f -> 1.0f. */
2830 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color)
2834 enum wined3d_format_id format_id;
2846 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2847 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2848 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2849 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2850 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2851 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2852 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2853 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2854 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2855 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2856 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2857 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2858 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2859 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2861 const struct wined3d_format *format = surface->resource.format;
2864 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2865 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2867 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2871 if (format->id != conv[i].format_id) continue;
2873 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2874 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2875 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2876 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2878 TRACE("Returning 0x%08x.\n", ret);
2883 if (format->id == WINED3DFMT_P8_UINT)
2888 if (!surface->palette)
2890 WARN("Surface doesn't have a palette, returning 0.\n");
2894 r = (BYTE)((color->r * 255.0f) + 0.5f);
2895 g = (BYTE)((color->g * 255.0f) + 0.5f);
2896 b = (BYTE)((color->b * 255.0f) + 0.5f);
2897 a = (BYTE)((color->a * 255.0f) + 0.5f);
2899 e = &surface->palette->palents[a];
2900 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2903 WARN("Alpha didn't match index, searching full palette.\n");
2905 for (i = 0; i < 256; ++i)
2907 e = &surface->palette->palents[i];
2908 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2912 FIXME("Unable to convert color to palette index.\n");
2917 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2922 /* DirectDraw stuff */
2923 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2927 case 8: return WINED3DFMT_P8_UINT;
2928 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2929 case 16: return WINED3DFMT_B5G6R5_UNORM;
2930 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2931 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2932 default: return WINED3DFMT_UNKNOWN;
2936 void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
2937 const struct wined3d_matrix *src2)
2939 struct wined3d_matrix temp;
2941 /* Now do the multiplication 'by hand'.
2942 I know that all this could be optimised, but this will be done later :-) */
2943 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);
2944 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);
2945 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);
2946 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);
2948 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);
2949 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);
2950 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);
2951 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);
2953 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);
2954 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);
2955 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);
2956 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);
2958 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);
2959 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);
2960 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);
2961 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);
2963 /* And copy the new matrix in the good storage.. */
2964 memcpy(dest, &temp, 16 * sizeof(float));
2967 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2970 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2972 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2973 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2974 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2975 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2976 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2977 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2978 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2979 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2980 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2981 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2982 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2983 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2984 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2985 default: ERR("Unexpected position mask\n");
2987 for (i = 0; i < numTextures; i++) {
2988 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2994 void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_state *state,
2995 struct ffp_frag_settings *settings, BOOL ignore_textype)
3000 static const unsigned char args[WINED3D_TOP_LERP + 1] =
3003 /* D3DTOP_DISABLE */ 0,
3004 /* D3DTOP_SELECTARG1 */ ARG1,
3005 /* D3DTOP_SELECTARG2 */ ARG2,
3006 /* D3DTOP_MODULATE */ ARG1 | ARG2,
3007 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
3008 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
3009 /* D3DTOP_ADD */ ARG1 | ARG2,
3010 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
3011 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
3012 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
3013 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
3014 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
3015 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
3016 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
3017 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
3018 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
3019 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
3020 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
3021 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
3022 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
3023 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
3024 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
3025 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
3026 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
3027 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
3028 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
3032 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
3033 const struct wined3d_surface *rt = state->fb->render_targets[0];
3034 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
3036 for (i = 0; i < gl_info->limits.texture_stages; ++i)
3038 const struct wined3d_texture *texture;
3040 settings->op[i].padding = 0;
3041 if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
3043 settings->op[i].cop = WINED3D_TOP_DISABLE;
3044 settings->op[i].aop = WINED3D_TOP_DISABLE;
3045 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
3046 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
3047 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
3048 settings->op[i].dst = resultreg;
3049 settings->op[i].tex_type = tex_1d;
3050 settings->op[i].projected = proj_none;
3055 if ((texture = state->textures[i]))
3057 settings->op[i].color_fixup = texture->resource.format->color_fixup;
3060 settings->op[i].tex_type = tex_1d;
3064 switch (texture->target)
3067 settings->op[i].tex_type = tex_1d;
3070 settings->op[i].tex_type = tex_2d;
3073 settings->op[i].tex_type = tex_3d;
3075 case GL_TEXTURE_CUBE_MAP_ARB:
3076 settings->op[i].tex_type = tex_cube;
3078 case GL_TEXTURE_RECTANGLE_ARB:
3079 settings->op[i].tex_type = tex_rect;
3084 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
3085 settings->op[i].tex_type = tex_1d;
3088 cop = state->texture_states[i][WINED3D_TSS_COLOR_OP];
3089 aop = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
3091 carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG1] : ARG_UNUSED;
3092 carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG2] : ARG_UNUSED;
3093 carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG0] : ARG_UNUSED;
3095 if (is_invalid_op(state, i, cop, carg1, carg2, carg0))
3099 carg1 = WINED3DTA_CURRENT;
3100 cop = WINED3D_TOP_SELECT_ARG1;
3103 if (cop == WINED3D_TOP_DOTPRODUCT3)
3105 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
3106 * the color result to the alpha component of the destination
3115 aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] : ARG_UNUSED;
3116 aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] : ARG_UNUSED;
3117 aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] : ARG_UNUSED;
3120 if (!i && state->textures[0] && state->render_states[WINED3D_RS_COLORKEYENABLE])
3122 GLenum texture_dimensions;
3124 texture = state->textures[0];
3125 texture_dimensions = texture->target;
3127 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3129 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3131 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size)
3133 if (aop == WINED3D_TOP_DISABLE)
3135 aarg1 = WINED3DTA_TEXTURE;
3136 aop = WINED3D_TOP_SELECT_ARG1;
3138 else if (aop == WINED3D_TOP_SELECT_ARG1 && aarg1 != WINED3DTA_TEXTURE)
3140 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3142 aarg2 = WINED3DTA_TEXTURE;
3143 aop = WINED3D_TOP_MODULATE;
3145 else aarg1 = WINED3DTA_TEXTURE;
3147 else if (aop == WINED3D_TOP_SELECT_ARG2 && aarg2 != WINED3DTA_TEXTURE)
3149 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3151 aarg1 = WINED3DTA_TEXTURE;
3152 aop = WINED3D_TOP_MODULATE;
3154 else aarg2 = WINED3DTA_TEXTURE;
3160 if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0))
3164 aarg1 = WINED3DTA_CURRENT;
3165 aop = WINED3D_TOP_SELECT_ARG1;
3168 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
3169 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
3171 ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
3172 if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3))
3173 settings->op[i].projected = proj_count3;
3174 else if (ttff & WINED3D_TTFF_PROJECTED)
3175 settings->op[i].projected = proj_count4;
3177 settings->op[i].projected = proj_none;
3181 settings->op[i].projected = proj_none;
3184 settings->op[i].cop = cop;
3185 settings->op[i].aop = aop;
3186 settings->op[i].carg0 = carg0;
3187 settings->op[i].carg1 = carg1;
3188 settings->op[i].carg2 = carg2;
3189 settings->op[i].aarg0 = aarg0;
3190 settings->op[i].aarg1 = aarg1;
3191 settings->op[i].aarg2 = aarg2;
3193 if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP)
3194 settings->op[i].dst = tempreg;
3196 settings->op[i].dst = resultreg;
3199 /* Clear unsupported stages */
3200 for(; i < MAX_TEXTURES; i++) {
3201 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
3204 if (!state->render_states[WINED3D_RS_FOGENABLE])
3206 settings->fog = FOG_OFF;
3208 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
3210 if (use_vs(state) || state->vertex_declaration->position_transformed)
3212 settings->fog = FOG_LINEAR;
3216 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
3218 case WINED3D_FOG_NONE:
3219 case WINED3D_FOG_LINEAR:
3220 settings->fog = FOG_LINEAR;
3222 case WINED3D_FOG_EXP:
3223 settings->fog = FOG_EXP;
3225 case WINED3D_FOG_EXP2:
3226 settings->fog = FOG_EXP2;
3233 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
3235 case WINED3D_FOG_LINEAR:
3236 settings->fog = FOG_LINEAR;
3238 case WINED3D_FOG_EXP:
3239 settings->fog = FOG_EXP;
3241 case WINED3D_FOG_EXP2:
3242 settings->fog = FOG_EXP2;
3246 if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB]
3247 && state->render_states[WINED3D_RS_SRGBWRITEENABLE]
3248 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
3250 settings->sRGB_write = 1;
3252 settings->sRGB_write = 0;
3254 if (device->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
3255 || !state->render_states[WINED3D_RS_CLIPPLANEENABLE])
3257 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3258 * the fixed function vertex pipeline is used(which always supports clipplanes), or
3259 * if no clipplane is enabled
3261 settings->emul_clipplanes = 0;
3263 settings->emul_clipplanes = 1;
3267 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3268 const struct ffp_frag_settings *settings)
3270 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3271 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3274 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3276 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3277 * whereas desc points to an extended structure with implementation specific parts. */
3278 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3280 ERR("Failed to insert ffp frag shader.\n");
3284 /* Activates the texture dimension according to the bound D3D texture. Does
3285 * not care for the colorop or correct gl texture unit (when using nvrc).
3286 * Requires the caller to activate the correct unit. */
3287 /* Context activation is done by the caller (state handler). */
3288 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3292 switch (texture->target)
3295 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3296 checkGLcall("glDisable(GL_TEXTURE_3D)");
3297 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3299 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3300 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3302 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3304 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3305 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3307 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3308 checkGLcall("glEnable(GL_TEXTURE_2D)");
3310 case GL_TEXTURE_RECTANGLE_ARB:
3311 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3312 checkGLcall("glDisable(GL_TEXTURE_2D)");
3313 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3314 checkGLcall("glDisable(GL_TEXTURE_3D)");
3315 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3317 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3318 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3320 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_RECTANGLE_ARB);
3321 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3324 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3326 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3327 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3329 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3331 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3332 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3334 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3335 checkGLcall("glDisable(GL_TEXTURE_2D)");
3336 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D);
3337 checkGLcall("glEnable(GL_TEXTURE_3D)");
3339 case GL_TEXTURE_CUBE_MAP_ARB:
3340 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3341 checkGLcall("glDisable(GL_TEXTURE_2D)");
3342 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3343 checkGLcall("glDisable(GL_TEXTURE_3D)");
3344 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3346 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3347 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3349 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3350 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3356 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3357 checkGLcall("glEnable(GL_TEXTURE_2D)");
3358 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3359 checkGLcall("glDisable(GL_TEXTURE_3D)");
3360 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3362 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3363 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3365 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3367 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3368 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3370 /* Binding textures is done by samplers. A dummy texture will be bound */
3374 /* Context activation is done by the caller (state handler). */
3375 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3377 DWORD sampler = state_id - STATE_SAMPLER(0);
3378 DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
3380 /* No need to enable / disable anything here for unused samplers. The
3381 * tex_colorop handler takes care. Also no action is needed with pixel
3382 * shaders, or if tex_colorop will take care of this business. */
3383 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
3385 if (sampler >= state->lowest_disabled_stage)
3387 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)))
3390 texture_activate_dimensions(state->textures[sampler], context->gl_info);
3393 void *wined3d_rb_alloc(size_t size)
3395 return HeapAlloc(GetProcessHeap(), 0, size);
3398 void *wined3d_rb_realloc(void *ptr, size_t size)
3400 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3403 void wined3d_rb_free(void *ptr)
3405 HeapFree(GetProcessHeap(), 0, ptr);
3408 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3410 const struct ffp_frag_settings *ka = key;
3411 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3413 return memcmp(ka, kb, sizeof(*ka));
3416 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3421 ffp_frag_program_key_compare,
3424 UINT wined3d_log2i(UINT32 x)
3426 static const UINT l[] =
3428 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3429 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3430 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3431 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3432 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3433 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3434 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3435 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3436 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3437 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3438 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3439 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3440 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3441 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3442 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3443 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3447 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3450 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3451 const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
3452 const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
3454 static const struct blit_shader * const blitters[] =
3462 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3464 if (blitters[i]->blit_supported(gl_info, blit_op,
3465 src_rect, src_usage, src_pool, src_format,
3466 dst_rect, dst_usage, dst_pool, dst_format))
3473 void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
3475 const struct wined3d_viewport *vp = &state->viewport;
3477 SetRect(rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
3479 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
3480 IntersectRect(rect, rect, &state->scissor_rect);