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 static const struct wined3d_format_texture_info format_texture_info[] =
560 /* format id internal srgbInternal rtInternal
565 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
566 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
567 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
568 * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
571 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
572 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
573 WINED3DFMT_FLAG_FILTERING,
574 WINED3D_GL_EXT_NONE, NULL},
575 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
576 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 0,
577 WINED3DFMT_FLAG_FILTERING,
578 APPLE_YCBCR_422, NULL},
579 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
580 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
581 WINED3DFMT_FLAG_FILTERING,
582 WINED3D_GL_EXT_NONE, NULL},
583 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
584 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, 0,
585 WINED3DFMT_FLAG_FILTERING,
586 APPLE_YCBCR_422, NULL},
587 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
588 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
589 WINED3DFMT_FLAG_FILTERING,
590 WINED3D_GL_EXT_NONE, NULL},
591 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
592 GL_RGBA, GL_UNSIGNED_BYTE, 0,
593 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
594 | WINED3DFMT_FLAG_COMPRESSED,
595 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
596 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
597 GL_RGBA, GL_UNSIGNED_BYTE, 0,
598 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
599 | WINED3DFMT_FLAG_COMPRESSED,
600 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
601 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
602 GL_RGBA, GL_UNSIGNED_BYTE, 0,
603 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
604 | WINED3DFMT_FLAG_COMPRESSED,
605 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
606 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
607 GL_RGBA, GL_UNSIGNED_BYTE, 0,
608 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
609 | WINED3DFMT_FLAG_COMPRESSED,
610 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
611 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
612 GL_RGBA, GL_UNSIGNED_BYTE, 0,
613 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
614 | WINED3DFMT_FLAG_COMPRESSED,
615 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
617 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
619 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
620 ARB_TEXTURE_FLOAT, NULL},
621 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
623 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
624 ARB_TEXTURE_RG, NULL},
625 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
626 GL_RGB, GL_FLOAT, 12,
627 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
628 ARB_TEXTURE_FLOAT, convert_r32g32_float},
629 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
631 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
632 ARB_TEXTURE_RG, NULL},
633 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
634 GL_RGBA, GL_FLOAT, 0,
635 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
636 ARB_TEXTURE_FLOAT, NULL},
638 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
639 GL_RED, GL_HALF_FLOAT_ARB, 0,
640 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
641 ARB_TEXTURE_FLOAT, NULL},
642 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
643 GL_RED, GL_HALF_FLOAT_ARB, 0,
644 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
645 ARB_TEXTURE_RG, NULL},
646 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
647 GL_RGB, GL_HALF_FLOAT_ARB, 6,
648 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
649 ARB_TEXTURE_FLOAT, convert_r16g16},
650 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
651 GL_RG, GL_HALF_FLOAT_ARB, 0,
652 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
653 ARB_TEXTURE_RG, NULL},
654 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
655 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
656 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
657 ARB_TEXTURE_FLOAT, NULL},
658 /* Palettized formats */
659 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
660 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
662 ARB_FRAGMENT_PROGRAM, NULL},
663 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
664 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
666 EXT_PALETTED_TEXTURE, NULL},
667 /* Standard ARGB formats */
668 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
669 GL_BGR, GL_UNSIGNED_BYTE, 0,
670 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
671 WINED3D_GL_EXT_NONE, NULL},
672 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
673 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
674 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
675 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE | WINED3DFMT_FLAG_VTF,
676 WINED3D_GL_EXT_NONE, NULL},
677 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
678 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
679 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
680 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
681 WINED3D_GL_EXT_NONE, NULL},
682 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
683 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
684 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
685 WINED3D_GL_EXT_NONE, NULL},
686 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
687 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
688 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
689 WINED3D_GL_EXT_NONE, NULL},
690 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
691 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
692 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
693 WINED3D_GL_EXT_NONE, NULL},
694 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
695 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
696 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
697 WINED3D_GL_EXT_NONE, NULL},
698 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
699 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
700 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
701 WINED3D_GL_EXT_NONE, NULL},
702 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
703 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
704 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
705 WINED3D_GL_EXT_NONE, NULL},
706 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
707 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
708 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
709 WINED3D_GL_EXT_NONE, NULL},
710 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
711 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
712 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
713 WINED3D_GL_EXT_NONE, NULL},
714 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
715 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
716 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
717 WINED3D_GL_EXT_NONE, NULL},
718 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
719 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
720 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
721 WINED3D_GL_EXT_NONE, NULL},
722 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
723 GL_RGB, GL_UNSIGNED_SHORT, 6,
724 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
725 WINED3D_GL_EXT_NONE, convert_r16g16},
726 {WINED3DFMT_R16G16_UNORM, GL_RG16, GL_RG16, 0,
727 GL_RG, GL_UNSIGNED_SHORT, 0,
728 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
729 ARB_TEXTURE_RG, NULL},
730 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
731 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
732 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
733 WINED3D_GL_EXT_NONE, NULL},
734 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
735 GL_RGBA, GL_UNSIGNED_SHORT, 0,
736 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
737 WINED3D_GL_EXT_NONE, NULL},
739 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
740 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
741 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
742 WINED3D_GL_EXT_NONE, NULL},
743 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
744 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
745 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
746 WINED3D_GL_EXT_NONE, NULL},
747 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
748 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
749 WINED3DFMT_FLAG_FILTERING,
750 WINED3D_GL_EXT_NONE, convert_l4a4_unorm},
751 /* Bump mapping stuff */
752 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
753 GL_BGR, GL_UNSIGNED_BYTE, 3,
754 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
755 WINED3D_GL_EXT_NONE, convert_r8g8_snorm},
756 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
757 GL_DSDT_NV, GL_BYTE, 0,
758 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
759 NV_TEXTURE_SHADER, NULL},
760 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
761 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
762 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
763 WINED3D_GL_EXT_NONE, convert_r5g5_snorm_l6_unorm},
764 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
765 GL_DSDT_MAG_NV, GL_BYTE, 3,
766 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
767 NV_TEXTURE_SHADER, convert_r5g5_snorm_l6_unorm_nv},
768 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
769 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
770 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
771 WINED3D_GL_EXT_NONE, convert_r8g8_snorm_l8x8_unorm},
772 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
773 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
774 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
775 NV_TEXTURE_SHADER, convert_r8g8_snorm_l8x8_unorm_nv},
776 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
777 GL_BGRA, GL_UNSIGNED_BYTE, 4,
778 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
779 WINED3D_GL_EXT_NONE, convert_r8g8b8a8_snorm},
780 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
782 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
783 NV_TEXTURE_SHADER, NULL},
784 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
785 GL_BGR, GL_UNSIGNED_SHORT, 6,
786 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
787 WINED3D_GL_EXT_NONE, convert_r16g16_snorm},
788 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
789 GL_HILO_NV, GL_SHORT, 0,
790 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
791 NV_TEXTURE_SHADER, NULL},
792 /* Depth stencil formats */
793 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
794 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
795 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
796 ARB_DEPTH_TEXTURE, NULL},
797 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
798 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
799 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
800 ARB_DEPTH_TEXTURE, NULL},
801 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
802 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
803 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
804 ARB_DEPTH_TEXTURE, NULL},
805 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
806 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
807 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
808 EXT_PACKED_DEPTH_STENCIL, convert_s1_uint_d15_unorm},
809 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
810 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
811 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
812 ARB_FRAMEBUFFER_OBJECT, convert_s1_uint_d15_unorm},
813 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
814 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
815 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
816 | WINED3DFMT_FLAG_SHADOW,
817 ARB_DEPTH_TEXTURE, NULL},
818 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
819 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
820 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
821 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
822 EXT_PACKED_DEPTH_STENCIL, NULL},
823 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
824 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
825 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
826 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
827 ARB_FRAMEBUFFER_OBJECT, NULL},
828 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
829 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
830 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
831 | WINED3DFMT_FLAG_SHADOW,
832 ARB_DEPTH_TEXTURE, NULL},
833 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
834 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
835 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
836 ARB_DEPTH_TEXTURE, NULL},
837 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
838 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
839 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
840 EXT_PACKED_DEPTH_STENCIL, convert_s4x4_uint_d24_unorm},
841 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
842 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
843 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
844 ARB_FRAMEBUFFER_OBJECT, convert_s4x4_uint_d24_unorm},
845 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
846 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
847 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
848 | WINED3DFMT_FLAG_SHADOW,
849 ARB_DEPTH_TEXTURE, NULL},
850 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
851 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
852 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
853 WINED3D_GL_EXT_NONE, NULL},
854 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
855 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
856 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
857 ARB_DEPTH_BUFFER_FLOAT, NULL},
858 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
859 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
860 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
861 ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float},
862 /* Vendor-specific formats */
863 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
864 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
865 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_COMPRESSED,
866 ATI_TEXTURE_COMPRESSION_3DC, NULL},
867 {WINED3DFMT_ATI2N, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0,
868 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
869 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_COMPRESSED,
870 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
871 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
872 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
873 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
874 | WINED3DFMT_FLAG_STENCIL,
875 EXT_PACKED_DEPTH_STENCIL, NULL},
876 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
877 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
878 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
879 | WINED3DFMT_FLAG_STENCIL,
880 ARB_FRAMEBUFFER_OBJECT, NULL},
881 {WINED3DFMT_NULL, GL_RGBA8, GL_RGBA8, 0,
882 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
883 WINED3DFMT_FLAG_RENDERTARGET,
884 ARB_FRAMEBUFFER_OBJECT, NULL},
887 static inline int getFmtIdx(enum wined3d_format_id format_id)
889 /* First check if the format is at the position of its value.
890 * This will catch the argb formats before the loop is entered. */
891 if (format_id < (sizeof(formats) / sizeof(*formats))
892 && formats[format_id].id == format_id)
900 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
902 if (formats[i].id == format_id) return i;
908 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
910 UINT format_count = sizeof(formats) / sizeof(*formats);
913 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
914 if (!gl_info->formats)
916 ERR("Failed to allocate memory.\n");
920 for (i = 0; i < format_count; ++i)
922 struct wined3d_format *format = &gl_info->formats[i];
923 format->id = formats[i].id;
924 format->red_size = formats[i].red_size;
925 format->green_size = formats[i].green_size;
926 format->blue_size = formats[i].blue_size;
927 format->alpha_size = formats[i].alpha_size;
928 format->red_offset = formats[i].red_offset;
929 format->green_offset = formats[i].green_offset;
930 format->blue_offset = formats[i].blue_offset;
931 format->alpha_offset = formats[i].alpha_offset;
932 format->byte_count = formats[i].bpp;
933 format->depth_size = formats[i].depth_size;
934 format->stencil_size = formats[i].stencil_size;
935 format->block_width = 1;
936 format->block_height = 1;
937 format->block_byte_count = formats[i].bpp;
940 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
942 int fmt_idx = getFmtIdx(format_base_flags[i].id);
946 ERR("Format %s (%#x) not found.\n",
947 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
948 HeapFree(GetProcessHeap(), 0, gl_info->formats);
952 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
958 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
962 for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i)
964 struct wined3d_format *format;
965 int fmt_idx = getFmtIdx(format_block_info[i].id);
969 ERR("Format %s (%#x) not found.\n",
970 debug_d3dformat(format_block_info[i].id), format_block_info[i].id);
974 format = &gl_info->formats[fmt_idx];
975 format->block_width = format_block_info[i].block_width;
976 format->block_height = format_block_info[i].block_height;
977 format->block_byte_count = format_block_info[i].block_byte_count;
978 format->flags |= WINED3DFMT_FLAG_BLOCKS;
984 /* Context activation is done by the caller. */
985 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
987 /* Check if the default internal format is supported as a frame buffer
988 * target, otherwise fall back to the render target internal.
990 * Try to stick to the standard format if possible, this limits precision differences. */
994 while (gl_info->gl_ops.gl.p_glGetError());
995 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
997 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
998 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1000 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0,
1001 format->glFormat, format->glType, NULL);
1002 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1003 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1005 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1007 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1008 checkGLcall("Framebuffer format check");
1010 if (status == GL_FRAMEBUFFER_COMPLETE)
1012 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1013 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1014 format->rtInternal = format->glInternal;
1018 if (!format->rtInternal)
1020 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1022 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1023 " and no fallback specified.\n", debug_d3dformat(format->id));
1024 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1028 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1030 format->rtInternal = format->glInternal;
1034 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1035 debug_d3dformat(format->id));
1037 while (gl_info->gl_ops.gl.p_glGetError());
1039 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1041 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0,
1042 format->glFormat, format->glType, NULL);
1043 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1044 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1046 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1048 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1049 checkGLcall("Framebuffer format check");
1051 if (status == GL_FRAMEBUFFER_COMPLETE)
1053 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1054 debug_d3dformat(format->id));
1058 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1059 debug_d3dformat(format->id));
1060 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1065 if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1066 || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1067 && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
1068 && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA
1069 && (format->red_size || format->alpha_size))
1072 DWORD readback[16 * 16], color, r_range, a_range;
1076 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1077 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1079 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1080 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1081 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1082 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1083 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1084 checkGLcall("RB attachment");
1087 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1088 gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1089 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1090 if (gl_info->gl_ops.gl.p_glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1092 while (gl_info->gl_ops.gl.p_glGetError());
1093 TRACE("Format doesn't support post-pixelshader blending.\n");
1094 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1098 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1099 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16);
1100 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1101 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1102 gl_info->gl_ops.gl.p_glLoadIdentity();
1103 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1104 gl_info->gl_ops.gl.p_glLoadIdentity();
1106 gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1108 /* Draw a full-black quad */
1109 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1110 gl_info->gl_ops.gl.p_glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
1111 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1112 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1113 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1114 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1115 gl_info->gl_ops.gl.p_glEnd();
1117 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1118 /* Draw a half-transparent red quad */
1119 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1120 gl_info->gl_ops.gl.p_glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
1121 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1122 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1123 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1124 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1125 gl_info->gl_ops.gl.p_glEnd();
1127 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1128 gl_info->gl_ops.gl.p_glGenTextures(1, &tex2);
1129 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex2);
1131 gl_info->gl_ops.gl.p_glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, 16, 16, 0);
1132 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1133 checkGLcall("Post-pixelshader blending check");
1135 color = readback[7 * 16 + 7];
1137 r = (color & 0x00ff0000) >> 16;
1139 r_range = format->red_size < 8 ? 1 << (8 - format->red_size) : 1;
1140 a_range = format->alpha_size < 8 ? 1 << (8 - format->alpha_size) : 1;
1141 if (format->red_size && (r < 0x7f - r_range || r > 0x7f + r_range))
1143 else if (format->alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range))
1147 TRACE("Format doesn't support post-pixelshader blending.\n");
1148 TRACE("Color output: %#x\n", color);
1149 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1153 TRACE("Format supports post-pixelshader blending.\n");
1154 TRACE("Color output: %#x\n", color);
1155 format->flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1158 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1159 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex2);
1162 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1163 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1165 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1166 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1167 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1168 checkGLcall("RB cleanup");
1172 if (format->glInternal != format->glGammaInternal)
1174 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0,
1175 format->glFormat, format->glType, NULL);
1176 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1178 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1179 checkGLcall("Framebuffer format check");
1181 if (status == GL_FRAMEBUFFER_COMPLETE)
1183 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1184 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1188 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1191 else if (status == GL_FRAMEBUFFER_COMPLETE)
1192 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1194 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1197 /* Context activation is done by the caller. */
1198 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1203 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1205 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1206 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1207 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1208 gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0);
1211 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1213 struct wined3d_format *format = &gl_info->formats[i];
1215 if (!format->glInternal) continue;
1217 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1219 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1220 debug_d3dformat(format->id));
1224 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1226 TRACE("Skipping format %s because it's a compressed format.\n",
1227 debug_d3dformat(format->id));
1231 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1233 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1234 check_fbo_compat(gl_info, format);
1238 format->rtInternal = format->glInternal;
1242 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1243 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1246 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1250 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1252 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1253 struct wined3d_format *format;
1257 ERR("Format %s (%#x) not found.\n",
1258 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1262 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1264 format = &gl_info->formats[fmt_idx];
1266 /* ARB_texture_rg defines floating point formats, but only if
1267 * ARB_texture_float is also supported. */
1268 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1269 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1272 format->glInternal = format_texture_info[i].gl_internal;
1273 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1274 format->rtInternal = format_texture_info[i].gl_rt_internal;
1275 format->glFormat = format_texture_info[i].gl_format;
1276 format->glType = format_texture_info[i].gl_type;
1277 format->color_fixup = COLOR_FIXUP_IDENTITY;
1278 format->flags |= format_texture_info[i].flags;
1279 format->height_scale.numerator = 1;
1280 format->height_scale.denominator = 1;
1282 if (format->glGammaInternal != format->glInternal)
1284 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1285 if (!gl_info->supported[EXT_TEXTURE_SRGB])
1287 format->glGammaInternal = format->glInternal;
1288 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1290 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1292 format->glInternal = format->glGammaInternal;
1296 /* Texture conversion stuff */
1297 format->convert = format_texture_info[i].convert;
1298 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1304 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1306 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1308 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1310 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1312 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1316 /* A context is provided by the caller */
1317 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1319 static const DWORD data[] = {0x00000000, 0xffffffff};
1320 GLuint tex, fbo, buffer;
1321 DWORD readback[16 * 1];
1324 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1325 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1326 * falling back to software. If this changes in the future this code will get fooled and
1327 * apps might hit the software path due to incorrectly advertised caps.
1329 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1330 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1331 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1334 while (gl_info->gl_ops.gl.p_glGetError());
1336 gl_info->gl_ops.gl.p_glGenTextures(1, &buffer);
1337 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1338 memset(readback, 0x7e, sizeof(readback));
1339 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0,
1340 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1341 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1342 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1343 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1344 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1345 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1347 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1348 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1349 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0,
1350 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1351 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1352 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1353 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1354 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1355 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1356 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
1358 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1359 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1360 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1361 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1363 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1);
1364 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1365 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1366 gl_info->gl_ops.gl.p_glLoadIdentity();
1367 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1368 gl_info->gl_ops.gl.p_glLoadIdentity();
1370 gl_info->gl_ops.gl.p_glClearColor(0, 1, 0, 0);
1371 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1373 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1374 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 0.0);
1375 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, -1.0f);
1376 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 0.0);
1377 gl_info->gl_ops.gl.p_glVertex2f(1.0f, -1.0f);
1378 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 1.0);
1379 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, 1.0f);
1380 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 1.0);
1381 gl_info->gl_ops.gl.p_glVertex2f(1.0f, 1.0f);
1382 gl_info->gl_ops.gl.p_glEnd();
1384 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1385 memset(readback, 0x7f, sizeof(readback));
1386 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1387 if (color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5)
1388 || color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1390 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, assuming no filtering\n",
1391 readback[6], readback[9]);
1396 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1397 readback[6], readback[9]);
1401 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1402 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1403 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1404 gl_info->gl_ops.gl.p_glDeleteTextures(1, &buffer);
1406 if (gl_info->gl_ops.gl.p_glGetError())
1408 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1415 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1417 struct wined3d_format *format;
1418 unsigned int fmt_idx, i;
1419 static const enum wined3d_format_id fmts16[] =
1421 WINED3DFMT_R16_FLOAT,
1422 WINED3DFMT_R16G16_FLOAT,
1423 WINED3DFMT_R16G16B16A16_FLOAT,
1427 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1429 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1430 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1432 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1435 else if (gl_info->limits.glsl_varyings > 44)
1437 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1442 TRACE("Assuming no float16 blending\n");
1448 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1450 fmt_idx = getFmtIdx(fmts16[i]);
1451 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1457 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1459 fmt_idx = getFmtIdx(fmts16[i]);
1460 format = &gl_info->formats[fmt_idx];
1461 if (!format->glInternal) continue; /* Not supported by GL */
1463 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1466 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1467 format->flags |= WINED3DFMT_FLAG_FILTERING;
1471 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1476 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1480 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1481 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1482 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1484 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1485 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1486 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1488 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1489 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1490 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1492 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1493 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1494 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1496 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1497 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1498 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1500 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1501 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1502 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1503 * the only driver that implements it(fglrx) has a buggy implementation.
1505 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1506 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1507 * conversion for this format.
1509 if (!gl_info->supported[NV_TEXTURE_SHADER])
1511 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1512 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1513 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1514 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1515 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1516 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1520 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1521 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1522 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1524 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1525 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1526 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1529 if (!gl_info->supported[NV_TEXTURE_SHADER])
1531 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1534 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1535 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1536 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1537 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1538 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1539 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1540 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1541 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1542 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1546 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1547 * are converted at surface loading time, but they do not need any modification in
1548 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1549 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1553 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1555 idx = getFmtIdx(WINED3DFMT_ATI2N);
1556 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1557 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1559 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1561 idx = getFmtIdx(WINED3DFMT_ATI2N);
1562 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1563 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1566 if (!gl_info->supported[APPLE_YCBCR_422])
1568 idx = getFmtIdx(WINED3DFMT_YUY2);
1569 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1571 idx = getFmtIdx(WINED3DFMT_UYVY);
1572 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1575 idx = getFmtIdx(WINED3DFMT_YV12);
1576 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
1577 gl_info->formats[idx].height_scale.numerator = 3;
1578 gl_info->formats[idx].height_scale.denominator = 2;
1579 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1581 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1583 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1584 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1587 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1589 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1590 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1593 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1595 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1596 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1597 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1598 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1600 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1601 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1605 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1609 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1611 struct wined3d_format *format;
1612 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1616 ERR("Format %s (%#x) not found.\n",
1617 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1621 format = &gl_info->formats[fmt_idx];
1622 format->emit_idx = format_vertex_info[i].emit_idx;
1623 format->component_count = format_vertex_info[i].component_count;
1624 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1625 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1626 format->gl_normalized = format_vertex_info[i].gl_normalized;
1627 format->component_size = format_vertex_info[i].component_size;
1633 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1635 if (!init_format_base_info(gl_info)) return FALSE;
1637 if (!init_format_block_info(gl_info))
1639 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1640 gl_info->formats = NULL;
1647 /* Context activation is done by the caller. */
1648 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1650 if (!init_format_base_info(gl_info)) return FALSE;
1652 if (!init_format_block_info(gl_info)) goto fail;
1653 if (!init_format_texture_info(gl_info)) goto fail;
1654 if (!init_format_vertex_info(gl_info)) goto fail;
1656 apply_format_fixups(gl_info);
1657 init_format_fbo_compat_info(gl_info);
1658 init_format_filter_info(gl_info, vendor);
1663 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1664 gl_info->formats = NULL;
1668 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1669 enum wined3d_format_id format_id)
1671 int idx = getFmtIdx(format_id);
1675 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1676 debug_d3dformat(format_id), format_id);
1677 /* Get the caller a valid pointer */
1678 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1681 return &gl_info->formats[idx];
1684 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1688 if (format->id == WINED3DFMT_UNKNOWN)
1692 else if (format->flags & WINED3DFMT_FLAG_BLOCKS)
1694 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1695 UINT row_count = (height + format->block_height - 1) / format->block_height;
1696 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1700 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1703 if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
1705 /* The D3D format requirements make sure that the resulting format is an integer again */
1706 size *= format->height_scale.numerator;
1707 size /= format->height_scale.denominator;
1713 /*****************************************************************************
1714 * Trace formatting of useful values
1716 const char *debug_d3dformat(enum wined3d_format_id format_id)
1720 #define FMT_TO_STR(format_id) case format_id: return #format_id
1721 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1722 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1723 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1724 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1725 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1726 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1727 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1728 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1729 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1730 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1731 FMT_TO_STR(WINED3DFMT_P8_UINT);
1732 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1733 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1734 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1735 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1736 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1737 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1738 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1739 FMT_TO_STR(WINED3DFMT_UYVY);
1740 FMT_TO_STR(WINED3DFMT_YUY2);
1741 FMT_TO_STR(WINED3DFMT_YV12);
1742 FMT_TO_STR(WINED3DFMT_DXT1);
1743 FMT_TO_STR(WINED3DFMT_DXT2);
1744 FMT_TO_STR(WINED3DFMT_DXT3);
1745 FMT_TO_STR(WINED3DFMT_DXT4);
1746 FMT_TO_STR(WINED3DFMT_DXT5);
1747 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1748 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1749 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1750 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1751 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1752 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1753 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1754 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1755 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1756 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1757 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1758 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1759 FMT_TO_STR(WINED3DFMT_ATI2N);
1760 FMT_TO_STR(WINED3DFMT_NVDB);
1761 FMT_TO_STR(WINED3DFMT_NVHU);
1762 FMT_TO_STR(WINED3DFMT_NVHS);
1763 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1764 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1765 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1766 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1767 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1768 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1769 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1770 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1771 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1772 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1773 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1774 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1775 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1776 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1777 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1778 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1779 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1780 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1781 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1782 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1783 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1784 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1785 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1786 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1787 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1788 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1789 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1790 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1791 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1792 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1793 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1794 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1795 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1796 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1797 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1798 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1799 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1800 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1801 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1802 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1803 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1804 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1805 FMT_TO_STR(WINED3DFMT_R32_UINT);
1806 FMT_TO_STR(WINED3DFMT_R32_SINT);
1807 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1808 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1809 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1810 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1811 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1812 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1813 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1814 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1815 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1816 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1817 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1818 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1819 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1820 FMT_TO_STR(WINED3DFMT_R16_UINT);
1821 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1822 FMT_TO_STR(WINED3DFMT_R16_SINT);
1823 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1824 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1825 FMT_TO_STR(WINED3DFMT_R8_UINT);
1826 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1827 FMT_TO_STR(WINED3DFMT_R8_SINT);
1828 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1829 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1830 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1831 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1832 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1833 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1834 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1835 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1836 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1837 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1838 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1839 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1840 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1841 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1842 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1843 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1844 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1845 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1846 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1847 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1848 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1849 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1850 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1851 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1852 FMT_TO_STR(WINED3DFMT_INTZ);
1853 FMT_TO_STR(WINED3DFMT_NULL);
1854 FMT_TO_STR(WINED3DFMT_R16);
1855 FMT_TO_STR(WINED3DFMT_AL16);
1860 fourcc[0] = (char)(format_id);
1861 fourcc[1] = (char)(format_id >> 8);
1862 fourcc[2] = (char)(format_id >> 16);
1863 fourcc[3] = (char)(format_id >> 24);
1865 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1866 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1868 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1870 return "unrecognized";
1874 const char *debug_d3ddevicetype(enum wined3d_device_type device_type)
1876 switch (device_type)
1878 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1879 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_HAL);
1880 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_REF);
1881 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_SW);
1882 #undef DEVTYPE_TO_STR
1884 FIXME("Unrecognized device type %#x.\n", device_type);
1885 return "unrecognized";
1889 const char *debug_d3dusage(DWORD usage)
1894 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1895 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1896 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1897 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1898 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1899 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1900 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1901 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1902 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1903 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1904 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1905 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1906 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1907 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1908 #undef WINED3DUSAGE_TO_STR
1909 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1911 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1914 const char *debug_d3dusagequery(DWORD usagequery)
1919 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1920 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1921 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1922 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1923 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1924 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1925 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1926 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1927 #undef WINED3DUSAGEQUERY_TO_STR
1928 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1930 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1933 const char *debug_d3ddeclmethod(enum wined3d_decl_method method)
1937 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1938 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_DEFAULT);
1939 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_U);
1940 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_V);
1941 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_CROSS_UV);
1942 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_UV);
1943 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP);
1944 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP_PRESAMPLED);
1945 #undef WINED3DDECLMETHOD_TO_STR
1947 FIXME("Unrecognized declaration method %#x.\n", method);
1948 return "unrecognized";
1952 const char *debug_d3ddeclusage(enum wined3d_decl_usage usage)
1956 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1957 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITION);
1958 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_WEIGHT);
1959 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_INDICES);
1960 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_NORMAL);
1961 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_PSIZE);
1962 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TEXCOORD);
1963 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TANGENT);
1964 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BINORMAL);
1965 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TESS_FACTOR);
1966 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITIONT);
1967 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_COLOR);
1968 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_FOG);
1969 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_DEPTH);
1970 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_SAMPLE);
1971 #undef WINED3DDECLUSAGE_TO_STR
1973 FIXME("Unrecognized %u declaration usage!\n", usage);
1974 return "unrecognized";
1978 const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
1980 switch (resource_type)
1982 #define RES_TO_STR(res) case res: return #res
1983 RES_TO_STR(WINED3D_RTYPE_SURFACE);
1984 RES_TO_STR(WINED3D_RTYPE_VOLUME);
1985 RES_TO_STR(WINED3D_RTYPE_TEXTURE);
1986 RES_TO_STR(WINED3D_RTYPE_VOLUME_TEXTURE);
1987 RES_TO_STR(WINED3D_RTYPE_CUBE_TEXTURE);
1988 RES_TO_STR(WINED3D_RTYPE_BUFFER);
1991 FIXME("Unrecognized resource type %#x.\n", resource_type);
1992 return "unrecognized";
1996 const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type)
1998 switch (primitive_type)
2000 #define PRIM_TO_STR(prim) case prim: return #prim
2001 PRIM_TO_STR(WINED3D_PT_UNDEFINED);
2002 PRIM_TO_STR(WINED3D_PT_POINTLIST);
2003 PRIM_TO_STR(WINED3D_PT_LINELIST);
2004 PRIM_TO_STR(WINED3D_PT_LINESTRIP);
2005 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST);
2006 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP);
2007 PRIM_TO_STR(WINED3D_PT_TRIANGLEFAN);
2008 PRIM_TO_STR(WINED3D_PT_LINELIST_ADJ);
2009 PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ);
2010 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ);
2011 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ);
2014 FIXME("Unrecognized %u primitive type!\n", primitive_type);
2015 return "unrecognized";
2019 const char *debug_d3drenderstate(enum wined3d_render_state state)
2023 #define D3DSTATE_TO_STR(u) case u: return #u
2024 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIAS);
2025 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREPERSPECTIVE);
2026 D3DSTATE_TO_STR(WINED3D_RS_WRAPU);
2027 D3DSTATE_TO_STR(WINED3D_RS_WRAPV);
2028 D3DSTATE_TO_STR(WINED3D_RS_ZENABLE);
2029 D3DSTATE_TO_STR(WINED3D_RS_FILLMODE);
2030 D3DSTATE_TO_STR(WINED3D_RS_SHADEMODE);
2031 D3DSTATE_TO_STR(WINED3D_RS_LINEPATTERN);
2032 D3DSTATE_TO_STR(WINED3D_RS_MONOENABLE);
2033 D3DSTATE_TO_STR(WINED3D_RS_ROP2);
2034 D3DSTATE_TO_STR(WINED3D_RS_PLANEMASK);
2035 D3DSTATE_TO_STR(WINED3D_RS_ZWRITEENABLE);
2036 D3DSTATE_TO_STR(WINED3D_RS_ALPHATESTENABLE);
2037 D3DSTATE_TO_STR(WINED3D_RS_LASTPIXEL);
2038 D3DSTATE_TO_STR(WINED3D_RS_SRCBLEND);
2039 D3DSTATE_TO_STR(WINED3D_RS_DESTBLEND);
2040 D3DSTATE_TO_STR(WINED3D_RS_CULLMODE);
2041 D3DSTATE_TO_STR(WINED3D_RS_ZFUNC);
2042 D3DSTATE_TO_STR(WINED3D_RS_ALPHAREF);
2043 D3DSTATE_TO_STR(WINED3D_RS_ALPHAFUNC);
2044 D3DSTATE_TO_STR(WINED3D_RS_DITHERENABLE);
2045 D3DSTATE_TO_STR(WINED3D_RS_ALPHABLENDENABLE);
2046 D3DSTATE_TO_STR(WINED3D_RS_FOGENABLE);
2047 D3DSTATE_TO_STR(WINED3D_RS_SPECULARENABLE);
2048 D3DSTATE_TO_STR(WINED3D_RS_ZVISIBLE);
2049 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXEL);
2050 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXELX);
2051 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEDALPHA);
2052 D3DSTATE_TO_STR(WINED3D_RS_FOGCOLOR);
2053 D3DSTATE_TO_STR(WINED3D_RS_FOGTABLEMODE);
2054 D3DSTATE_TO_STR(WINED3D_RS_FOGSTART);
2055 D3DSTATE_TO_STR(WINED3D_RS_FOGEND);
2056 D3DSTATE_TO_STR(WINED3D_RS_FOGDENSITY);
2057 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEENABLE);
2058 D3DSTATE_TO_STR(WINED3D_RS_EDGEANTIALIAS);
2059 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYENABLE);
2060 D3DSTATE_TO_STR(WINED3D_RS_MIPMAPLODBIAS);
2061 D3DSTATE_TO_STR(WINED3D_RS_RANGEFOGENABLE);
2062 D3DSTATE_TO_STR(WINED3D_RS_ANISOTROPY);
2063 D3DSTATE_TO_STR(WINED3D_RS_FLUSHBATCH);
2064 D3DSTATE_TO_STR(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT);
2065 D3DSTATE_TO_STR(WINED3D_RS_STENCILENABLE);
2066 D3DSTATE_TO_STR(WINED3D_RS_STENCILFAIL);
2067 D3DSTATE_TO_STR(WINED3D_RS_STENCILZFAIL);
2068 D3DSTATE_TO_STR(WINED3D_RS_STENCILPASS);
2069 D3DSTATE_TO_STR(WINED3D_RS_STENCILFUNC);
2070 D3DSTATE_TO_STR(WINED3D_RS_STENCILREF);
2071 D3DSTATE_TO_STR(WINED3D_RS_STENCILMASK);
2072 D3DSTATE_TO_STR(WINED3D_RS_STENCILWRITEMASK);
2073 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREFACTOR);
2074 D3DSTATE_TO_STR(WINED3D_RS_WRAP0);
2075 D3DSTATE_TO_STR(WINED3D_RS_WRAP1);
2076 D3DSTATE_TO_STR(WINED3D_RS_WRAP2);
2077 D3DSTATE_TO_STR(WINED3D_RS_WRAP3);
2078 D3DSTATE_TO_STR(WINED3D_RS_WRAP4);
2079 D3DSTATE_TO_STR(WINED3D_RS_WRAP5);
2080 D3DSTATE_TO_STR(WINED3D_RS_WRAP6);
2081 D3DSTATE_TO_STR(WINED3D_RS_WRAP7);
2082 D3DSTATE_TO_STR(WINED3D_RS_CLIPPING);
2083 D3DSTATE_TO_STR(WINED3D_RS_LIGHTING);
2084 D3DSTATE_TO_STR(WINED3D_RS_EXTENTS);
2085 D3DSTATE_TO_STR(WINED3D_RS_AMBIENT);
2086 D3DSTATE_TO_STR(WINED3D_RS_FOGVERTEXMODE);
2087 D3DSTATE_TO_STR(WINED3D_RS_COLORVERTEX);
2088 D3DSTATE_TO_STR(WINED3D_RS_LOCALVIEWER);
2089 D3DSTATE_TO_STR(WINED3D_RS_NORMALIZENORMALS);
2090 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYBLENDENABLE);
2091 D3DSTATE_TO_STR(WINED3D_RS_DIFFUSEMATERIALSOURCE);
2092 D3DSTATE_TO_STR(WINED3D_RS_SPECULARMATERIALSOURCE);
2093 D3DSTATE_TO_STR(WINED3D_RS_AMBIENTMATERIALSOURCE);
2094 D3DSTATE_TO_STR(WINED3D_RS_EMISSIVEMATERIALSOURCE);
2095 D3DSTATE_TO_STR(WINED3D_RS_VERTEXBLEND);
2096 D3DSTATE_TO_STR(WINED3D_RS_CLIPPLANEENABLE);
2097 D3DSTATE_TO_STR(WINED3D_RS_SOFTWAREVERTEXPROCESSING);
2098 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE);
2099 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MIN);
2100 D3DSTATE_TO_STR(WINED3D_RS_POINTSPRITEENABLE);
2101 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALEENABLE);
2102 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_A);
2103 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_B);
2104 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_C);
2105 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEANTIALIAS);
2106 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEMASK);
2107 D3DSTATE_TO_STR(WINED3D_RS_PATCHEDGESTYLE);
2108 D3DSTATE_TO_STR(WINED3D_RS_PATCHSEGMENTS);
2109 D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN);
2110 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX);
2111 D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE);
2112 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
2113 D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR);
2114 D3DSTATE_TO_STR(WINED3D_RS_BLENDOP);
2115 D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE);
2116 D3DSTATE_TO_STR(WINED3D_RS_NORMALDEGREE);
2117 D3DSTATE_TO_STR(WINED3D_RS_SCISSORTESTENABLE);
2118 D3DSTATE_TO_STR(WINED3D_RS_SLOPESCALEDEPTHBIAS);
2119 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIASEDLINEENABLE);
2120 D3DSTATE_TO_STR(WINED3D_RS_MINTESSELLATIONLEVEL);
2121 D3DSTATE_TO_STR(WINED3D_RS_MAXTESSELLATIONLEVEL);
2122 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_X);
2123 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Y);
2124 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Z);
2125 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_W);
2126 D3DSTATE_TO_STR(WINED3D_RS_ENABLEADAPTIVETESSELLATION);
2127 D3DSTATE_TO_STR(WINED3D_RS_TWOSIDEDSTENCILMODE);
2128 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFAIL);
2129 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILZFAIL);
2130 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILPASS);
2131 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFUNC);
2132 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1);
2133 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2);
2134 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3);
2135 D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR);
2136 D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE);
2137 D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS);
2138 D3DSTATE_TO_STR(WINED3D_RS_WRAP8);
2139 D3DSTATE_TO_STR(WINED3D_RS_WRAP9);
2140 D3DSTATE_TO_STR(WINED3D_RS_WRAP10);
2141 D3DSTATE_TO_STR(WINED3D_RS_WRAP11);
2142 D3DSTATE_TO_STR(WINED3D_RS_WRAP12);
2143 D3DSTATE_TO_STR(WINED3D_RS_WRAP13);
2144 D3DSTATE_TO_STR(WINED3D_RS_WRAP14);
2145 D3DSTATE_TO_STR(WINED3D_RS_WRAP15);
2146 D3DSTATE_TO_STR(WINED3D_RS_SEPARATEALPHABLENDENABLE);
2147 D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
2148 D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
2149 D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
2150 #undef D3DSTATE_TO_STR
2152 FIXME("Unrecognized %u render state!\n", state);
2153 return "unrecognized";
2157 const char *debug_d3dsamplerstate(enum wined3d_sampler_state state)
2161 #define D3DSTATE_TO_STR(u) case u: return #u
2162 D3DSTATE_TO_STR(WINED3D_SAMP_BORDER_COLOR);
2163 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_U);
2164 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_V);
2165 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_W);
2166 D3DSTATE_TO_STR(WINED3D_SAMP_MAG_FILTER);
2167 D3DSTATE_TO_STR(WINED3D_SAMP_MIN_FILTER);
2168 D3DSTATE_TO_STR(WINED3D_SAMP_MIP_FILTER);
2169 D3DSTATE_TO_STR(WINED3D_SAMP_MIPMAP_LOD_BIAS);
2170 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_MIP_LEVEL);
2171 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_ANISOTROPY);
2172 D3DSTATE_TO_STR(WINED3D_SAMP_SRGB_TEXTURE);
2173 D3DSTATE_TO_STR(WINED3D_SAMP_ELEMENT_INDEX);
2174 D3DSTATE_TO_STR(WINED3D_SAMP_DMAP_OFFSET);
2175 #undef D3DSTATE_TO_STR
2177 FIXME("Unrecognized %u sampler state!\n", state);
2178 return "unrecognized";
2182 const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type)
2184 switch (filter_type)
2186 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2187 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_NONE);
2188 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_POINT);
2189 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_LINEAR);
2190 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_ANISOTROPIC);
2191 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_FLAT_CUBIC);
2192 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_CUBIC);
2193 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_PYRAMIDAL_QUAD);
2194 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_QUAD);
2195 #undef D3DTEXTUREFILTERTYPE_TO_STR
2197 FIXME("Unrecognied texture filter type 0x%08x.\n", filter_type);
2198 return "unrecognized";
2202 const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state)
2206 #define D3DSTATE_TO_STR(u) case u: return #u
2207 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_OP);
2208 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG1);
2209 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG2);
2210 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_OP);
2211 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG1);
2212 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG2);
2213 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT00);
2214 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT01);
2215 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT10);
2216 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT11);
2217 D3DSTATE_TO_STR(WINED3D_TSS_TEXCOORD_INDEX);
2218 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LSCALE);
2219 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LOFFSET);
2220 D3DSTATE_TO_STR(WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS);
2221 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG0);
2222 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG0);
2223 D3DSTATE_TO_STR(WINED3D_TSS_RESULT_ARG);
2224 D3DSTATE_TO_STR(WINED3D_TSS_CONSTANT);
2225 #undef D3DSTATE_TO_STR
2227 FIXME("Unrecognized %u texture state!\n", state);
2228 return "unrecognized";
2232 const char *debug_d3dtop(enum wined3d_texture_op d3dtop)
2236 #define D3DTOP_TO_STR(u) case u: return #u
2237 D3DTOP_TO_STR(WINED3D_TOP_DISABLE);
2238 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG1);
2239 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG2);
2240 D3DTOP_TO_STR(WINED3D_TOP_MODULATE);
2241 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_2X);
2242 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_4X);
2243 D3DTOP_TO_STR(WINED3D_TOP_ADD);
2244 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED);
2245 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED_2X);
2246 D3DTOP_TO_STR(WINED3D_TOP_SUBTRACT);
2247 D3DTOP_TO_STR(WINED3D_TOP_ADD_SMOOTH);
2248 D3DTOP_TO_STR(WINED3D_TOP_BLEND_DIFFUSE_ALPHA);
2249 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA);
2250 D3DTOP_TO_STR(WINED3D_TOP_BLEND_FACTOR_ALPHA);
2251 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM);
2252 D3DTOP_TO_STR(WINED3D_TOP_BLEND_CURRENT_ALPHA);
2253 D3DTOP_TO_STR(WINED3D_TOP_PREMODULATE);
2254 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR);
2255 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA);
2256 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR);
2257 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA);
2258 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP);
2259 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP_LUMINANCE);
2260 D3DTOP_TO_STR(WINED3D_TOP_DOTPRODUCT3);
2261 D3DTOP_TO_STR(WINED3D_TOP_MULTIPLY_ADD);
2262 D3DTOP_TO_STR(WINED3D_TOP_LERP);
2263 #undef D3DTOP_TO_STR
2265 FIXME("Unrecognized texture op %#x.\n", d3dtop);
2266 return "unrecognized";
2270 const char *debug_d3dtstype(enum wined3d_transform_state tstype)
2274 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2275 TSTYPE_TO_STR(WINED3D_TS_VIEW);
2276 TSTYPE_TO_STR(WINED3D_TS_PROJECTION);
2277 TSTYPE_TO_STR(WINED3D_TS_TEXTURE0);
2278 TSTYPE_TO_STR(WINED3D_TS_TEXTURE1);
2279 TSTYPE_TO_STR(WINED3D_TS_TEXTURE2);
2280 TSTYPE_TO_STR(WINED3D_TS_TEXTURE3);
2281 TSTYPE_TO_STR(WINED3D_TS_TEXTURE4);
2282 TSTYPE_TO_STR(WINED3D_TS_TEXTURE5);
2283 TSTYPE_TO_STR(WINED3D_TS_TEXTURE6);
2284 TSTYPE_TO_STR(WINED3D_TS_TEXTURE7);
2285 TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(0));
2286 #undef TSTYPE_TO_STR
2288 if (tstype > 256 && tstype < 512)
2290 FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype);
2291 return ("WINED3D_TS_WORLD_MATRIX > 0");
2293 FIXME("Unrecognized transform state %#x.\n", tstype);
2294 return "unrecognized";
2298 const char *debug_d3dstate(DWORD state)
2300 if (STATE_IS_RENDER(state))
2301 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2302 if (STATE_IS_TEXTURESTAGE(state))
2304 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2305 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2306 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2307 texture_stage, debug_d3dtexturestate(texture_state));
2309 if (STATE_IS_SAMPLER(state))
2310 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2311 if (STATE_IS_PIXELSHADER(state))
2312 return "STATE_PIXELSHADER";
2313 if (STATE_IS_TRANSFORM(state))
2314 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2315 if (STATE_IS_STREAMSRC(state))
2316 return "STATE_STREAMSRC";
2317 if (STATE_IS_INDEXBUFFER(state))
2318 return "STATE_INDEXBUFFER";
2319 if (STATE_IS_VDECL(state))
2320 return "STATE_VDECL";
2321 if (STATE_IS_VSHADER(state))
2322 return "STATE_VSHADER";
2323 if (STATE_IS_GEOMETRY_SHADER(state))
2324 return "STATE_GEOMETRY_SHADER";
2325 if (STATE_IS_VIEWPORT(state))
2326 return "STATE_VIEWPORT";
2327 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2328 return "STATE_VERTEXSHADERCONSTANT";
2329 if (STATE_IS_PIXELSHADERCONSTANT(state))
2330 return "STATE_PIXELSHADERCONSTANT";
2331 if (STATE_IS_ACTIVELIGHT(state))
2332 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2333 if (STATE_IS_SCISSORRECT(state))
2334 return "STATE_SCISSORRECT";
2335 if (STATE_IS_CLIPPLANE(state))
2336 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2337 if (STATE_IS_MATERIAL(state))
2338 return "STATE_MATERIAL";
2339 if (STATE_IS_FRONTFACE(state))
2340 return "STATE_FRONTFACE";
2341 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2342 return "STATE_POINTSPRITECOORDORIGIN";
2343 if (STATE_IS_BASEVERTEXINDEX(state))
2344 return "STATE_BASEVERTEXINDEX";
2345 if (STATE_IS_FRAMEBUFFER(state))
2346 return "STATE_FRAMEBUFFER";
2348 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2351 const char *debug_d3dpool(enum wined3d_pool pool)
2355 #define POOL_TO_STR(p) case p: return #p
2356 POOL_TO_STR(WINED3D_POOL_DEFAULT);
2357 POOL_TO_STR(WINED3D_POOL_MANAGED);
2358 POOL_TO_STR(WINED3D_POOL_SYSTEM_MEM);
2359 POOL_TO_STR(WINED3D_POOL_SCRATCH);
2362 FIXME("Unrecognized pool %#x.\n", pool);
2363 return "unrecognized";
2367 const char *debug_fbostatus(GLenum status) {
2369 #define FBOSTATUS_TO_STR(u) case u: return #u
2370 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2371 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2372 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2373 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2374 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2375 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2376 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2377 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2378 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2379 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2380 #undef FBOSTATUS_TO_STR
2382 FIXME("Unrecognied FBO status 0x%08x\n", status);
2383 return "unrecognized";
2387 const char *debug_glerror(GLenum error) {
2389 #define GLERROR_TO_STR(u) case u: return #u
2390 GLERROR_TO_STR(GL_NO_ERROR);
2391 GLERROR_TO_STR(GL_INVALID_ENUM);
2392 GLERROR_TO_STR(GL_INVALID_VALUE);
2393 GLERROR_TO_STR(GL_INVALID_OPERATION);
2394 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2395 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2396 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2397 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2398 #undef GLERROR_TO_STR
2400 FIXME("Unrecognied GL error 0x%08x\n", error);
2401 return "unrecognized";
2405 const char *debug_d3dbasis(enum wined3d_basis_type basis)
2409 case WINED3D_BASIS_BEZIER: return "WINED3D_BASIS_BEZIER";
2410 case WINED3D_BASIS_BSPLINE: return "WINED3D_BASIS_BSPLINE";
2411 case WINED3D_BASIS_INTERPOLATE: return "WINED3D_BASIS_INTERPOLATE";
2412 default: return "unrecognized";
2416 const char *debug_d3ddegree(enum wined3d_degree_type degree)
2420 case WINED3D_DEGREE_LINEAR: return "WINED3D_DEGREE_LINEAR";
2421 case WINED3D_DEGREE_QUADRATIC: return "WINED3D_DEGREE_QUADRATIC";
2422 case WINED3D_DEGREE_CUBIC: return "WINED3D_DEGREE_CUBIC";
2423 case WINED3D_DEGREE_QUINTIC: return "WINED3D_DEGREE_QUINTIC";
2424 default: return "unrecognized";
2428 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2432 #define WINED3D_TO_STR(x) case x: return #x
2433 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2434 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2435 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2436 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2437 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2438 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2439 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2440 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2441 #undef WINED3D_TO_STR
2443 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2444 return "unrecognized";
2448 static const char *debug_complex_fixup(enum complex_fixup fixup)
2452 #define WINED3D_TO_STR(x) case x: return #x
2453 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2454 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2455 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2456 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2457 #undef WINED3D_TO_STR
2459 FIXME("Unrecognized complex fixup %#x\n", fixup);
2460 return "unrecognized";
2464 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2466 if (is_complex_fixup(fixup))
2468 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2472 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2473 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2474 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2475 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2478 const char *debug_surflocation(DWORD flag) {
2482 if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM"); /* 17 */
2483 if (flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE"); /* 19 */
2484 if (flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE"); /* 18 */
2485 if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX"); /* 18 */
2486 if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE"); /* 25 */
2487 if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED"); /* 22 */
2488 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2491 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2492 enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2494 if (op == WINED3D_TOP_DISABLE)
2496 if (state->textures[stage])
2499 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2500 && op != WINED3D_TOP_SELECT_ARG2)
2502 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2503 && op != WINED3D_TOP_SELECT_ARG1)
2505 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2506 && (op == WINED3D_TOP_MULTIPLY_ADD || op == WINED3D_TOP_LERP))
2512 /* Setup this textures matrix according to the texture flags. */
2513 /* Context activation is done by the caller (state handler). */
2514 void set_texture_matrix(const struct wined3d_gl_info *gl_info, const float *smat, DWORD flags,
2515 BOOL calculatedCoords, BOOL transformed, enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2519 gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
2520 checkGLcall("glMatrixMode(GL_TEXTURE)");
2522 if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed)
2524 gl_info->gl_ops.gl.p_glLoadIdentity();
2525 checkGLcall("glLoadIdentity()");
2529 if (flags == (WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED))
2531 ERR("Invalid texture transform flags: WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED.\n");
2535 memcpy(mat, smat, 16 * sizeof(float));
2537 if (flags & WINED3D_TTFF_PROJECTED)
2539 if (!ffp_proj_control)
2541 switch (flags & ~WINED3D_TTFF_PROJECTED)
2543 case WINED3D_TTFF_COUNT2:
2548 mat[ 1] = mat[ 5] = mat[ 9] = mat[13] = 0.0f;
2550 case WINED3D_TTFF_COUNT3:
2555 mat[ 2] = mat[ 6] = mat[10] = mat[14] = 0.0f;
2559 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2560 if(!calculatedCoords) {
2563 case WINED3DFMT_R32_FLOAT:
2564 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2565 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2566 * the input value to the transformation will be 0, so the matrix value is irrelevant
2573 case WINED3DFMT_R32G32_FLOAT:
2574 /* See above, just 3rd and 4th coord
2581 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2582 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2584 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2585 * into a bad place. The division elimination below will apply to make sure the
2586 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2588 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2591 FIXME("Unexpected fixed function texture coord input\n");
2594 if (!ffp_proj_control)
2596 switch (flags & ~WINED3D_TTFF_PROJECTED)
2598 /* case WINED3D_TTFF_COUNT1: Won't ever get here. */
2599 case WINED3D_TTFF_COUNT2:
2600 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2601 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2602 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2603 * the 4th coord evaluates to 1.0 to eliminate that.
2605 * If the fixed function pipeline is used, the 4th value remains unused,
2606 * so there is no danger in doing this. With vertex shaders we have a
2607 * problem. Should an app hit that problem, the code here would have to
2608 * check for pixel shaders, and the shader has to undo the default gl divide.
2610 * A more serious problem occurs if the app passes 4 coordinates in, and the
2611 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2612 * or a replacement shader. */
2614 mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2619 gl_info->gl_ops.gl.p_glLoadMatrixf(mat);
2620 checkGLcall("glLoadMatrixf(mat)");
2623 /* This small helper function is used to convert a bitmask into the number of masked bits */
2624 unsigned int count_bits(unsigned int mask)
2627 for (count = 0; mask; ++count)
2634 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2635 * The later function requires individual color components. */
2636 BOOL getColorBits(const struct wined3d_format *format,
2637 BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2639 TRACE("format %s.\n", debug_d3dformat(format->id));
2643 case WINED3DFMT_B10G10R10A2_UNORM:
2644 case WINED3DFMT_R10G10B10A2_UNORM:
2645 case WINED3DFMT_B8G8R8X8_UNORM:
2646 case WINED3DFMT_B8G8R8_UNORM:
2647 case WINED3DFMT_B8G8R8A8_UNORM:
2648 case WINED3DFMT_R8G8B8A8_UNORM:
2649 case WINED3DFMT_B5G5R5X1_UNORM:
2650 case WINED3DFMT_B5G5R5A1_UNORM:
2651 case WINED3DFMT_B5G6R5_UNORM:
2652 case WINED3DFMT_B4G4R4X4_UNORM:
2653 case WINED3DFMT_B4G4R4A4_UNORM:
2654 case WINED3DFMT_B2G3R3_UNORM:
2655 case WINED3DFMT_P8_UINT_A8_UNORM:
2656 case WINED3DFMT_P8_UINT:
2659 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2663 *redSize = format->red_size;
2664 *greenSize = format->green_size;
2665 *blueSize = format->blue_size;
2666 *alphaSize = format->alpha_size;
2667 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2669 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2670 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2674 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2675 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
2677 TRACE("format %s.\n", debug_d3dformat(format->id));
2681 case WINED3DFMT_D16_LOCKABLE:
2682 case WINED3DFMT_D16_UNORM:
2683 case WINED3DFMT_S1_UINT_D15_UNORM:
2684 case WINED3DFMT_X8D24_UNORM:
2685 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2686 case WINED3DFMT_D24_UNORM_S8_UINT:
2687 case WINED3DFMT_S8_UINT_D24_FLOAT:
2688 case WINED3DFMT_D32_UNORM:
2689 case WINED3DFMT_D32_FLOAT:
2690 case WINED3DFMT_INTZ:
2693 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2697 *depthSize = format->depth_size;
2698 *stencilSize = format->stencil_size;
2700 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2701 *depthSize, *stencilSize, debug_d3dformat(format->id));
2705 /* Note: It's the caller's responsibility to ensure values can be expressed
2706 * in the requested format. UNORM formats for example can only express values
2707 * in the range 0.0f -> 1.0f. */
2708 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color)
2712 enum wined3d_format_id format_id;
2724 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2725 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2726 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2727 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2728 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2729 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2730 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2731 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2732 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2733 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2734 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2735 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2736 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2737 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2739 const struct wined3d_format *format = surface->resource.format;
2742 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2743 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2745 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2749 if (format->id != conv[i].format_id) continue;
2751 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2752 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2753 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2754 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2756 TRACE("Returning 0x%08x.\n", ret);
2761 if (format->id == WINED3DFMT_P8_UINT)
2766 if (!surface->palette)
2768 WARN("Surface doesn't have a palette, returning 0.\n");
2772 r = (BYTE)((color->r * 255.0f) + 0.5f);
2773 g = (BYTE)((color->g * 255.0f) + 0.5f);
2774 b = (BYTE)((color->b * 255.0f) + 0.5f);
2775 a = (BYTE)((color->a * 255.0f) + 0.5f);
2777 e = &surface->palette->palents[a];
2778 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2781 WARN("Alpha didn't match index, searching full palette.\n");
2783 for (i = 0; i < 256; ++i)
2785 e = &surface->palette->palents[i];
2786 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2790 FIXME("Unable to convert color to palette index.\n");
2795 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2800 /* DirectDraw stuff */
2801 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2805 case 8: return WINED3DFMT_P8_UINT;
2806 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2807 case 16: return WINED3DFMT_B5G6R5_UNORM;
2808 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2809 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2810 default: return WINED3DFMT_UNKNOWN;
2814 void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
2815 const struct wined3d_matrix *src2)
2817 struct wined3d_matrix temp;
2819 /* Now do the multiplication 'by hand'.
2820 I know that all this could be optimised, but this will be done later :-) */
2821 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);
2822 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);
2823 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);
2824 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);
2826 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);
2827 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);
2828 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);
2829 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);
2831 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);
2832 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);
2833 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);
2834 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);
2836 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);
2837 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);
2838 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);
2839 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);
2841 /* And copy the new matrix in the good storage.. */
2842 memcpy(dest, &temp, 16 * sizeof(float));
2845 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2848 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2850 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2851 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2852 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2853 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2854 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2855 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2856 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2857 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2858 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2859 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2860 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2861 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2862 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2863 default: ERR("Unexpected position mask\n");
2865 for (i = 0; i < numTextures; i++) {
2866 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2872 void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_state *state,
2873 struct ffp_frag_settings *settings, BOOL ignore_textype)
2878 static const unsigned char args[WINED3D_TOP_LERP + 1] =
2881 /* D3DTOP_DISABLE */ 0,
2882 /* D3DTOP_SELECTARG1 */ ARG1,
2883 /* D3DTOP_SELECTARG2 */ ARG2,
2884 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2885 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2886 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2887 /* D3DTOP_ADD */ ARG1 | ARG2,
2888 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2889 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2890 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2891 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2892 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2893 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2894 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2895 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2896 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2897 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2898 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2899 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2900 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2901 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2902 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2903 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2904 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2905 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2906 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2910 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2911 const struct wined3d_surface *rt = state->fb->render_targets[0];
2912 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2914 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2916 const struct wined3d_texture *texture;
2918 settings->op[i].padding = 0;
2919 if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
2921 settings->op[i].cop = WINED3D_TOP_DISABLE;
2922 settings->op[i].aop = WINED3D_TOP_DISABLE;
2923 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2924 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2925 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2926 settings->op[i].dst = resultreg;
2927 settings->op[i].tex_type = tex_1d;
2928 settings->op[i].projected = proj_none;
2933 if ((texture = state->textures[i]))
2935 settings->op[i].color_fixup = texture->resource.format->color_fixup;
2938 settings->op[i].tex_type = tex_1d;
2942 switch (texture->target)
2945 settings->op[i].tex_type = tex_1d;
2948 settings->op[i].tex_type = tex_2d;
2951 settings->op[i].tex_type = tex_3d;
2953 case GL_TEXTURE_CUBE_MAP_ARB:
2954 settings->op[i].tex_type = tex_cube;
2956 case GL_TEXTURE_RECTANGLE_ARB:
2957 settings->op[i].tex_type = tex_rect;
2962 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2963 settings->op[i].tex_type = tex_1d;
2966 cop = state->texture_states[i][WINED3D_TSS_COLOR_OP];
2967 aop = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
2969 carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG1] : ARG_UNUSED;
2970 carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG2] : ARG_UNUSED;
2971 carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG0] : ARG_UNUSED;
2973 if (is_invalid_op(state, i, cop, carg1, carg2, carg0))
2977 carg1 = WINED3DTA_CURRENT;
2978 cop = WINED3D_TOP_SELECT_ARG1;
2981 if (cop == WINED3D_TOP_DOTPRODUCT3)
2983 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2984 * the color result to the alpha component of the destination
2993 aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] : ARG_UNUSED;
2994 aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] : ARG_UNUSED;
2995 aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] : ARG_UNUSED;
2998 if (!i && state->textures[0] && state->render_states[WINED3D_RS_COLORKEYENABLE])
3000 GLenum texture_dimensions;
3002 texture = state->textures[0];
3003 texture_dimensions = texture->target;
3005 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3007 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3009 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size)
3011 if (aop == WINED3D_TOP_DISABLE)
3013 aarg1 = WINED3DTA_TEXTURE;
3014 aop = WINED3D_TOP_SELECT_ARG1;
3016 else if (aop == WINED3D_TOP_SELECT_ARG1 && aarg1 != WINED3DTA_TEXTURE)
3018 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3020 aarg2 = WINED3DTA_TEXTURE;
3021 aop = WINED3D_TOP_MODULATE;
3023 else aarg1 = WINED3DTA_TEXTURE;
3025 else if (aop == WINED3D_TOP_SELECT_ARG2 && aarg2 != WINED3DTA_TEXTURE)
3027 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3029 aarg1 = WINED3DTA_TEXTURE;
3030 aop = WINED3D_TOP_MODULATE;
3032 else aarg2 = WINED3DTA_TEXTURE;
3038 if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0))
3042 aarg1 = WINED3DTA_CURRENT;
3043 aop = WINED3D_TOP_SELECT_ARG1;
3046 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
3047 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
3049 ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
3050 if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3))
3051 settings->op[i].projected = proj_count3;
3052 else if (ttff & WINED3D_TTFF_PROJECTED)
3053 settings->op[i].projected = proj_count4;
3055 settings->op[i].projected = proj_none;
3059 settings->op[i].projected = proj_none;
3062 settings->op[i].cop = cop;
3063 settings->op[i].aop = aop;
3064 settings->op[i].carg0 = carg0;
3065 settings->op[i].carg1 = carg1;
3066 settings->op[i].carg2 = carg2;
3067 settings->op[i].aarg0 = aarg0;
3068 settings->op[i].aarg1 = aarg1;
3069 settings->op[i].aarg2 = aarg2;
3071 if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP)
3072 settings->op[i].dst = tempreg;
3074 settings->op[i].dst = resultreg;
3077 /* Clear unsupported stages */
3078 for(; i < MAX_TEXTURES; i++) {
3079 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
3082 if (!state->render_states[WINED3D_RS_FOGENABLE])
3084 settings->fog = FOG_OFF;
3086 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
3088 if (use_vs(state) || state->vertex_declaration->position_transformed)
3090 settings->fog = FOG_LINEAR;
3094 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
3096 case WINED3D_FOG_NONE:
3097 case WINED3D_FOG_LINEAR:
3098 settings->fog = FOG_LINEAR;
3100 case WINED3D_FOG_EXP:
3101 settings->fog = FOG_EXP;
3103 case WINED3D_FOG_EXP2:
3104 settings->fog = FOG_EXP2;
3111 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
3113 case WINED3D_FOG_LINEAR:
3114 settings->fog = FOG_LINEAR;
3116 case WINED3D_FOG_EXP:
3117 settings->fog = FOG_EXP;
3119 case WINED3D_FOG_EXP2:
3120 settings->fog = FOG_EXP2;
3124 if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB]
3125 && state->render_states[WINED3D_RS_SRGBWRITEENABLE]
3126 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
3128 settings->sRGB_write = 1;
3130 settings->sRGB_write = 0;
3132 if (device->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
3133 || !state->render_states[WINED3D_RS_CLIPPLANEENABLE])
3135 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3136 * the fixed function vertex pipeline is used(which always supports clipplanes), or
3137 * if no clipplane is enabled
3139 settings->emul_clipplanes = 0;
3141 settings->emul_clipplanes = 1;
3145 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3146 const struct ffp_frag_settings *settings)
3148 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3149 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3152 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3154 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3155 * whereas desc points to an extended structure with implementation specific parts. */
3156 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3158 ERR("Failed to insert ffp frag shader.\n");
3162 /* Activates the texture dimension according to the bound D3D texture. Does
3163 * not care for the colorop or correct gl texture unit (when using nvrc).
3164 * Requires the caller to activate the correct unit. */
3165 /* Context activation is done by the caller (state handler). */
3166 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3170 switch (texture->target)
3173 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3174 checkGLcall("glDisable(GL_TEXTURE_3D)");
3175 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3177 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3178 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3180 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3182 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3183 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3185 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3186 checkGLcall("glEnable(GL_TEXTURE_2D)");
3188 case GL_TEXTURE_RECTANGLE_ARB:
3189 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3190 checkGLcall("glDisable(GL_TEXTURE_2D)");
3191 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3192 checkGLcall("glDisable(GL_TEXTURE_3D)");
3193 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3195 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3196 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3198 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_RECTANGLE_ARB);
3199 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3202 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3204 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3205 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3207 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3209 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3210 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3212 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3213 checkGLcall("glDisable(GL_TEXTURE_2D)");
3214 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D);
3215 checkGLcall("glEnable(GL_TEXTURE_3D)");
3217 case GL_TEXTURE_CUBE_MAP_ARB:
3218 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3219 checkGLcall("glDisable(GL_TEXTURE_2D)");
3220 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3221 checkGLcall("glDisable(GL_TEXTURE_3D)");
3222 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3224 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3225 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3227 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3228 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3234 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3235 checkGLcall("glEnable(GL_TEXTURE_2D)");
3236 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3237 checkGLcall("glDisable(GL_TEXTURE_3D)");
3238 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3240 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3241 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3243 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3245 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3246 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3248 /* Binding textures is done by samplers. A dummy texture will be bound */
3252 /* Context activation is done by the caller (state handler). */
3253 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3255 DWORD sampler = state_id - STATE_SAMPLER(0);
3256 DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
3258 /* No need to enable / disable anything here for unused samplers. The
3259 * tex_colorop handler takes care. Also no action is needed with pixel
3260 * shaders, or if tex_colorop will take care of this business. */
3261 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
3263 if (sampler >= state->lowest_disabled_stage)
3265 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)))
3268 texture_activate_dimensions(state->textures[sampler], context->gl_info);
3271 void *wined3d_rb_alloc(size_t size)
3273 return HeapAlloc(GetProcessHeap(), 0, size);
3276 void *wined3d_rb_realloc(void *ptr, size_t size)
3278 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3281 void wined3d_rb_free(void *ptr)
3283 HeapFree(GetProcessHeap(), 0, ptr);
3286 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3288 const struct ffp_frag_settings *ka = key;
3289 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3291 return memcmp(ka, kb, sizeof(*ka));
3294 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3299 ffp_frag_program_key_compare,
3302 UINT wined3d_log2i(UINT32 x)
3304 static const UINT l[] =
3306 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3307 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3308 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3309 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3310 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3311 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3312 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3313 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3314 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3315 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3316 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3317 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3318 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3319 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3320 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3321 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3325 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3328 /* Set the shader type for this device, depending on the given capabilities
3329 * and the user preferences in wined3d_settings. */
3330 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3332 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3334 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3335 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3337 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3338 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3339 * shaders only on this card. */
3340 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3341 else *vs_selected = SHADER_GLSL;
3343 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3344 else *vs_selected = SHADER_NONE;
3346 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3347 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3348 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3349 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3350 else *ps_selected = SHADER_NONE;
3353 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3354 const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
3355 const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
3357 static const struct blit_shader * const blitters[] =
3365 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3367 if (blitters[i]->blit_supported(gl_info, blit_op,
3368 src_rect, src_usage, src_pool, src_format,
3369 dst_rect, dst_usage, dst_pool, dst_format))
3376 void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
3378 const struct wined3d_viewport *vp = &state->viewport;
3380 SetRect(rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
3382 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
3383 IntersectRect(rect, rect, &state->scissor_rect);