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_INST, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
128 {WINED3DFMT_INTZ, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
129 {WINED3DFMT_RESZ, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
130 {WINED3DFMT_NVHU, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
131 {WINED3DFMT_NVHS, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
132 {WINED3DFMT_NULL, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
133 /* Unsure about them, could not find a Windows driver that supports them */
134 {WINED3DFMT_R16, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
135 {WINED3DFMT_AL16, 0, 0, 0, 16, 0, 0, 0, 16, 4, 0, 0},
138 struct wined3d_format_base_flags
140 enum wined3d_format_id id;
144 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
145 * still needs to use the correct block based calculation for e.g. the
147 static const struct wined3d_format_base_flags format_base_flags[] =
149 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
150 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
151 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
152 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
153 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
156 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
157 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
158 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
159 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
160 {WINED3DFMT_INTZ, WINED3DFMT_FLAG_FOURCC},
161 {WINED3DFMT_NULL, WINED3DFMT_FLAG_FOURCC},
162 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
163 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
164 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
165 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
166 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
171 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
172 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
173 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
174 {WINED3DFMT_NVDB, WINED3DFMT_FLAG_FOURCC},
175 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
176 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
177 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
178 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
179 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
181 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
182 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
184 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
185 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
188 struct wined3d_format_block_info
190 enum wined3d_format_id id;
193 UINT block_byte_count;
196 static const struct wined3d_format_block_info format_block_info[] =
198 {WINED3DFMT_DXT1, 4, 4, 8},
199 {WINED3DFMT_DXT2, 4, 4, 16},
200 {WINED3DFMT_DXT3, 4, 4, 16},
201 {WINED3DFMT_DXT4, 4, 4, 16},
202 {WINED3DFMT_DXT5, 4, 4, 16},
203 {WINED3DFMT_ATI2N, 4, 4, 16},
204 {WINED3DFMT_YUY2, 2, 1, 4},
205 {WINED3DFMT_UYVY, 2, 1, 4},
208 struct wined3d_format_vertex_info
210 enum wined3d_format_id id;
211 enum wined3d_ffp_emit_idx emit_idx;
212 GLint component_count;
215 GLboolean gl_normalized;
216 unsigned int component_size;
219 static const struct wined3d_format_vertex_info format_vertex_info[] =
221 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
222 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
223 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
224 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
225 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
226 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
227 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
228 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
229 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
230 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
231 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
232 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
233 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
234 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
235 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
236 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
237 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
240 struct wined3d_format_texture_info
242 enum wined3d_format_id id;
244 GLint gl_srgb_internal;
245 GLint gl_rt_internal;
248 unsigned int conv_byte_count;
250 enum wined3d_gl_extension extension;
251 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
254 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
256 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
257 * format+type combination to load it. Thus convert it to A8L8, then load it
258 * with A4L4 internal, but A8L8 format+type
261 const unsigned char *Source;
263 UINT outpitch = pitch * 2;
265 for(y = 0; y < height; y++) {
266 Source = src + y * pitch;
267 Dest = dst + y * outpitch;
268 for (x = 0; x < width; x++ ) {
269 unsigned char color = (*Source++);
270 /* A */ Dest[1] = (color & 0xf0) << 0;
271 /* L */ Dest[0] = (color & 0x0f) << 4;
277 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
282 for(y = 0; y < height; y++)
284 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
285 Source = (const WORD *)(src + y * pitch);
286 for (x = 0; x < width; x++ )
288 short color = (*Source++);
289 unsigned char l = ((color >> 10) & 0xfc);
290 short v = ((color >> 5) & 0x3e);
291 short u = ((color ) & 0x1f);
292 short v_conv = v + 16;
293 short u_conv = u + 16;
295 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
301 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
306 UINT outpitch = (pitch * 3)/2;
308 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
309 * fixed function and shaders without further conversion once the surface is
312 for(y = 0; y < height; y++) {
313 Source = (const WORD *)(src + y * pitch);
314 Dest = dst + y * outpitch;
315 for (x = 0; x < width; x++ ) {
316 short color = (*Source++);
317 unsigned char l = ((color >> 10) & 0xfc);
318 char v = ((color >> 5) & 0x3e);
319 char u = ((color ) & 0x1f);
321 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
322 * and doubles the positive range. Thus shift left only once, gl does the 2nd
323 * shift. GL reads a signed value and converts it into an unsigned value.
325 /* M */ Dest[2] = l << 1;
327 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
328 * from 5 bit values to 8 bit values.
330 /* V */ Dest[1] = v << 3;
331 /* U */ Dest[0] = u << 3;
337 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
342 UINT outpitch = (pitch * 3)/2;
344 for(y = 0; y < height; y++)
346 Source = (const short *)(src + y * pitch);
347 Dest = dst + y * outpitch;
348 for (x = 0; x < width; x++ )
350 const short color = (*Source++);
351 /* B */ Dest[0] = 0xff;
352 /* G */ Dest[1] = (color >> 8) + 128; /* V */
353 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
359 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
365 /* Doesn't work correctly with the fixed function pipeline, but can work in
366 * shaders if the shader is adjusted. (There's no use for this format in gl's
367 * standard fixed function pipeline anyway).
369 for(y = 0; y < height; y++)
371 Source = (const DWORD *)(src + y * pitch);
372 Dest = dst + y * pitch;
373 for (x = 0; x < width; x++ )
375 LONG color = (*Source++);
376 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
377 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
378 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
384 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
390 /* This implementation works with the fixed function pipeline and shaders
391 * without further modification after converting the surface.
393 for(y = 0; y < height; y++)
395 Source = (const DWORD *)(src + y * pitch);
396 Dest = dst + y * pitch;
397 for (x = 0; x < width; x++ )
399 LONG color = (*Source++);
400 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
401 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
402 /* U */ Dest[0] = (color & 0xff); /* U */
403 /* I */ Dest[3] = 255; /* X */
409 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
415 for(y = 0; y < height; y++)
417 Source = (const DWORD *)(src + y * pitch);
418 Dest = dst + y * pitch;
419 for (x = 0; x < width; x++ )
421 LONG color = (*Source++);
422 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
423 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
424 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
425 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
431 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
435 unsigned short *Dest;
436 UINT outpitch = (pitch * 3)/2;
438 for(y = 0; y < height; y++)
440 Source = (const DWORD *)(src + y * pitch);
441 Dest = (unsigned short *) (dst + y * outpitch);
442 for (x = 0; x < width; x++ )
444 const DWORD color = (*Source++);
445 /* B */ Dest[0] = 0xffff;
446 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
447 /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */
453 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
458 UINT outpitch = (pitch * 3)/2;
460 for(y = 0; y < height; y++)
462 Source = (const WORD *)(src + y * pitch);
463 Dest = (WORD *) (dst + y * outpitch);
464 for (x = 0; x < width; x++ )
466 WORD green = (*Source++);
467 WORD red = (*Source++);
470 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
471 * shader overwrites it anyway
479 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
484 UINT outpitch = (pitch * 3)/2;
486 for(y = 0; y < height; y++)
488 Source = (const float *)(src + y * pitch);
489 Dest = (float *) (dst + y * outpitch);
490 for (x = 0; x < width; x++ )
492 float green = (*Source++);
493 float red = (*Source++);
502 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
505 UINT outpitch = pitch * 2;
507 for (y = 0; y < height; ++y)
509 const WORD *source = (const WORD *)(src + y * pitch);
510 DWORD *dest = (DWORD *)(dst + y * outpitch);
512 for (x = 0; x < width; ++x)
514 /* The depth data is normalized, so needs to be scaled,
515 * the stencil data isn't. Scale depth data by
516 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
517 WORD d15 = source[x] >> 1;
518 DWORD d24 = (d15 << 9) + (d15 >> 6);
519 dest[x] = (d24 << 8) | (source[x] & 0x1);
524 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
528 for (y = 0; y < height; ++y)
530 const DWORD *source = (const DWORD *)(src + y * pitch);
531 DWORD *dest = (DWORD *)(dst + y * pitch);
533 for (x = 0; x < width; ++x)
535 /* Just need to clear out the X4 part. */
536 dest[x] = source[x] & ~0xf0;
541 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
544 UINT outpitch = pitch * 2;
546 for (y = 0; y < height; ++y)
548 const DWORD *source = (const DWORD *)(src + y * pitch);
549 float *dest_f = (float *)(dst + y * outpitch);
550 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
552 for (x = 0; x < width; ++x)
554 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
555 dest_s[x * 2 + 1] = source[x] & 0xff;
560 /* The following formats explicitly don't have WINED3DFMT_FLAG_TEXTURE set:
562 * These are never supported on native.
563 * WINED3DFMT_B8G8R8_UNORM
564 * WINED3DFMT_B2G3R3_UNORM
565 * WINED3DFMT_L4A4_UNORM
566 * WINED3DFMT_S1_UINT_D15_UNORM
567 * WINED3DFMT_S4X4_UINT_D24_UNORM
569 * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of ddraw.
570 * Since it is not widely available, don't offer it. Further no Windows driver
571 * offers WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either.
573 * WINED3DFMT_P8_UINT_A8_UNORM
575 * These formats seem to be similar to the HILO formats in
576 * GL_NV_texture_shader. NVHU is said to be GL_UNSIGNED_HILO16,
577 * NVHS GL_SIGNED_HILO16. Rumours say that D3D computes a 3rd channel
578 * similarly to D3DFMT_CxV8U8 (So NVHS could be called D3DFMT_CxV16U16). ATI
579 * refused to support formats which can easily be emulated with pixel shaders,
580 * so applications have to deal with not having NVHS and NVHU.
583 static const struct wined3d_format_texture_info format_texture_info[] =
585 /* format id internal srgbInternal rtInternal
590 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
591 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
592 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
593 * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
596 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
597 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
598 WINED3DFMT_FLAG_FILTERING,
599 WINED3D_GL_EXT_NONE, NULL},
600 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
601 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 0,
602 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
603 APPLE_YCBCR_422, NULL},
604 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
605 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
606 WINED3DFMT_FLAG_FILTERING,
607 WINED3D_GL_EXT_NONE, NULL},
608 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
609 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, 0,
610 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
611 APPLE_YCBCR_422, NULL},
612 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
613 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
614 WINED3DFMT_FLAG_FILTERING,
615 WINED3D_GL_EXT_NONE, NULL},
616 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
617 GL_RGBA, GL_UNSIGNED_BYTE, 0,
618 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
619 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
620 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
621 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
622 GL_RGBA, GL_UNSIGNED_BYTE, 0,
623 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
624 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
625 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
626 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
627 GL_RGBA, GL_UNSIGNED_BYTE, 0,
628 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
629 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
630 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
631 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
632 GL_RGBA, GL_UNSIGNED_BYTE, 0,
633 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
634 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
635 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
636 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
637 GL_RGBA, GL_UNSIGNED_BYTE, 0,
638 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
639 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
640 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
642 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
644 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
645 ARB_TEXTURE_FLOAT, NULL},
646 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
648 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
649 ARB_TEXTURE_RG, NULL},
650 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
651 GL_RGB, GL_FLOAT, 12,
652 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
653 ARB_TEXTURE_FLOAT, convert_r32g32_float},
654 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
656 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
657 ARB_TEXTURE_RG, NULL},
658 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
659 GL_RGBA, GL_FLOAT, 0,
660 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
661 ARB_TEXTURE_FLOAT, NULL},
663 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
664 GL_RED, GL_HALF_FLOAT_ARB, 0,
665 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
666 ARB_TEXTURE_FLOAT, NULL},
667 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
668 GL_RED, GL_HALF_FLOAT_ARB, 0,
669 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
670 ARB_TEXTURE_RG, NULL},
671 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
672 GL_RGB, GL_HALF_FLOAT_ARB, 6,
673 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
674 ARB_TEXTURE_FLOAT, convert_r16g16},
675 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
676 GL_RG, GL_HALF_FLOAT_ARB, 0,
677 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
678 ARB_TEXTURE_RG, NULL},
679 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
680 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
681 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET
682 | WINED3DFMT_FLAG_VTF,
683 ARB_TEXTURE_FLOAT, NULL},
684 /* Palettized formats */
685 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
686 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
688 ARB_FRAGMENT_PROGRAM, NULL},
689 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
690 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
692 EXT_PALETTED_TEXTURE, NULL},
693 /* Standard ARGB formats */
694 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
695 GL_BGR, GL_UNSIGNED_BYTE, 0,
696 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
697 WINED3D_GL_EXT_NONE, NULL},
698 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
699 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
700 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
701 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE
702 | WINED3DFMT_FLAG_VTF,
703 WINED3D_GL_EXT_NONE, NULL},
704 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
705 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
706 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
707 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
708 WINED3D_GL_EXT_NONE, NULL},
709 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
710 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
711 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
712 | WINED3DFMT_FLAG_RENDERTARGET,
713 WINED3D_GL_EXT_NONE, NULL},
714 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
715 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
716 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
717 WINED3D_GL_EXT_NONE, NULL},
718 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
719 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
720 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
721 WINED3D_GL_EXT_NONE, NULL},
722 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
723 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
724 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
725 | WINED3DFMT_FLAG_SRGB_READ,
726 WINED3D_GL_EXT_NONE, NULL},
727 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
728 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
729 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
730 WINED3D_GL_EXT_NONE, NULL},
731 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
732 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
733 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
734 WINED3D_GL_EXT_NONE, NULL},
735 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
736 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
737 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
738 WINED3D_GL_EXT_NONE, NULL},
739 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
740 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
741 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
742 | WINED3DFMT_FLAG_RENDERTARGET,
743 WINED3D_GL_EXT_NONE, NULL},
744 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
745 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
746 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
747 WINED3D_GL_EXT_NONE, NULL},
748 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
749 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
750 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
751 WINED3D_GL_EXT_NONE, NULL},
752 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
753 GL_RGB, GL_UNSIGNED_SHORT, 6,
754 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
755 WINED3D_GL_EXT_NONE, convert_r16g16},
756 {WINED3DFMT_R16G16_UNORM, GL_RG16, GL_RG16, 0,
757 GL_RG, GL_UNSIGNED_SHORT, 0,
758 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
759 | WINED3DFMT_FLAG_RENDERTARGET,
760 ARB_TEXTURE_RG, NULL},
761 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
762 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
763 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
764 | WINED3DFMT_FLAG_RENDERTARGET,
765 WINED3D_GL_EXT_NONE, NULL},
766 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
767 GL_RGBA, GL_UNSIGNED_SHORT, 0,
768 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
769 | WINED3DFMT_FLAG_RENDERTARGET,
770 WINED3D_GL_EXT_NONE, NULL},
772 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
773 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
774 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
775 | WINED3DFMT_FLAG_SRGB_READ,
776 WINED3D_GL_EXT_NONE, NULL},
777 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
778 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
779 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
780 | WINED3DFMT_FLAG_SRGB_READ,
781 WINED3D_GL_EXT_NONE, NULL},
782 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
783 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
784 WINED3DFMT_FLAG_FILTERING,
785 WINED3D_GL_EXT_NONE, convert_l4a4_unorm},
786 /* Bump mapping stuff */
787 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
788 GL_BGR, GL_UNSIGNED_BYTE, 3,
789 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
790 | WINED3DFMT_FLAG_BUMPMAP,
791 WINED3D_GL_EXT_NONE, convert_r8g8_snorm},
792 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
793 GL_DSDT_NV, GL_BYTE, 0,
794 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
795 | WINED3DFMT_FLAG_BUMPMAP,
796 NV_TEXTURE_SHADER, NULL},
797 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
798 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
799 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
800 | WINED3DFMT_FLAG_BUMPMAP,
801 WINED3D_GL_EXT_NONE, convert_r5g5_snorm_l6_unorm},
802 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
803 GL_DSDT_MAG_NV, GL_BYTE, 3,
804 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
805 | WINED3DFMT_FLAG_BUMPMAP,
806 NV_TEXTURE_SHADER, convert_r5g5_snorm_l6_unorm_nv},
807 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
808 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
809 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
810 | WINED3DFMT_FLAG_BUMPMAP,
811 WINED3D_GL_EXT_NONE, convert_r8g8_snorm_l8x8_unorm},
812 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
813 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
814 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
815 | WINED3DFMT_FLAG_BUMPMAP,
816 NV_TEXTURE_SHADER, convert_r8g8_snorm_l8x8_unorm_nv},
817 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
818 GL_BGRA, GL_UNSIGNED_BYTE, 4,
819 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
820 | WINED3DFMT_FLAG_BUMPMAP,
821 WINED3D_GL_EXT_NONE, convert_r8g8b8a8_snorm},
822 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
824 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
825 | WINED3DFMT_FLAG_BUMPMAP,
826 NV_TEXTURE_SHADER, NULL},
827 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
828 GL_BGR, GL_UNSIGNED_SHORT, 6,
829 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
830 | WINED3DFMT_FLAG_BUMPMAP,
831 WINED3D_GL_EXT_NONE, convert_r16g16_snorm},
832 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
833 GL_HILO_NV, GL_SHORT, 0,
834 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
835 | WINED3DFMT_FLAG_BUMPMAP,
836 NV_TEXTURE_SHADER, NULL},
837 /* Depth stencil formats */
838 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
839 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
840 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
841 ARB_DEPTH_TEXTURE, NULL},
842 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
843 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
844 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
845 ARB_DEPTH_TEXTURE, NULL},
846 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
847 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
848 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
849 ARB_DEPTH_TEXTURE, NULL},
850 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
851 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
852 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
853 EXT_PACKED_DEPTH_STENCIL, convert_s1_uint_d15_unorm},
854 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
855 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
856 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
857 ARB_FRAMEBUFFER_OBJECT, convert_s1_uint_d15_unorm},
858 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
859 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
860 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
861 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
862 ARB_DEPTH_TEXTURE, NULL},
863 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
864 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
865 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
866 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
867 EXT_PACKED_DEPTH_STENCIL, NULL},
868 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
869 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
870 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
871 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
872 ARB_FRAMEBUFFER_OBJECT, NULL},
873 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
874 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
875 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
876 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
877 ARB_DEPTH_TEXTURE, NULL},
878 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
879 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
880 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
881 ARB_DEPTH_TEXTURE, NULL},
882 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
883 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
884 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
885 EXT_PACKED_DEPTH_STENCIL, convert_s4x4_uint_d24_unorm},
886 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
887 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
888 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
889 ARB_FRAMEBUFFER_OBJECT, convert_s4x4_uint_d24_unorm},
890 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
891 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
892 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
893 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
894 ARB_DEPTH_TEXTURE, NULL},
895 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
896 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
897 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
898 WINED3D_GL_EXT_NONE, NULL},
899 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
900 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
901 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
902 ARB_DEPTH_BUFFER_FLOAT, NULL},
903 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
904 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
905 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
906 ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float},
907 /* Vendor-specific formats */
908 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
909 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
910 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
911 | WINED3DFMT_FLAG_COMPRESSED,
912 ATI_TEXTURE_COMPRESSION_3DC, NULL},
913 {WINED3DFMT_ATI2N, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0,
914 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
915 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
916 | WINED3DFMT_FLAG_COMPRESSED,
917 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
918 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
919 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
920 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
921 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
922 EXT_PACKED_DEPTH_STENCIL, NULL},
923 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
924 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
925 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
926 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
927 ARB_FRAMEBUFFER_OBJECT, NULL},
928 {WINED3DFMT_NULL, GL_RGBA8, GL_RGBA8, 0,
929 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
930 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET,
931 ARB_FRAMEBUFFER_OBJECT, NULL},
934 static inline int getFmtIdx(enum wined3d_format_id format_id)
936 /* First check if the format is at the position of its value.
937 * This will catch the argb formats before the loop is entered. */
938 if (format_id < (sizeof(formats) / sizeof(*formats))
939 && formats[format_id].id == format_id)
947 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
949 if (formats[i].id == format_id) return i;
955 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
957 UINT format_count = sizeof(formats) / sizeof(*formats);
960 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
961 if (!gl_info->formats)
963 ERR("Failed to allocate memory.\n");
967 for (i = 0; i < format_count; ++i)
969 struct wined3d_format *format = &gl_info->formats[i];
970 format->id = formats[i].id;
971 format->red_size = formats[i].red_size;
972 format->green_size = formats[i].green_size;
973 format->blue_size = formats[i].blue_size;
974 format->alpha_size = formats[i].alpha_size;
975 format->red_offset = formats[i].red_offset;
976 format->green_offset = formats[i].green_offset;
977 format->blue_offset = formats[i].blue_offset;
978 format->alpha_offset = formats[i].alpha_offset;
979 format->byte_count = formats[i].bpp;
980 format->depth_size = formats[i].depth_size;
981 format->stencil_size = formats[i].stencil_size;
982 format->block_width = 1;
983 format->block_height = 1;
984 format->block_byte_count = formats[i].bpp;
987 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
989 int fmt_idx = getFmtIdx(format_base_flags[i].id);
993 ERR("Format %s (%#x) not found.\n",
994 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
995 HeapFree(GetProcessHeap(), 0, gl_info->formats);
999 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
1005 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
1009 for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i)
1011 struct wined3d_format *format;
1012 int fmt_idx = getFmtIdx(format_block_info[i].id);
1016 ERR("Format %s (%#x) not found.\n",
1017 debug_d3dformat(format_block_info[i].id), format_block_info[i].id);
1021 format = &gl_info->formats[fmt_idx];
1022 format->block_width = format_block_info[i].block_width;
1023 format->block_height = format_block_info[i].block_height;
1024 format->block_byte_count = format_block_info[i].block_byte_count;
1025 format->flags |= WINED3DFMT_FLAG_BLOCKS;
1031 /* Context activation is done by the caller. */
1032 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
1034 /* Check if the default internal format is supported as a frame buffer
1035 * target, otherwise fall back to the render target internal.
1037 * Try to stick to the standard format if possible, this limits precision differences. */
1041 while (gl_info->gl_ops.gl.p_glGetError());
1042 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1044 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1045 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1047 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0,
1048 format->glFormat, format->glType, NULL);
1049 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1050 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1052 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1054 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1055 checkGLcall("Framebuffer format check");
1057 if (status == GL_FRAMEBUFFER_COMPLETE)
1059 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1060 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1061 format->rtInternal = format->glInternal;
1065 if (!format->rtInternal)
1067 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1069 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1070 " and no fallback specified.\n", debug_d3dformat(format->id));
1071 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1075 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1077 format->rtInternal = format->glInternal;
1081 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1082 debug_d3dformat(format->id));
1084 while (gl_info->gl_ops.gl.p_glGetError());
1086 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1088 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0,
1089 format->glFormat, format->glType, NULL);
1090 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1091 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1093 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1095 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1096 checkGLcall("Framebuffer format check");
1098 if (status == GL_FRAMEBUFFER_COMPLETE)
1100 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1101 debug_d3dformat(format->id));
1105 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1106 debug_d3dformat(format->id));
1107 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1112 if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1113 || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1114 && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
1115 && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA
1116 && (format->red_size || format->alpha_size))
1118 DWORD readback[16 * 16], color, r_range, a_range;
1123 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1124 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1126 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1127 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1128 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1129 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1130 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1131 checkGLcall("RB attachment");
1134 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1135 gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1136 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1137 if (gl_info->gl_ops.gl.p_glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1139 while (gl_info->gl_ops.gl.p_glGetError());
1140 TRACE("Format doesn't support post-pixelshader blending.\n");
1141 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1145 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1146 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16);
1147 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1148 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1149 gl_info->gl_ops.gl.p_glLoadIdentity();
1150 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1151 gl_info->gl_ops.gl.p_glLoadIdentity();
1153 gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1155 /* Draw a full-black quad */
1156 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1157 gl_info->gl_ops.gl.p_glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
1158 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1159 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1160 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1161 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1162 gl_info->gl_ops.gl.p_glEnd();
1164 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1165 /* Draw a half-transparent red quad */
1166 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1167 gl_info->gl_ops.gl.p_glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
1168 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1169 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1170 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1171 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1172 gl_info->gl_ops.gl.p_glEnd();
1174 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1176 /* Rebinding texture to workaround a fglrx bug. */
1177 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1178 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1179 checkGLcall("Post-pixelshader blending check");
1181 color = readback[7 * 16 + 7];
1183 r = (color & 0x00ff0000) >> 16;
1185 r_range = format->red_size < 8 ? 1 << (8 - format->red_size) : 1;
1186 a_range = format->alpha_size < 8 ? 1 << (8 - format->alpha_size) : 1;
1187 if (format->red_size && (r < 0x7f - r_range || r > 0x7f + r_range))
1189 else if (format->alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range))
1193 TRACE("Format doesn't support post-pixelshader blending.\n");
1194 TRACE("Color output: %#x\n", color);
1195 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1199 TRACE("Format supports post-pixelshader blending.\n");
1200 TRACE("Color output: %#x\n", color);
1201 format->flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1205 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1206 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1208 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1209 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1210 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1211 checkGLcall("RB cleanup");
1215 if (format->glInternal != format->glGammaInternal)
1217 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0,
1218 format->glFormat, format->glType, NULL);
1219 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1221 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1222 checkGLcall("Framebuffer format check");
1224 if (status == GL_FRAMEBUFFER_COMPLETE)
1226 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1227 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1231 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1234 else if (status == GL_FRAMEBUFFER_COMPLETE)
1235 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1237 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1240 /* Context activation is done by the caller. */
1241 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1246 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1248 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1249 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1250 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1251 gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0);
1254 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1256 struct wined3d_format *format = &gl_info->formats[i];
1258 if (!format->glInternal) continue;
1260 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1262 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1263 debug_d3dformat(format->id));
1267 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1269 TRACE("Skipping format %s because it's a compressed format.\n",
1270 debug_d3dformat(format->id));
1274 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1276 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1277 check_fbo_compat(gl_info, format);
1281 format->rtInternal = format->glInternal;
1285 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1286 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1289 static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1291 struct fragment_caps fragment_caps;
1292 struct shader_caps shader_caps;
1296 adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
1297 adapter->shader_backend->shader_get_caps(gl_info, &shader_caps);
1298 srgb_write = (fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_SRGB_WRITE)
1299 && (shader_caps.wined3d_caps & WINED3D_SHADER_CAP_SRGB_WRITE);
1301 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1303 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1304 struct wined3d_format *format;
1308 ERR("Format %s (%#x) not found.\n",
1309 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1313 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1315 format = &gl_info->formats[fmt_idx];
1317 /* ARB_texture_rg defines floating point formats, but only if
1318 * ARB_texture_float is also supported. */
1319 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1320 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1323 format->glInternal = format_texture_info[i].gl_internal;
1324 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1325 format->rtInternal = format_texture_info[i].gl_rt_internal;
1326 format->glFormat = format_texture_info[i].gl_format;
1327 format->glType = format_texture_info[i].gl_type;
1328 format->color_fixup = COLOR_FIXUP_IDENTITY;
1329 format->flags |= format_texture_info[i].flags;
1330 format->height_scale.numerator = 1;
1331 format->height_scale.denominator = 1;
1333 if (!gl_info->limits.vertex_samplers)
1334 format->flags &= ~WINED3DFMT_FLAG_VTF;
1336 if (!(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1337 format->flags |= WINED3DFMT_FLAG_FILTERING;
1338 else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT)
1339 format->flags &= ~WINED3DFMT_FLAG_VTF;
1341 if (format->glGammaInternal != format->glInternal)
1343 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1344 if (!gl_info->supported[EXT_TEXTURE_SRGB])
1346 format->glGammaInternal = format->glInternal;
1347 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1349 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1351 format->glInternal = format->glGammaInternal;
1355 if ((format->flags & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write)
1356 format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
1358 /* Texture conversion stuff */
1359 format->convert = format_texture_info[i].convert;
1360 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1366 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1368 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1370 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1372 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1374 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1378 /* A context is provided by the caller */
1379 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1381 static const DWORD data[] = {0x00000000, 0xffffffff};
1382 GLuint tex, fbo, buffer;
1383 DWORD readback[16 * 1];
1386 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1387 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1388 * falling back to software. If this changes in the future this code will get fooled and
1389 * apps might hit the software path due to incorrectly advertised caps.
1391 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1392 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1393 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1396 while (gl_info->gl_ops.gl.p_glGetError());
1398 gl_info->gl_ops.gl.p_glGenTextures(1, &buffer);
1399 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1400 memset(readback, 0x7e, sizeof(readback));
1401 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0,
1402 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1403 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1404 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1405 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1406 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1407 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1409 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1410 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1411 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0,
1412 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1413 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1414 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1415 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1416 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1417 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1418 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
1420 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1421 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1422 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1423 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1425 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1);
1426 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1427 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1428 gl_info->gl_ops.gl.p_glLoadIdentity();
1429 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1430 gl_info->gl_ops.gl.p_glLoadIdentity();
1432 gl_info->gl_ops.gl.p_glClearColor(0, 1, 0, 0);
1433 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1435 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1436 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 0.0);
1437 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, -1.0f);
1438 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 0.0);
1439 gl_info->gl_ops.gl.p_glVertex2f(1.0f, -1.0f);
1440 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 1.0);
1441 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, 1.0f);
1442 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 1.0);
1443 gl_info->gl_ops.gl.p_glVertex2f(1.0f, 1.0f);
1444 gl_info->gl_ops.gl.p_glEnd();
1446 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1447 memset(readback, 0x7f, sizeof(readback));
1448 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1449 if (color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5)
1450 || color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1452 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, assuming no filtering\n",
1453 readback[6], readback[9]);
1458 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1459 readback[6], readback[9]);
1463 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1464 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1465 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1466 gl_info->gl_ops.gl.p_glDeleteTextures(1, &buffer);
1468 if (gl_info->gl_ops.gl.p_glGetError())
1470 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1477 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1479 struct wined3d_format *format;
1480 unsigned int fmt_idx, i;
1481 static const enum wined3d_format_id fmts16[] =
1483 WINED3DFMT_R16_FLOAT,
1484 WINED3DFMT_R16G16_FLOAT,
1485 WINED3DFMT_R16G16B16A16_FLOAT,
1489 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1491 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1492 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1494 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1497 else if (gl_info->limits.glsl_varyings > 44)
1499 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1504 TRACE("Assuming no float16 blending\n");
1510 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1512 fmt_idx = getFmtIdx(fmts16[i]);
1513 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1519 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1521 fmt_idx = getFmtIdx(fmts16[i]);
1522 format = &gl_info->formats[fmt_idx];
1523 if (!format->glInternal) continue; /* Not supported by GL */
1525 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1528 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1529 format->flags |= WINED3DFMT_FLAG_FILTERING;
1533 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1538 static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1543 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1544 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1545 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1547 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1548 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1549 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1551 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1552 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1553 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1555 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1556 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1557 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1559 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1560 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1561 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1563 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1564 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1565 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1566 * the only driver that implements it(fglrx) has a buggy implementation.
1568 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1569 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1570 * conversion for this format.
1572 if (!gl_info->supported[NV_TEXTURE_SHADER])
1574 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1575 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1576 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1577 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1578 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1579 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1583 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1584 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1585 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1587 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1588 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1589 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1592 if (!gl_info->supported[NV_TEXTURE_SHADER])
1594 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1597 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1598 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1599 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1600 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1601 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1602 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1603 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1604 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1605 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1609 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1610 * are converted at surface loading time, but they do not need any modification in
1611 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1612 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1616 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1618 idx = getFmtIdx(WINED3DFMT_ATI2N);
1619 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1620 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1622 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1624 idx = getFmtIdx(WINED3DFMT_ATI2N);
1625 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1626 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1629 if (!gl_info->supported[APPLE_YCBCR_422])
1631 idx = getFmtIdx(WINED3DFMT_YUY2);
1632 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1634 idx = getFmtIdx(WINED3DFMT_UYVY);
1635 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1638 idx = getFmtIdx(WINED3DFMT_YV12);
1639 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
1640 gl_info->formats[idx].height_scale.numerator = 3;
1641 gl_info->formats[idx].height_scale.denominator = 2;
1642 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1644 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1646 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1647 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1650 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1652 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1653 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1656 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1658 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1659 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1660 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1661 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1663 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1664 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1667 if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
1669 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1670 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1672 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1673 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1675 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1676 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1679 if (gl_info->quirks & WINED3D_QUIRK_BROKEN_RGBA16)
1681 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_UNORM);
1682 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1685 /* ATI instancing hack: Although ATI cards do not support Shader Model
1686 * 3.0, they support instancing. To query if the card supports instancing
1687 * CheckDeviceFormat() with the special format MAKEFOURCC('I','N','S','T')
1688 * is used. Should an application check for this, provide a proper return
1689 * value. We can do instancing with all shader versions, but we need
1692 * Additionally applications have to set the D3DRS_POINTSIZE render state
1693 * to MAKEFOURCC('I','N','S','T') once to enable instancing. Wined3d
1694 * doesn't need that and just ignores it.
1696 * With Shader Model 3.0 capable cards Instancing 'just works' in Windows. */
1697 /* FIXME: This should just check the shader backend caps. */
1698 if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
1700 idx = getFmtIdx(WINED3DFMT_INST);
1701 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
1704 /* Depth bound test. To query if the card supports it CheckDeviceFormat()
1705 * with the special format MAKEFOURCC('N','V','D','B') is used. It is
1706 * enabled by setting D3DRS_ADAPTIVETESS_X render state to
1707 * MAKEFOURCC('N','V','D','B') and then controlled by setting
1708 * D3DRS_ADAPTIVETESS_Z (zMin) and D3DRS_ADAPTIVETESS_W (zMax) to test
1710 if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST])
1712 idx = getFmtIdx(WINED3DFMT_NVDB);
1713 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
1716 /* RESZ aka AMD DX9-level hack for multisampled depth buffer resolve. You query for RESZ
1717 * support by checking for availability of MAKEFOURCC('R','E','S','Z') surfaces with
1718 * RENDERTARGET usage. */
1719 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
1721 idx = getFmtIdx(WINED3DFMT_RESZ);
1722 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET;
1725 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1727 struct wined3d_format *format = &gl_info->formats[idx];
1729 if (!(format->flags & WINED3DFMT_FLAG_TEXTURE))
1732 if (!adapter->shader_backend->shader_color_fixup_supported(format->color_fixup)
1733 || !adapter->fragment_pipe->color_fixup_supported(format->color_fixup))
1734 format->flags &= ~WINED3DFMT_FLAG_TEXTURE;
1738 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1742 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1744 struct wined3d_format *format;
1745 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1749 ERR("Format %s (%#x) not found.\n",
1750 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1754 format = &gl_info->formats[fmt_idx];
1755 format->emit_idx = format_vertex_info[i].emit_idx;
1756 format->component_count = format_vertex_info[i].component_count;
1757 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1758 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1759 format->gl_normalized = format_vertex_info[i].gl_normalized;
1760 format->component_size = format_vertex_info[i].component_size;
1766 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1768 if (!init_format_base_info(gl_info)) return FALSE;
1770 if (!init_format_block_info(gl_info))
1772 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1773 gl_info->formats = NULL;
1780 /* Context activation is done by the caller. */
1781 BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter)
1783 struct wined3d_gl_info *gl_info = &adapter->gl_info;
1785 if (!init_format_base_info(gl_info)) return FALSE;
1787 if (!init_format_block_info(gl_info)) goto fail;
1788 if (!init_format_texture_info(adapter, gl_info)) goto fail;
1789 if (!init_format_vertex_info(gl_info)) goto fail;
1791 apply_format_fixups(adapter, gl_info);
1792 init_format_fbo_compat_info(gl_info);
1793 init_format_filter_info(gl_info, adapter->driver_info.vendor);
1798 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1799 gl_info->formats = NULL;
1803 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1804 enum wined3d_format_id format_id)
1806 int idx = getFmtIdx(format_id);
1810 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1811 debug_d3dformat(format_id), format_id);
1812 /* Get the caller a valid pointer */
1813 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1816 return &gl_info->formats[idx];
1819 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1823 if (format->id == WINED3DFMT_UNKNOWN)
1827 else if (format->flags & WINED3DFMT_FLAG_BLOCKS)
1829 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1830 UINT row_count = (height + format->block_height - 1) / format->block_height;
1831 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1835 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1838 if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
1840 /* The D3D format requirements make sure that the resulting format is an integer again */
1841 size *= format->height_scale.numerator;
1842 size /= format->height_scale.denominator;
1848 /*****************************************************************************
1849 * Trace formatting of useful values
1851 const char *debug_d3dformat(enum wined3d_format_id format_id)
1855 #define FMT_TO_STR(format_id) case format_id: return #format_id
1856 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1857 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1858 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1859 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1860 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1861 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1862 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1863 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1864 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1865 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1866 FMT_TO_STR(WINED3DFMT_P8_UINT);
1867 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1868 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1869 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1870 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1871 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1872 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1873 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1874 FMT_TO_STR(WINED3DFMT_UYVY);
1875 FMT_TO_STR(WINED3DFMT_YUY2);
1876 FMT_TO_STR(WINED3DFMT_YV12);
1877 FMT_TO_STR(WINED3DFMT_DXT1);
1878 FMT_TO_STR(WINED3DFMT_DXT2);
1879 FMT_TO_STR(WINED3DFMT_DXT3);
1880 FMT_TO_STR(WINED3DFMT_DXT4);
1881 FMT_TO_STR(WINED3DFMT_DXT5);
1882 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1883 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1884 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1885 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1886 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1887 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1888 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1889 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1890 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1891 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1892 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1893 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1894 FMT_TO_STR(WINED3DFMT_ATI2N);
1895 FMT_TO_STR(WINED3DFMT_NVDB);
1896 FMT_TO_STR(WINED3DFMT_NVHU);
1897 FMT_TO_STR(WINED3DFMT_NVHS);
1898 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1899 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1900 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1901 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1902 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1903 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1904 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1905 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1906 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1907 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1908 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1909 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1910 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1911 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1912 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1913 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1914 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1915 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1916 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1917 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1918 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1919 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1920 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1921 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1922 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1923 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1924 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1925 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1926 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1927 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1928 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1929 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1930 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1931 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1932 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1933 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1934 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1935 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1936 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1937 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1938 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1939 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1940 FMT_TO_STR(WINED3DFMT_R32_UINT);
1941 FMT_TO_STR(WINED3DFMT_R32_SINT);
1942 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1943 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1944 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1945 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1946 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1947 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1948 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1949 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1950 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1951 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1952 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1953 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1954 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1955 FMT_TO_STR(WINED3DFMT_R16_UINT);
1956 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1957 FMT_TO_STR(WINED3DFMT_R16_SINT);
1958 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1959 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1960 FMT_TO_STR(WINED3DFMT_R8_UINT);
1961 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1962 FMT_TO_STR(WINED3DFMT_R8_SINT);
1963 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1964 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1965 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1966 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1967 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1968 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1969 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1970 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1971 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1972 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1973 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1974 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1975 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1976 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1977 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1978 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1979 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1980 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1981 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1982 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1983 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1984 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1985 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1986 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1987 FMT_TO_STR(WINED3DFMT_INTZ);
1988 FMT_TO_STR(WINED3DFMT_RESZ);
1989 FMT_TO_STR(WINED3DFMT_NULL);
1990 FMT_TO_STR(WINED3DFMT_R16);
1991 FMT_TO_STR(WINED3DFMT_AL16);
1996 fourcc[0] = (char)(format_id);
1997 fourcc[1] = (char)(format_id >> 8);
1998 fourcc[2] = (char)(format_id >> 16);
1999 fourcc[3] = (char)(format_id >> 24);
2001 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
2002 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
2004 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
2006 return "unrecognized";
2010 const char *debug_d3ddevicetype(enum wined3d_device_type device_type)
2012 switch (device_type)
2014 #define DEVTYPE_TO_STR(dev) case dev: return #dev
2015 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_HAL);
2016 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_REF);
2017 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_SW);
2018 #undef DEVTYPE_TO_STR
2020 FIXME("Unrecognized device type %#x.\n", device_type);
2021 return "unrecognized";
2025 const char *debug_d3dusage(DWORD usage)
2030 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
2031 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
2032 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
2033 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
2034 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
2035 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
2036 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
2037 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
2038 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
2039 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
2040 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
2041 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
2042 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
2043 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
2044 #undef WINED3DUSAGE_TO_STR
2045 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
2047 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2050 const char *debug_d3dusagequery(DWORD usagequery)
2055 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
2056 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
2057 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
2058 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
2059 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
2060 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
2061 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
2062 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
2063 #undef WINED3DUSAGEQUERY_TO_STR
2064 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
2066 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2069 const char *debug_d3ddeclmethod(enum wined3d_decl_method method)
2073 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
2074 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_DEFAULT);
2075 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_U);
2076 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_V);
2077 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_CROSS_UV);
2078 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_UV);
2079 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP);
2080 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP_PRESAMPLED);
2081 #undef WINED3DDECLMETHOD_TO_STR
2083 FIXME("Unrecognized declaration method %#x.\n", method);
2084 return "unrecognized";
2088 const char *debug_d3ddeclusage(enum wined3d_decl_usage usage)
2092 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
2093 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITION);
2094 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_WEIGHT);
2095 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_INDICES);
2096 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_NORMAL);
2097 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_PSIZE);
2098 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TEXCOORD);
2099 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TANGENT);
2100 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BINORMAL);
2101 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TESS_FACTOR);
2102 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITIONT);
2103 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_COLOR);
2104 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_FOG);
2105 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_DEPTH);
2106 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_SAMPLE);
2107 #undef WINED3DDECLUSAGE_TO_STR
2109 FIXME("Unrecognized %u declaration usage!\n", usage);
2110 return "unrecognized";
2114 const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
2116 switch (resource_type)
2118 #define RES_TO_STR(res) case res: return #res
2119 RES_TO_STR(WINED3D_RTYPE_SURFACE);
2120 RES_TO_STR(WINED3D_RTYPE_VOLUME);
2121 RES_TO_STR(WINED3D_RTYPE_TEXTURE);
2122 RES_TO_STR(WINED3D_RTYPE_VOLUME_TEXTURE);
2123 RES_TO_STR(WINED3D_RTYPE_CUBE_TEXTURE);
2124 RES_TO_STR(WINED3D_RTYPE_BUFFER);
2127 FIXME("Unrecognized resource type %#x.\n", resource_type);
2128 return "unrecognized";
2132 const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type)
2134 switch (primitive_type)
2136 #define PRIM_TO_STR(prim) case prim: return #prim
2137 PRIM_TO_STR(WINED3D_PT_UNDEFINED);
2138 PRIM_TO_STR(WINED3D_PT_POINTLIST);
2139 PRIM_TO_STR(WINED3D_PT_LINELIST);
2140 PRIM_TO_STR(WINED3D_PT_LINESTRIP);
2141 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST);
2142 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP);
2143 PRIM_TO_STR(WINED3D_PT_TRIANGLEFAN);
2144 PRIM_TO_STR(WINED3D_PT_LINELIST_ADJ);
2145 PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ);
2146 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ);
2147 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ);
2150 FIXME("Unrecognized %u primitive type!\n", primitive_type);
2151 return "unrecognized";
2155 const char *debug_d3drenderstate(enum wined3d_render_state state)
2159 #define D3DSTATE_TO_STR(u) case u: return #u
2160 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIAS);
2161 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREPERSPECTIVE);
2162 D3DSTATE_TO_STR(WINED3D_RS_WRAPU);
2163 D3DSTATE_TO_STR(WINED3D_RS_WRAPV);
2164 D3DSTATE_TO_STR(WINED3D_RS_ZENABLE);
2165 D3DSTATE_TO_STR(WINED3D_RS_FILLMODE);
2166 D3DSTATE_TO_STR(WINED3D_RS_SHADEMODE);
2167 D3DSTATE_TO_STR(WINED3D_RS_LINEPATTERN);
2168 D3DSTATE_TO_STR(WINED3D_RS_MONOENABLE);
2169 D3DSTATE_TO_STR(WINED3D_RS_ROP2);
2170 D3DSTATE_TO_STR(WINED3D_RS_PLANEMASK);
2171 D3DSTATE_TO_STR(WINED3D_RS_ZWRITEENABLE);
2172 D3DSTATE_TO_STR(WINED3D_RS_ALPHATESTENABLE);
2173 D3DSTATE_TO_STR(WINED3D_RS_LASTPIXEL);
2174 D3DSTATE_TO_STR(WINED3D_RS_SRCBLEND);
2175 D3DSTATE_TO_STR(WINED3D_RS_DESTBLEND);
2176 D3DSTATE_TO_STR(WINED3D_RS_CULLMODE);
2177 D3DSTATE_TO_STR(WINED3D_RS_ZFUNC);
2178 D3DSTATE_TO_STR(WINED3D_RS_ALPHAREF);
2179 D3DSTATE_TO_STR(WINED3D_RS_ALPHAFUNC);
2180 D3DSTATE_TO_STR(WINED3D_RS_DITHERENABLE);
2181 D3DSTATE_TO_STR(WINED3D_RS_ALPHABLENDENABLE);
2182 D3DSTATE_TO_STR(WINED3D_RS_FOGENABLE);
2183 D3DSTATE_TO_STR(WINED3D_RS_SPECULARENABLE);
2184 D3DSTATE_TO_STR(WINED3D_RS_ZVISIBLE);
2185 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXEL);
2186 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXELX);
2187 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEDALPHA);
2188 D3DSTATE_TO_STR(WINED3D_RS_FOGCOLOR);
2189 D3DSTATE_TO_STR(WINED3D_RS_FOGTABLEMODE);
2190 D3DSTATE_TO_STR(WINED3D_RS_FOGSTART);
2191 D3DSTATE_TO_STR(WINED3D_RS_FOGEND);
2192 D3DSTATE_TO_STR(WINED3D_RS_FOGDENSITY);
2193 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEENABLE);
2194 D3DSTATE_TO_STR(WINED3D_RS_EDGEANTIALIAS);
2195 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYENABLE);
2196 D3DSTATE_TO_STR(WINED3D_RS_MIPMAPLODBIAS);
2197 D3DSTATE_TO_STR(WINED3D_RS_RANGEFOGENABLE);
2198 D3DSTATE_TO_STR(WINED3D_RS_ANISOTROPY);
2199 D3DSTATE_TO_STR(WINED3D_RS_FLUSHBATCH);
2200 D3DSTATE_TO_STR(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT);
2201 D3DSTATE_TO_STR(WINED3D_RS_STENCILENABLE);
2202 D3DSTATE_TO_STR(WINED3D_RS_STENCILFAIL);
2203 D3DSTATE_TO_STR(WINED3D_RS_STENCILZFAIL);
2204 D3DSTATE_TO_STR(WINED3D_RS_STENCILPASS);
2205 D3DSTATE_TO_STR(WINED3D_RS_STENCILFUNC);
2206 D3DSTATE_TO_STR(WINED3D_RS_STENCILREF);
2207 D3DSTATE_TO_STR(WINED3D_RS_STENCILMASK);
2208 D3DSTATE_TO_STR(WINED3D_RS_STENCILWRITEMASK);
2209 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREFACTOR);
2210 D3DSTATE_TO_STR(WINED3D_RS_WRAP0);
2211 D3DSTATE_TO_STR(WINED3D_RS_WRAP1);
2212 D3DSTATE_TO_STR(WINED3D_RS_WRAP2);
2213 D3DSTATE_TO_STR(WINED3D_RS_WRAP3);
2214 D3DSTATE_TO_STR(WINED3D_RS_WRAP4);
2215 D3DSTATE_TO_STR(WINED3D_RS_WRAP5);
2216 D3DSTATE_TO_STR(WINED3D_RS_WRAP6);
2217 D3DSTATE_TO_STR(WINED3D_RS_WRAP7);
2218 D3DSTATE_TO_STR(WINED3D_RS_CLIPPING);
2219 D3DSTATE_TO_STR(WINED3D_RS_LIGHTING);
2220 D3DSTATE_TO_STR(WINED3D_RS_EXTENTS);
2221 D3DSTATE_TO_STR(WINED3D_RS_AMBIENT);
2222 D3DSTATE_TO_STR(WINED3D_RS_FOGVERTEXMODE);
2223 D3DSTATE_TO_STR(WINED3D_RS_COLORVERTEX);
2224 D3DSTATE_TO_STR(WINED3D_RS_LOCALVIEWER);
2225 D3DSTATE_TO_STR(WINED3D_RS_NORMALIZENORMALS);
2226 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYBLENDENABLE);
2227 D3DSTATE_TO_STR(WINED3D_RS_DIFFUSEMATERIALSOURCE);
2228 D3DSTATE_TO_STR(WINED3D_RS_SPECULARMATERIALSOURCE);
2229 D3DSTATE_TO_STR(WINED3D_RS_AMBIENTMATERIALSOURCE);
2230 D3DSTATE_TO_STR(WINED3D_RS_EMISSIVEMATERIALSOURCE);
2231 D3DSTATE_TO_STR(WINED3D_RS_VERTEXBLEND);
2232 D3DSTATE_TO_STR(WINED3D_RS_CLIPPLANEENABLE);
2233 D3DSTATE_TO_STR(WINED3D_RS_SOFTWAREVERTEXPROCESSING);
2234 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE);
2235 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MIN);
2236 D3DSTATE_TO_STR(WINED3D_RS_POINTSPRITEENABLE);
2237 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALEENABLE);
2238 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_A);
2239 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_B);
2240 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_C);
2241 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEANTIALIAS);
2242 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEMASK);
2243 D3DSTATE_TO_STR(WINED3D_RS_PATCHEDGESTYLE);
2244 D3DSTATE_TO_STR(WINED3D_RS_PATCHSEGMENTS);
2245 D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN);
2246 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX);
2247 D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE);
2248 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
2249 D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR);
2250 D3DSTATE_TO_STR(WINED3D_RS_BLENDOP);
2251 D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE);
2252 D3DSTATE_TO_STR(WINED3D_RS_NORMALDEGREE);
2253 D3DSTATE_TO_STR(WINED3D_RS_SCISSORTESTENABLE);
2254 D3DSTATE_TO_STR(WINED3D_RS_SLOPESCALEDEPTHBIAS);
2255 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIASEDLINEENABLE);
2256 D3DSTATE_TO_STR(WINED3D_RS_MINTESSELLATIONLEVEL);
2257 D3DSTATE_TO_STR(WINED3D_RS_MAXTESSELLATIONLEVEL);
2258 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_X);
2259 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Y);
2260 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Z);
2261 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_W);
2262 D3DSTATE_TO_STR(WINED3D_RS_ENABLEADAPTIVETESSELLATION);
2263 D3DSTATE_TO_STR(WINED3D_RS_TWOSIDEDSTENCILMODE);
2264 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFAIL);
2265 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILZFAIL);
2266 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILPASS);
2267 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFUNC);
2268 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1);
2269 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2);
2270 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3);
2271 D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR);
2272 D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE);
2273 D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS);
2274 D3DSTATE_TO_STR(WINED3D_RS_WRAP8);
2275 D3DSTATE_TO_STR(WINED3D_RS_WRAP9);
2276 D3DSTATE_TO_STR(WINED3D_RS_WRAP10);
2277 D3DSTATE_TO_STR(WINED3D_RS_WRAP11);
2278 D3DSTATE_TO_STR(WINED3D_RS_WRAP12);
2279 D3DSTATE_TO_STR(WINED3D_RS_WRAP13);
2280 D3DSTATE_TO_STR(WINED3D_RS_WRAP14);
2281 D3DSTATE_TO_STR(WINED3D_RS_WRAP15);
2282 D3DSTATE_TO_STR(WINED3D_RS_SEPARATEALPHABLENDENABLE);
2283 D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
2284 D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
2285 D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
2286 #undef D3DSTATE_TO_STR
2288 FIXME("Unrecognized %u render state!\n", state);
2289 return "unrecognized";
2293 const char *debug_d3dsamplerstate(enum wined3d_sampler_state state)
2297 #define D3DSTATE_TO_STR(u) case u: return #u
2298 D3DSTATE_TO_STR(WINED3D_SAMP_BORDER_COLOR);
2299 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_U);
2300 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_V);
2301 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_W);
2302 D3DSTATE_TO_STR(WINED3D_SAMP_MAG_FILTER);
2303 D3DSTATE_TO_STR(WINED3D_SAMP_MIN_FILTER);
2304 D3DSTATE_TO_STR(WINED3D_SAMP_MIP_FILTER);
2305 D3DSTATE_TO_STR(WINED3D_SAMP_MIPMAP_LOD_BIAS);
2306 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_MIP_LEVEL);
2307 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_ANISOTROPY);
2308 D3DSTATE_TO_STR(WINED3D_SAMP_SRGB_TEXTURE);
2309 D3DSTATE_TO_STR(WINED3D_SAMP_ELEMENT_INDEX);
2310 D3DSTATE_TO_STR(WINED3D_SAMP_DMAP_OFFSET);
2311 #undef D3DSTATE_TO_STR
2313 FIXME("Unrecognized %u sampler state!\n", state);
2314 return "unrecognized";
2318 const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type)
2320 switch (filter_type)
2322 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2323 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_NONE);
2324 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_POINT);
2325 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_LINEAR);
2326 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_ANISOTROPIC);
2327 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_FLAT_CUBIC);
2328 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_CUBIC);
2329 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_PYRAMIDAL_QUAD);
2330 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_QUAD);
2331 #undef D3DTEXTUREFILTERTYPE_TO_STR
2333 FIXME("Unrecognied texture filter type 0x%08x.\n", filter_type);
2334 return "unrecognized";
2338 const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state)
2342 #define D3DSTATE_TO_STR(u) case u: return #u
2343 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_OP);
2344 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG1);
2345 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG2);
2346 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_OP);
2347 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG1);
2348 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG2);
2349 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT00);
2350 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT01);
2351 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT10);
2352 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT11);
2353 D3DSTATE_TO_STR(WINED3D_TSS_TEXCOORD_INDEX);
2354 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LSCALE);
2355 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LOFFSET);
2356 D3DSTATE_TO_STR(WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS);
2357 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG0);
2358 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG0);
2359 D3DSTATE_TO_STR(WINED3D_TSS_RESULT_ARG);
2360 D3DSTATE_TO_STR(WINED3D_TSS_CONSTANT);
2361 #undef D3DSTATE_TO_STR
2363 FIXME("Unrecognized %u texture state!\n", state);
2364 return "unrecognized";
2368 const char *debug_d3dtop(enum wined3d_texture_op d3dtop)
2372 #define D3DTOP_TO_STR(u) case u: return #u
2373 D3DTOP_TO_STR(WINED3D_TOP_DISABLE);
2374 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG1);
2375 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG2);
2376 D3DTOP_TO_STR(WINED3D_TOP_MODULATE);
2377 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_2X);
2378 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_4X);
2379 D3DTOP_TO_STR(WINED3D_TOP_ADD);
2380 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED);
2381 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED_2X);
2382 D3DTOP_TO_STR(WINED3D_TOP_SUBTRACT);
2383 D3DTOP_TO_STR(WINED3D_TOP_ADD_SMOOTH);
2384 D3DTOP_TO_STR(WINED3D_TOP_BLEND_DIFFUSE_ALPHA);
2385 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA);
2386 D3DTOP_TO_STR(WINED3D_TOP_BLEND_FACTOR_ALPHA);
2387 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM);
2388 D3DTOP_TO_STR(WINED3D_TOP_BLEND_CURRENT_ALPHA);
2389 D3DTOP_TO_STR(WINED3D_TOP_PREMODULATE);
2390 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR);
2391 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA);
2392 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR);
2393 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA);
2394 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP);
2395 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP_LUMINANCE);
2396 D3DTOP_TO_STR(WINED3D_TOP_DOTPRODUCT3);
2397 D3DTOP_TO_STR(WINED3D_TOP_MULTIPLY_ADD);
2398 D3DTOP_TO_STR(WINED3D_TOP_LERP);
2399 #undef D3DTOP_TO_STR
2401 FIXME("Unrecognized texture op %#x.\n", d3dtop);
2402 return "unrecognized";
2406 const char *debug_d3dtstype(enum wined3d_transform_state tstype)
2410 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2411 TSTYPE_TO_STR(WINED3D_TS_VIEW);
2412 TSTYPE_TO_STR(WINED3D_TS_PROJECTION);
2413 TSTYPE_TO_STR(WINED3D_TS_TEXTURE0);
2414 TSTYPE_TO_STR(WINED3D_TS_TEXTURE1);
2415 TSTYPE_TO_STR(WINED3D_TS_TEXTURE2);
2416 TSTYPE_TO_STR(WINED3D_TS_TEXTURE3);
2417 TSTYPE_TO_STR(WINED3D_TS_TEXTURE4);
2418 TSTYPE_TO_STR(WINED3D_TS_TEXTURE5);
2419 TSTYPE_TO_STR(WINED3D_TS_TEXTURE6);
2420 TSTYPE_TO_STR(WINED3D_TS_TEXTURE7);
2421 TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(0));
2422 #undef TSTYPE_TO_STR
2424 if (tstype > 256 && tstype < 512)
2426 FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype);
2427 return ("WINED3D_TS_WORLD_MATRIX > 0");
2429 FIXME("Unrecognized transform state %#x.\n", tstype);
2430 return "unrecognized";
2434 const char *debug_d3dstate(DWORD state)
2436 if (STATE_IS_RENDER(state))
2437 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2438 if (STATE_IS_TEXTURESTAGE(state))
2440 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2441 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2442 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2443 texture_stage, debug_d3dtexturestate(texture_state));
2445 if (STATE_IS_SAMPLER(state))
2446 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2447 if (STATE_IS_PIXELSHADER(state))
2448 return "STATE_PIXELSHADER";
2449 if (STATE_IS_TRANSFORM(state))
2450 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2451 if (STATE_IS_STREAMSRC(state))
2452 return "STATE_STREAMSRC";
2453 if (STATE_IS_INDEXBUFFER(state))
2454 return "STATE_INDEXBUFFER";
2455 if (STATE_IS_VDECL(state))
2456 return "STATE_VDECL";
2457 if (STATE_IS_VSHADER(state))
2458 return "STATE_VSHADER";
2459 if (STATE_IS_GEOMETRY_SHADER(state))
2460 return "STATE_GEOMETRY_SHADER";
2461 if (STATE_IS_VIEWPORT(state))
2462 return "STATE_VIEWPORT";
2463 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2464 return "STATE_VERTEXSHADERCONSTANT";
2465 if (STATE_IS_PIXELSHADERCONSTANT(state))
2466 return "STATE_PIXELSHADERCONSTANT";
2467 if (STATE_IS_ACTIVELIGHT(state))
2468 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2469 if (STATE_IS_SCISSORRECT(state))
2470 return "STATE_SCISSORRECT";
2471 if (STATE_IS_CLIPPLANE(state))
2472 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2473 if (STATE_IS_MATERIAL(state))
2474 return "STATE_MATERIAL";
2475 if (STATE_IS_FRONTFACE(state))
2476 return "STATE_FRONTFACE";
2477 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2478 return "STATE_POINTSPRITECOORDORIGIN";
2479 if (STATE_IS_BASEVERTEXINDEX(state))
2480 return "STATE_BASEVERTEXINDEX";
2481 if (STATE_IS_FRAMEBUFFER(state))
2482 return "STATE_FRAMEBUFFER";
2484 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2487 const char *debug_d3dpool(enum wined3d_pool pool)
2491 #define POOL_TO_STR(p) case p: return #p
2492 POOL_TO_STR(WINED3D_POOL_DEFAULT);
2493 POOL_TO_STR(WINED3D_POOL_MANAGED);
2494 POOL_TO_STR(WINED3D_POOL_SYSTEM_MEM);
2495 POOL_TO_STR(WINED3D_POOL_SCRATCH);
2498 FIXME("Unrecognized pool %#x.\n", pool);
2499 return "unrecognized";
2503 const char *debug_fbostatus(GLenum status) {
2505 #define FBOSTATUS_TO_STR(u) case u: return #u
2506 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2507 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2508 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2509 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2510 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2511 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2512 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2513 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2514 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2515 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2516 #undef FBOSTATUS_TO_STR
2518 FIXME("Unrecognied FBO status 0x%08x\n", status);
2519 return "unrecognized";
2523 const char *debug_glerror(GLenum error) {
2525 #define GLERROR_TO_STR(u) case u: return #u
2526 GLERROR_TO_STR(GL_NO_ERROR);
2527 GLERROR_TO_STR(GL_INVALID_ENUM);
2528 GLERROR_TO_STR(GL_INVALID_VALUE);
2529 GLERROR_TO_STR(GL_INVALID_OPERATION);
2530 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2531 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2532 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2533 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2534 #undef GLERROR_TO_STR
2536 FIXME("Unrecognied GL error 0x%08x\n", error);
2537 return "unrecognized";
2541 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2545 #define WINED3D_TO_STR(x) case x: return #x
2546 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2547 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2548 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2549 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2550 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2551 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2552 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2553 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2554 #undef WINED3D_TO_STR
2556 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2557 return "unrecognized";
2561 static const char *debug_complex_fixup(enum complex_fixup fixup)
2565 #define WINED3D_TO_STR(x) case x: return #x
2566 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2567 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2568 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2569 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2570 #undef WINED3D_TO_STR
2572 FIXME("Unrecognized complex fixup %#x\n", fixup);
2573 return "unrecognized";
2577 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2579 if (is_complex_fixup(fixup))
2581 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2585 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2586 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2587 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2588 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2591 const char *debug_surflocation(DWORD flag) {
2595 if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM"); /* 17 */
2596 if (flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE"); /* 19 */
2597 if (flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE"); /* 18 */
2598 if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX"); /* 18 */
2599 if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE"); /* 25 */
2600 if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED"); /* 22 */
2601 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2604 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2605 enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2607 if (op == WINED3D_TOP_DISABLE)
2609 if (state->textures[stage])
2612 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2613 && op != WINED3D_TOP_SELECT_ARG2)
2615 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2616 && op != WINED3D_TOP_SELECT_ARG1)
2618 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2619 && (op == WINED3D_TOP_MULTIPLY_ADD || op == WINED3D_TOP_LERP))
2625 /* Setup this textures matrix according to the texture flags. */
2626 /* Context activation is done by the caller (state handler). */
2627 void set_texture_matrix(const struct wined3d_gl_info *gl_info, const float *smat, DWORD flags,
2628 BOOL calculatedCoords, BOOL transformed, enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2632 gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
2633 checkGLcall("glMatrixMode(GL_TEXTURE)");
2635 if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed)
2637 gl_info->gl_ops.gl.p_glLoadIdentity();
2638 checkGLcall("glLoadIdentity()");
2642 if (flags == (WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED))
2644 ERR("Invalid texture transform flags: WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED.\n");
2648 memcpy(mat, smat, 16 * sizeof(float));
2650 if (flags & WINED3D_TTFF_PROJECTED)
2652 if (!ffp_proj_control)
2654 switch (flags & ~WINED3D_TTFF_PROJECTED)
2656 case WINED3D_TTFF_COUNT2:
2661 mat[ 1] = mat[ 5] = mat[ 9] = mat[13] = 0.0f;
2663 case WINED3D_TTFF_COUNT3:
2668 mat[ 2] = mat[ 6] = mat[10] = mat[14] = 0.0f;
2672 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2673 if(!calculatedCoords) {
2676 case WINED3DFMT_R32_FLOAT:
2677 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2678 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2679 * the input value to the transformation will be 0, so the matrix value is irrelevant
2686 case WINED3DFMT_R32G32_FLOAT:
2687 /* See above, just 3rd and 4th coord
2694 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2695 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2697 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2698 * into a bad place. The division elimination below will apply to make sure the
2699 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2701 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2704 FIXME("Unexpected fixed function texture coord input\n");
2707 if (!ffp_proj_control)
2709 switch (flags & ~WINED3D_TTFF_PROJECTED)
2711 /* case WINED3D_TTFF_COUNT1: Won't ever get here. */
2712 case WINED3D_TTFF_COUNT2:
2713 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2714 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2715 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2716 * the 4th coord evaluates to 1.0 to eliminate that.
2718 * If the fixed function pipeline is used, the 4th value remains unused,
2719 * so there is no danger in doing this. With vertex shaders we have a
2720 * problem. Should an app hit that problem, the code here would have to
2721 * check for pixel shaders, and the shader has to undo the default gl divide.
2723 * A more serious problem occurs if the app passes 4 coordinates in, and the
2724 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2725 * or a replacement shader. */
2727 mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2732 gl_info->gl_ops.gl.p_glLoadMatrixf(mat);
2733 checkGLcall("glLoadMatrixf(mat)");
2736 /* This small helper function is used to convert a bitmask into the number of masked bits */
2737 unsigned int count_bits(unsigned int mask)
2740 for (count = 0; mask; ++count)
2747 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2748 * The later function requires individual color components. */
2749 BOOL getColorBits(const struct wined3d_format *format,
2750 BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2752 TRACE("format %s.\n", debug_d3dformat(format->id));
2756 case WINED3DFMT_B10G10R10A2_UNORM:
2757 case WINED3DFMT_R10G10B10A2_UNORM:
2758 case WINED3DFMT_B8G8R8X8_UNORM:
2759 case WINED3DFMT_B8G8R8_UNORM:
2760 case WINED3DFMT_B8G8R8A8_UNORM:
2761 case WINED3DFMT_R8G8B8A8_UNORM:
2762 case WINED3DFMT_B5G5R5X1_UNORM:
2763 case WINED3DFMT_B5G5R5A1_UNORM:
2764 case WINED3DFMT_B5G6R5_UNORM:
2765 case WINED3DFMT_B4G4R4X4_UNORM:
2766 case WINED3DFMT_B4G4R4A4_UNORM:
2767 case WINED3DFMT_B2G3R3_UNORM:
2768 case WINED3DFMT_P8_UINT_A8_UNORM:
2769 case WINED3DFMT_P8_UINT:
2772 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2776 *redSize = format->red_size;
2777 *greenSize = format->green_size;
2778 *blueSize = format->blue_size;
2779 *alphaSize = format->alpha_size;
2780 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2782 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2783 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2787 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2788 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
2790 TRACE("format %s.\n", debug_d3dformat(format->id));
2794 case WINED3DFMT_D16_LOCKABLE:
2795 case WINED3DFMT_D16_UNORM:
2796 case WINED3DFMT_S1_UINT_D15_UNORM:
2797 case WINED3DFMT_X8D24_UNORM:
2798 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2799 case WINED3DFMT_D24_UNORM_S8_UINT:
2800 case WINED3DFMT_S8_UINT_D24_FLOAT:
2801 case WINED3DFMT_D32_UNORM:
2802 case WINED3DFMT_D32_FLOAT:
2803 case WINED3DFMT_INTZ:
2806 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2810 *depthSize = format->depth_size;
2811 *stencilSize = format->stencil_size;
2813 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2814 *depthSize, *stencilSize, debug_d3dformat(format->id));
2818 /* Note: It's the caller's responsibility to ensure values can be expressed
2819 * in the requested format. UNORM formats for example can only express values
2820 * in the range 0.0f -> 1.0f. */
2821 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color)
2825 enum wined3d_format_id format_id;
2837 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2838 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2839 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2840 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2841 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2842 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2843 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2844 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2845 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2846 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2847 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2848 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2849 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2850 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2852 const struct wined3d_format *format = surface->resource.format;
2855 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2856 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2858 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2862 if (format->id != conv[i].format_id) continue;
2864 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2865 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2866 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2867 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2869 TRACE("Returning 0x%08x.\n", ret);
2874 if (format->id == WINED3DFMT_P8_UINT)
2879 if (!surface->palette)
2881 WARN("Surface doesn't have a palette, returning 0.\n");
2885 r = (BYTE)((color->r * 255.0f) + 0.5f);
2886 g = (BYTE)((color->g * 255.0f) + 0.5f);
2887 b = (BYTE)((color->b * 255.0f) + 0.5f);
2888 a = (BYTE)((color->a * 255.0f) + 0.5f);
2890 e = &surface->palette->palents[a];
2891 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2894 WARN("Alpha didn't match index, searching full palette.\n");
2896 for (i = 0; i < 256; ++i)
2898 e = &surface->palette->palents[i];
2899 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2903 FIXME("Unable to convert color to palette index.\n");
2908 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2913 /* DirectDraw stuff */
2914 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2918 case 8: return WINED3DFMT_P8_UINT;
2919 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2920 case 16: return WINED3DFMT_B5G6R5_UNORM;
2921 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2922 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2923 default: return WINED3DFMT_UNKNOWN;
2927 void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
2928 const struct wined3d_matrix *src2)
2930 struct wined3d_matrix temp;
2932 /* Now do the multiplication 'by hand'.
2933 I know that all this could be optimised, but this will be done later :-) */
2934 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);
2935 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);
2936 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);
2937 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);
2939 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);
2940 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);
2941 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);
2942 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);
2944 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);
2945 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);
2946 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);
2947 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);
2949 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);
2950 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);
2951 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);
2952 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);
2954 /* And copy the new matrix in the good storage.. */
2955 memcpy(dest, &temp, 16 * sizeof(float));
2958 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2961 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2963 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2964 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2965 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2966 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2967 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2968 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2969 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2970 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2971 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2972 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2973 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2974 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2975 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2976 default: ERR("Unexpected position mask\n");
2978 for (i = 0; i < numTextures; i++) {
2979 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2985 void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_state *state,
2986 struct ffp_frag_settings *settings, BOOL ignore_textype)
2991 static const unsigned char args[WINED3D_TOP_LERP + 1] =
2994 /* D3DTOP_DISABLE */ 0,
2995 /* D3DTOP_SELECTARG1 */ ARG1,
2996 /* D3DTOP_SELECTARG2 */ ARG2,
2997 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2998 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2999 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
3000 /* D3DTOP_ADD */ ARG1 | ARG2,
3001 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
3002 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
3003 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
3004 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
3005 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
3006 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
3007 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
3008 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
3009 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
3010 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
3011 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
3012 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
3013 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
3014 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
3015 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
3016 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
3017 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
3018 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
3019 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
3023 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
3024 const struct wined3d_surface *rt = state->fb->render_targets[0];
3025 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
3027 for (i = 0; i < gl_info->limits.texture_stages; ++i)
3029 const struct wined3d_texture *texture;
3031 settings->op[i].padding = 0;
3032 if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
3034 settings->op[i].cop = WINED3D_TOP_DISABLE;
3035 settings->op[i].aop = WINED3D_TOP_DISABLE;
3036 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
3037 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
3038 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
3039 settings->op[i].dst = resultreg;
3040 settings->op[i].tex_type = tex_1d;
3041 settings->op[i].projected = proj_none;
3046 if ((texture = state->textures[i]))
3048 settings->op[i].color_fixup = texture->resource.format->color_fixup;
3051 settings->op[i].tex_type = tex_1d;
3055 switch (texture->target)
3058 settings->op[i].tex_type = tex_1d;
3061 settings->op[i].tex_type = tex_2d;
3064 settings->op[i].tex_type = tex_3d;
3066 case GL_TEXTURE_CUBE_MAP_ARB:
3067 settings->op[i].tex_type = tex_cube;
3069 case GL_TEXTURE_RECTANGLE_ARB:
3070 settings->op[i].tex_type = tex_rect;
3075 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
3076 settings->op[i].tex_type = tex_1d;
3079 cop = state->texture_states[i][WINED3D_TSS_COLOR_OP];
3080 aop = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
3082 carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG1] : ARG_UNUSED;
3083 carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG2] : ARG_UNUSED;
3084 carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG0] : ARG_UNUSED;
3086 if (is_invalid_op(state, i, cop, carg1, carg2, carg0))
3090 carg1 = WINED3DTA_CURRENT;
3091 cop = WINED3D_TOP_SELECT_ARG1;
3094 if (cop == WINED3D_TOP_DOTPRODUCT3)
3096 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
3097 * the color result to the alpha component of the destination
3106 aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] : ARG_UNUSED;
3107 aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] : ARG_UNUSED;
3108 aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] : ARG_UNUSED;
3111 if (!i && state->textures[0] && state->render_states[WINED3D_RS_COLORKEYENABLE])
3113 GLenum texture_dimensions;
3115 texture = state->textures[0];
3116 texture_dimensions = texture->target;
3118 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3120 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3122 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size)
3124 if (aop == WINED3D_TOP_DISABLE)
3126 aarg1 = WINED3DTA_TEXTURE;
3127 aop = WINED3D_TOP_SELECT_ARG1;
3129 else if (aop == WINED3D_TOP_SELECT_ARG1 && aarg1 != WINED3DTA_TEXTURE)
3131 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3133 aarg2 = WINED3DTA_TEXTURE;
3134 aop = WINED3D_TOP_MODULATE;
3136 else aarg1 = WINED3DTA_TEXTURE;
3138 else if (aop == WINED3D_TOP_SELECT_ARG2 && aarg2 != WINED3DTA_TEXTURE)
3140 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3142 aarg1 = WINED3DTA_TEXTURE;
3143 aop = WINED3D_TOP_MODULATE;
3145 else aarg2 = WINED3DTA_TEXTURE;
3151 if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0))
3155 aarg1 = WINED3DTA_CURRENT;
3156 aop = WINED3D_TOP_SELECT_ARG1;
3159 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
3160 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
3162 ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
3163 if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3))
3164 settings->op[i].projected = proj_count3;
3165 else if (ttff & WINED3D_TTFF_PROJECTED)
3166 settings->op[i].projected = proj_count4;
3168 settings->op[i].projected = proj_none;
3172 settings->op[i].projected = proj_none;
3175 settings->op[i].cop = cop;
3176 settings->op[i].aop = aop;
3177 settings->op[i].carg0 = carg0;
3178 settings->op[i].carg1 = carg1;
3179 settings->op[i].carg2 = carg2;
3180 settings->op[i].aarg0 = aarg0;
3181 settings->op[i].aarg1 = aarg1;
3182 settings->op[i].aarg2 = aarg2;
3184 if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP)
3185 settings->op[i].dst = tempreg;
3187 settings->op[i].dst = resultreg;
3190 /* Clear unsupported stages */
3191 for(; i < MAX_TEXTURES; i++) {
3192 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
3195 if (!state->render_states[WINED3D_RS_FOGENABLE])
3197 settings->fog = FOG_OFF;
3199 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
3201 if (use_vs(state) || state->vertex_declaration->position_transformed)
3203 settings->fog = FOG_LINEAR;
3207 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
3209 case WINED3D_FOG_NONE:
3210 case WINED3D_FOG_LINEAR:
3211 settings->fog = FOG_LINEAR;
3213 case WINED3D_FOG_EXP:
3214 settings->fog = FOG_EXP;
3216 case WINED3D_FOG_EXP2:
3217 settings->fog = FOG_EXP2;
3224 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
3226 case WINED3D_FOG_LINEAR:
3227 settings->fog = FOG_LINEAR;
3229 case WINED3D_FOG_EXP:
3230 settings->fog = FOG_EXP;
3232 case WINED3D_FOG_EXP2:
3233 settings->fog = FOG_EXP2;
3237 if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB]
3238 && state->render_states[WINED3D_RS_SRGBWRITEENABLE]
3239 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
3241 settings->sRGB_write = 1;
3243 settings->sRGB_write = 0;
3245 if (device->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
3246 || !state->render_states[WINED3D_RS_CLIPPLANEENABLE])
3248 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3249 * the fixed function vertex pipeline is used(which always supports clipplanes), or
3250 * if no clipplane is enabled
3252 settings->emul_clipplanes = 0;
3254 settings->emul_clipplanes = 1;
3258 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3259 const struct ffp_frag_settings *settings)
3261 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3262 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3265 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3267 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3268 * whereas desc points to an extended structure with implementation specific parts. */
3269 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3271 ERR("Failed to insert ffp frag shader.\n");
3275 /* Activates the texture dimension according to the bound D3D texture. Does
3276 * not care for the colorop or correct gl texture unit (when using nvrc).
3277 * Requires the caller to activate the correct unit. */
3278 /* Context activation is done by the caller (state handler). */
3279 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3283 switch (texture->target)
3286 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3287 checkGLcall("glDisable(GL_TEXTURE_3D)");
3288 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3290 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3291 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3293 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3295 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3296 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3298 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3299 checkGLcall("glEnable(GL_TEXTURE_2D)");
3301 case GL_TEXTURE_RECTANGLE_ARB:
3302 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3303 checkGLcall("glDisable(GL_TEXTURE_2D)");
3304 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3305 checkGLcall("glDisable(GL_TEXTURE_3D)");
3306 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3308 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3309 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3311 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_RECTANGLE_ARB);
3312 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3315 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3317 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3318 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3320 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3322 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3323 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3325 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3326 checkGLcall("glDisable(GL_TEXTURE_2D)");
3327 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D);
3328 checkGLcall("glEnable(GL_TEXTURE_3D)");
3330 case GL_TEXTURE_CUBE_MAP_ARB:
3331 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3332 checkGLcall("glDisable(GL_TEXTURE_2D)");
3333 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3334 checkGLcall("glDisable(GL_TEXTURE_3D)");
3335 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3337 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3338 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3340 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3341 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3347 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3348 checkGLcall("glEnable(GL_TEXTURE_2D)");
3349 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3350 checkGLcall("glDisable(GL_TEXTURE_3D)");
3351 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3353 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3354 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3356 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3358 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3359 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3361 /* Binding textures is done by samplers. A dummy texture will be bound */
3365 /* Context activation is done by the caller (state handler). */
3366 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3368 DWORD sampler = state_id - STATE_SAMPLER(0);
3369 DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
3371 /* No need to enable / disable anything here for unused samplers. The
3372 * tex_colorop handler takes care. Also no action is needed with pixel
3373 * shaders, or if tex_colorop will take care of this business. */
3374 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
3376 if (sampler >= state->lowest_disabled_stage)
3378 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)))
3381 texture_activate_dimensions(state->textures[sampler], context->gl_info);
3384 void *wined3d_rb_alloc(size_t size)
3386 return HeapAlloc(GetProcessHeap(), 0, size);
3389 void *wined3d_rb_realloc(void *ptr, size_t size)
3391 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3394 void wined3d_rb_free(void *ptr)
3396 HeapFree(GetProcessHeap(), 0, ptr);
3399 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3401 const struct ffp_frag_settings *ka = key;
3402 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3404 return memcmp(ka, kb, sizeof(*ka));
3407 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3412 ffp_frag_program_key_compare,
3415 UINT wined3d_log2i(UINT32 x)
3417 static const UINT l[] =
3419 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3420 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3421 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3422 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3423 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3424 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3425 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3426 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3427 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3428 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3429 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3430 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3431 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3432 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3433 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3434 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3438 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3441 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3442 const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
3443 const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
3445 static const struct blit_shader * const blitters[] =
3453 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3455 if (blitters[i]->blit_supported(gl_info, blit_op,
3456 src_rect, src_usage, src_pool, src_format,
3457 dst_rect, dst_usage, dst_pool, dst_format))
3464 void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
3466 const struct wined3d_viewport *vp = &state->viewport;
3468 SetRect(rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
3470 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
3471 IntersectRect(rect, rect, &state->scissor_rect);