[DIRECTX]
[reactos.git] / reactos / dll / directx / wine / wined3d / utils.c
1 /*
2 * Utility functions for the WineD3D Library
3 *
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
11 *
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.
16 *
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.
21 *
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
25 */
26
27 #include "config.h"
28 #include "wine/port.h"
29
30 #include "wined3d_private.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
33
34 struct wined3d_format_channels
35 {
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;
39 UINT bpp;
40 BYTE depth_size, stencil_size;
41 };
42
43 static const struct wined3d_format_channels formats[] =
44 {
45 /* size offset
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},
48 /* FourCC formats */
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},
60 /* IEEE formats */
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},
65 /* Hmm? */
66 {WINED3DFMT_R8G8_SNORM_Cx, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
67 /* Float */
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},
97 /* Luminance */
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_NVHU, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
130 {WINED3DFMT_NVHS, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
131 {WINED3DFMT_NULL, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
132 /* Unsure about them, could not find a Windows driver that supports them */
133 {WINED3DFMT_R16, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
134 {WINED3DFMT_AL16, 0, 0, 0, 16, 0, 0, 0, 16, 4, 0, 0},
135 };
136
137 struct wined3d_format_base_flags
138 {
139 enum wined3d_format_id id;
140 DWORD flags;
141 };
142
143 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
144 * still needs to use the correct block based calculation for e.g. the
145 * resource size. */
146 static const struct wined3d_format_base_flags format_base_flags[] =
147 {
148 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
149 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
150 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
151 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
152 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
153 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
156 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
157 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
158 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
159 {WINED3DFMT_INTZ, WINED3DFMT_FLAG_FOURCC},
160 {WINED3DFMT_NULL, WINED3DFMT_FLAG_FOURCC},
161 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
162 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
163 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
164 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
165 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
166 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
171 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
172 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
173 {WINED3DFMT_NVDB, WINED3DFMT_FLAG_FOURCC},
174 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
175 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
176 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
177 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
178 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
179 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
181 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
182 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
184 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
185 };
186
187 struct wined3d_format_block_info
188 {
189 enum wined3d_format_id id;
190 UINT block_width;
191 UINT block_height;
192 UINT block_byte_count;
193 };
194
195 static const struct wined3d_format_block_info format_block_info[] =
196 {
197 {WINED3DFMT_DXT1, 4, 4, 8},
198 {WINED3DFMT_DXT2, 4, 4, 16},
199 {WINED3DFMT_DXT3, 4, 4, 16},
200 {WINED3DFMT_DXT4, 4, 4, 16},
201 {WINED3DFMT_DXT5, 4, 4, 16},
202 {WINED3DFMT_ATI2N, 4, 4, 16},
203 {WINED3DFMT_YUY2, 2, 1, 4},
204 {WINED3DFMT_UYVY, 2, 1, 4},
205 };
206
207 struct wined3d_format_vertex_info
208 {
209 enum wined3d_format_id id;
210 enum wined3d_ffp_emit_idx emit_idx;
211 GLint component_count;
212 GLenum gl_vtx_type;
213 GLint gl_vtx_format;
214 GLboolean gl_normalized;
215 unsigned int component_size;
216 };
217
218 static const struct wined3d_format_vertex_info format_vertex_info[] =
219 {
220 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
221 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
222 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
223 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
224 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
225 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
226 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
227 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
228 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
229 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
230 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
231 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
232 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
233 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
234 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
235 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
236 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
237 };
238
239 struct wined3d_format_texture_info
240 {
241 enum wined3d_format_id id;
242 GLint gl_internal;
243 GLint gl_srgb_internal;
244 GLint gl_rt_internal;
245 GLint gl_format;
246 GLint gl_type;
247 unsigned int conv_byte_count;
248 unsigned int flags;
249 enum wined3d_gl_extension extension;
250 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
251 };
252
253 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
254 {
255 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
256 * format+type combination to load it. Thus convert it to A8L8, then load it
257 * with A4L4 internal, but A8L8 format+type
258 */
259 unsigned int x, y;
260 const unsigned char *Source;
261 unsigned char *Dest;
262 UINT outpitch = pitch * 2;
263
264 for(y = 0; y < height; y++) {
265 Source = src + y * pitch;
266 Dest = dst + y * outpitch;
267 for (x = 0; x < width; x++ ) {
268 unsigned char color = (*Source++);
269 /* A */ Dest[1] = (color & 0xf0) << 0;
270 /* L */ Dest[0] = (color & 0x0f) << 4;
271 Dest += 2;
272 }
273 }
274 }
275
276 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
277 {
278 unsigned int x, y;
279 const WORD *Source;
280
281 for(y = 0; y < height; y++)
282 {
283 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
284 Source = (const WORD *)(src + y * pitch);
285 for (x = 0; x < width; x++ )
286 {
287 short color = (*Source++);
288 unsigned char l = ((color >> 10) & 0xfc);
289 short v = ((color >> 5) & 0x3e);
290 short u = ((color ) & 0x1f);
291 short v_conv = v + 16;
292 short u_conv = u + 16;
293
294 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
295 Dest_s += 1;
296 }
297 }
298 }
299
300 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
301 {
302 unsigned int x, y;
303 const WORD *Source;
304 unsigned char *Dest;
305 UINT outpitch = (pitch * 3)/2;
306
307 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
308 * fixed function and shaders without further conversion once the surface is
309 * loaded
310 */
311 for(y = 0; y < height; y++) {
312 Source = (const WORD *)(src + y * pitch);
313 Dest = dst + y * outpitch;
314 for (x = 0; x < width; x++ ) {
315 short color = (*Source++);
316 unsigned char l = ((color >> 10) & 0xfc);
317 char v = ((color >> 5) & 0x3e);
318 char u = ((color ) & 0x1f);
319
320 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
321 * and doubles the positive range. Thus shift left only once, gl does the 2nd
322 * shift. GL reads a signed value and converts it into an unsigned value.
323 */
324 /* M */ Dest[2] = l << 1;
325
326 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
327 * from 5 bit values to 8 bit values.
328 */
329 /* V */ Dest[1] = v << 3;
330 /* U */ Dest[0] = u << 3;
331 Dest += 3;
332 }
333 }
334 }
335
336 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
337 {
338 unsigned int x, y;
339 const short *Source;
340 unsigned char *Dest;
341 UINT outpitch = (pitch * 3)/2;
342
343 for(y = 0; y < height; y++)
344 {
345 Source = (const short *)(src + y * pitch);
346 Dest = dst + y * outpitch;
347 for (x = 0; x < width; x++ )
348 {
349 const short color = (*Source++);
350 /* B */ Dest[0] = 0xff;
351 /* G */ Dest[1] = (color >> 8) + 128; /* V */
352 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
353 Dest += 3;
354 }
355 }
356 }
357
358 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
359 {
360 unsigned int x, y;
361 const DWORD *Source;
362 unsigned char *Dest;
363
364 /* Doesn't work correctly with the fixed function pipeline, but can work in
365 * shaders if the shader is adjusted. (There's no use for this format in gl's
366 * standard fixed function pipeline anyway).
367 */
368 for(y = 0; y < height; y++)
369 {
370 Source = (const DWORD *)(src + y * pitch);
371 Dest = dst + y * pitch;
372 for (x = 0; x < width; x++ )
373 {
374 LONG color = (*Source++);
375 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
376 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
377 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
378 Dest += 4;
379 }
380 }
381 }
382
383 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
384 {
385 unsigned int x, y;
386 const DWORD *Source;
387 unsigned char *Dest;
388
389 /* This implementation works with the fixed function pipeline and shaders
390 * without further modification after converting the surface.
391 */
392 for(y = 0; y < height; y++)
393 {
394 Source = (const DWORD *)(src + y * pitch);
395 Dest = dst + y * pitch;
396 for (x = 0; x < width; x++ )
397 {
398 LONG color = (*Source++);
399 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
400 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
401 /* U */ Dest[0] = (color & 0xff); /* U */
402 /* I */ Dest[3] = 255; /* X */
403 Dest += 4;
404 }
405 }
406 }
407
408 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
409 {
410 unsigned int x, y;
411 const DWORD *Source;
412 unsigned char *Dest;
413
414 for(y = 0; y < height; y++)
415 {
416 Source = (const DWORD *)(src + y * pitch);
417 Dest = dst + y * pitch;
418 for (x = 0; x < width; x++ )
419 {
420 LONG color = (*Source++);
421 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
422 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
423 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
424 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
425 Dest += 4;
426 }
427 }
428 }
429
430 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
431 {
432 unsigned int x, y;
433 const DWORD *Source;
434 unsigned short *Dest;
435 UINT outpitch = (pitch * 3)/2;
436
437 for(y = 0; y < height; y++)
438 {
439 Source = (const DWORD *)(src + y * pitch);
440 Dest = (unsigned short *) (dst + y * outpitch);
441 for (x = 0; x < width; x++ )
442 {
443 const DWORD color = (*Source++);
444 /* B */ Dest[0] = 0xffff;
445 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
446 /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */
447 Dest += 3;
448 }
449 }
450 }
451
452 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
453 {
454 unsigned int x, y;
455 const WORD *Source;
456 WORD *Dest;
457 UINT outpitch = (pitch * 3)/2;
458
459 for(y = 0; y < height; y++)
460 {
461 Source = (const WORD *)(src + y * pitch);
462 Dest = (WORD *) (dst + y * outpitch);
463 for (x = 0; x < width; x++ )
464 {
465 WORD green = (*Source++);
466 WORD red = (*Source++);
467 Dest[0] = green;
468 Dest[1] = red;
469 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
470 * shader overwrites it anyway
471 */
472 Dest[2] = 0xffff;
473 Dest += 3;
474 }
475 }
476 }
477
478 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
479 {
480 unsigned int x, y;
481 const float *Source;
482 float *Dest;
483 UINT outpitch = (pitch * 3)/2;
484
485 for(y = 0; y < height; y++)
486 {
487 Source = (const float *)(src + y * pitch);
488 Dest = (float *) (dst + y * outpitch);
489 for (x = 0; x < width; x++ )
490 {
491 float green = (*Source++);
492 float red = (*Source++);
493 Dest[0] = green;
494 Dest[1] = red;
495 Dest[2] = 1.0f;
496 Dest += 3;
497 }
498 }
499 }
500
501 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
502 {
503 unsigned int x, y;
504 UINT outpitch = pitch * 2;
505
506 for (y = 0; y < height; ++y)
507 {
508 const WORD *source = (const WORD *)(src + y * pitch);
509 DWORD *dest = (DWORD *)(dst + y * outpitch);
510
511 for (x = 0; x < width; ++x)
512 {
513 /* The depth data is normalized, so needs to be scaled,
514 * the stencil data isn't. Scale depth data by
515 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
516 WORD d15 = source[x] >> 1;
517 DWORD d24 = (d15 << 9) + (d15 >> 6);
518 dest[x] = (d24 << 8) | (source[x] & 0x1);
519 }
520 }
521 }
522
523 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
524 {
525 unsigned int x, y;
526
527 for (y = 0; y < height; ++y)
528 {
529 const DWORD *source = (const DWORD *)(src + y * pitch);
530 DWORD *dest = (DWORD *)(dst + y * pitch);
531
532 for (x = 0; x < width; ++x)
533 {
534 /* Just need to clear out the X4 part. */
535 dest[x] = source[x] & ~0xf0;
536 }
537 }
538 }
539
540 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
541 {
542 unsigned int x, y;
543 UINT outpitch = pitch * 2;
544
545 for (y = 0; y < height; ++y)
546 {
547 const DWORD *source = (const DWORD *)(src + y * pitch);
548 float *dest_f = (float *)(dst + y * outpitch);
549 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
550
551 for (x = 0; x < width; ++x)
552 {
553 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
554 dest_s[x * 2 + 1] = source[x] & 0xff;
555 }
556 }
557 }
558
559 /* The following formats explicitly don't have WINED3DFMT_FLAG_TEXTURE set:
560 *
561 * These are never supported on native.
562 * WINED3DFMT_B8G8R8_UNORM
563 * WINED3DFMT_B2G3R3_UNORM
564 * WINED3DFMT_L4A4_UNORM
565 * WINED3DFMT_S1_UINT_D15_UNORM
566 * WINED3DFMT_S4X4_UINT_D24_UNORM
567 *
568 * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of ddraw.
569 * Since it is not widely available, don't offer it. Further no Windows driver
570 * offers WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either.
571 * WINED3DFMT_P8_UINT
572 * WINED3DFMT_P8_UINT_A8_UNORM
573 *
574 * These formats seem to be similar to the HILO formats in
575 * GL_NV_texture_shader. NVHU is said to be GL_UNSIGNED_HILO16,
576 * NVHS GL_SIGNED_HILO16. Rumours say that D3D computes a 3rd channel
577 * similarly to D3DFMT_CxV8U8 (So NVHS could be called D3DFMT_CxV16U16). ATI
578 * refused to support formats which can easily be emulated with pixel shaders,
579 * so applications have to deal with not having NVHS and NVHU.
580 * WINED3DFMT_NVHU
581 * WINED3DFMT_NVHS */
582 static const struct wined3d_format_texture_info format_texture_info[] =
583 {
584 /* format id internal srgbInternal rtInternal
585 format type
586 flags
587 extension */
588 /* FourCC formats */
589 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
590 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
591 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
592 * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
593 * endian machine
594 */
595 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
596 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
597 WINED3DFMT_FLAG_FILTERING,
598 WINED3D_GL_EXT_NONE, NULL},
599 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
600 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 0,
601 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
602 APPLE_YCBCR_422, NULL},
603 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
604 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
605 WINED3DFMT_FLAG_FILTERING,
606 WINED3D_GL_EXT_NONE, NULL},
607 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
608 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, 0,
609 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
610 APPLE_YCBCR_422, NULL},
611 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
612 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
613 WINED3DFMT_FLAG_FILTERING,
614 WINED3D_GL_EXT_NONE, NULL},
615 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
616 GL_RGBA, GL_UNSIGNED_BYTE, 0,
617 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
618 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
619 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
620 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
621 GL_RGBA, GL_UNSIGNED_BYTE, 0,
622 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
623 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
624 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
625 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
626 GL_RGBA, GL_UNSIGNED_BYTE, 0,
627 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
628 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
629 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
630 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
631 GL_RGBA, GL_UNSIGNED_BYTE, 0,
632 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
633 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
634 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
635 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
636 GL_RGBA, GL_UNSIGNED_BYTE, 0,
637 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
638 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
639 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
640 /* IEEE formats */
641 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
642 GL_RED, GL_FLOAT, 0,
643 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
644 ARB_TEXTURE_FLOAT, NULL},
645 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
646 GL_RED, GL_FLOAT, 0,
647 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
648 ARB_TEXTURE_RG, NULL},
649 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
650 GL_RGB, GL_FLOAT, 12,
651 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
652 ARB_TEXTURE_FLOAT, convert_r32g32_float},
653 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
654 GL_RG, GL_FLOAT, 0,
655 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
656 ARB_TEXTURE_RG, NULL},
657 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
658 GL_RGBA, GL_FLOAT, 0,
659 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
660 ARB_TEXTURE_FLOAT, NULL},
661 /* Float */
662 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
663 GL_RED, GL_HALF_FLOAT_ARB, 0,
664 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
665 ARB_TEXTURE_FLOAT, NULL},
666 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
667 GL_RED, GL_HALF_FLOAT_ARB, 0,
668 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
669 ARB_TEXTURE_RG, NULL},
670 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
671 GL_RGB, GL_HALF_FLOAT_ARB, 6,
672 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
673 ARB_TEXTURE_FLOAT, convert_r16g16},
674 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
675 GL_RG, GL_HALF_FLOAT_ARB, 0,
676 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
677 ARB_TEXTURE_RG, NULL},
678 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
679 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
680 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET
681 | WINED3DFMT_FLAG_VTF,
682 ARB_TEXTURE_FLOAT, NULL},
683 /* Palettized formats */
684 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
685 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
686 0,
687 ARB_FRAGMENT_PROGRAM, NULL},
688 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
689 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
690 0,
691 EXT_PALETTED_TEXTURE, NULL},
692 /* Standard ARGB formats */
693 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
694 GL_BGR, GL_UNSIGNED_BYTE, 0,
695 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
696 WINED3D_GL_EXT_NONE, NULL},
697 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
698 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
699 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
700 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE
701 | WINED3DFMT_FLAG_VTF,
702 WINED3D_GL_EXT_NONE, NULL},
703 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
704 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
705 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
706 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
707 WINED3D_GL_EXT_NONE, NULL},
708 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
709 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
710 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
711 | WINED3DFMT_FLAG_RENDERTARGET,
712 WINED3D_GL_EXT_NONE, NULL},
713 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
714 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
715 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
716 WINED3D_GL_EXT_NONE, NULL},
717 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
718 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
719 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
720 WINED3D_GL_EXT_NONE, NULL},
721 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
722 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
723 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
724 | WINED3DFMT_FLAG_SRGB_READ,
725 WINED3D_GL_EXT_NONE, NULL},
726 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
727 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
728 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
729 WINED3D_GL_EXT_NONE, NULL},
730 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
731 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
732 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
733 WINED3D_GL_EXT_NONE, NULL},
734 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
735 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
736 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
737 WINED3D_GL_EXT_NONE, NULL},
738 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
739 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
740 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
741 | WINED3DFMT_FLAG_RENDERTARGET,
742 WINED3D_GL_EXT_NONE, NULL},
743 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
744 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
745 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
746 WINED3D_GL_EXT_NONE, NULL},
747 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
748 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
749 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
750 WINED3D_GL_EXT_NONE, NULL},
751 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
752 GL_RGB, GL_UNSIGNED_SHORT, 6,
753 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
754 WINED3D_GL_EXT_NONE, convert_r16g16},
755 {WINED3DFMT_R16G16_UNORM, GL_RG16, GL_RG16, 0,
756 GL_RG, GL_UNSIGNED_SHORT, 0,
757 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
758 | WINED3DFMT_FLAG_RENDERTARGET,
759 ARB_TEXTURE_RG, NULL},
760 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
761 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
762 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
763 | WINED3DFMT_FLAG_RENDERTARGET,
764 WINED3D_GL_EXT_NONE, NULL},
765 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
766 GL_RGBA, GL_UNSIGNED_SHORT, 0,
767 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
768 | WINED3DFMT_FLAG_RENDERTARGET,
769 WINED3D_GL_EXT_NONE, NULL},
770 /* Luminance */
771 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
772 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
773 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
774 | WINED3DFMT_FLAG_SRGB_READ,
775 WINED3D_GL_EXT_NONE, NULL},
776 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
777 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
778 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
779 | WINED3DFMT_FLAG_SRGB_READ,
780 WINED3D_GL_EXT_NONE, NULL},
781 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
782 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
783 WINED3DFMT_FLAG_FILTERING,
784 WINED3D_GL_EXT_NONE, convert_l4a4_unorm},
785 /* Bump mapping stuff */
786 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
787 GL_BGR, GL_UNSIGNED_BYTE, 3,
788 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
789 | WINED3DFMT_FLAG_BUMPMAP,
790 WINED3D_GL_EXT_NONE, convert_r8g8_snorm},
791 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
792 GL_DSDT_NV, GL_BYTE, 0,
793 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
794 | WINED3DFMT_FLAG_BUMPMAP,
795 NV_TEXTURE_SHADER, NULL},
796 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
797 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
798 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
799 | WINED3DFMT_FLAG_BUMPMAP,
800 WINED3D_GL_EXT_NONE, convert_r5g5_snorm_l6_unorm},
801 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
802 GL_DSDT_MAG_NV, GL_BYTE, 3,
803 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
804 | WINED3DFMT_FLAG_BUMPMAP,
805 NV_TEXTURE_SHADER, convert_r5g5_snorm_l6_unorm_nv},
806 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
807 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
808 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
809 | WINED3DFMT_FLAG_BUMPMAP,
810 WINED3D_GL_EXT_NONE, convert_r8g8_snorm_l8x8_unorm},
811 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
812 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
813 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
814 | WINED3DFMT_FLAG_BUMPMAP,
815 NV_TEXTURE_SHADER, convert_r8g8_snorm_l8x8_unorm_nv},
816 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
817 GL_BGRA, GL_UNSIGNED_BYTE, 4,
818 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
819 | WINED3DFMT_FLAG_BUMPMAP,
820 WINED3D_GL_EXT_NONE, convert_r8g8b8a8_snorm},
821 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
822 GL_RGBA, GL_BYTE, 0,
823 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
824 | WINED3DFMT_FLAG_BUMPMAP,
825 NV_TEXTURE_SHADER, NULL},
826 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
827 GL_BGR, GL_UNSIGNED_SHORT, 6,
828 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
829 | WINED3DFMT_FLAG_BUMPMAP,
830 WINED3D_GL_EXT_NONE, convert_r16g16_snorm},
831 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
832 GL_HILO_NV, GL_SHORT, 0,
833 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
834 | WINED3DFMT_FLAG_BUMPMAP,
835 NV_TEXTURE_SHADER, NULL},
836 /* Depth stencil formats */
837 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
838 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
839 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
840 ARB_DEPTH_TEXTURE, NULL},
841 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
842 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
843 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
844 ARB_DEPTH_TEXTURE, NULL},
845 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
846 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
847 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
848 ARB_DEPTH_TEXTURE, NULL},
849 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
850 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
851 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
852 EXT_PACKED_DEPTH_STENCIL, convert_s1_uint_d15_unorm},
853 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
854 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
855 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
856 ARB_FRAMEBUFFER_OBJECT, convert_s1_uint_d15_unorm},
857 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
858 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
859 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
860 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
861 ARB_DEPTH_TEXTURE, NULL},
862 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
863 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
864 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
865 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
866 EXT_PACKED_DEPTH_STENCIL, NULL},
867 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
868 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
869 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
870 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
871 ARB_FRAMEBUFFER_OBJECT, NULL},
872 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
873 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
874 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
875 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
876 ARB_DEPTH_TEXTURE, NULL},
877 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
878 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
879 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
880 ARB_DEPTH_TEXTURE, NULL},
881 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
882 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
883 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
884 EXT_PACKED_DEPTH_STENCIL, convert_s4x4_uint_d24_unorm},
885 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
886 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
887 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
888 ARB_FRAMEBUFFER_OBJECT, convert_s4x4_uint_d24_unorm},
889 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
890 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
891 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
892 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
893 ARB_DEPTH_TEXTURE, NULL},
894 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
895 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
896 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
897 WINED3D_GL_EXT_NONE, NULL},
898 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
899 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
900 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
901 ARB_DEPTH_BUFFER_FLOAT, NULL},
902 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
903 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
904 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
905 ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float},
906 /* Vendor-specific formats */
907 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
908 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
909 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
910 | WINED3DFMT_FLAG_COMPRESSED,
911 ATI_TEXTURE_COMPRESSION_3DC, NULL},
912 {WINED3DFMT_ATI2N, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0,
913 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
914 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
915 | WINED3DFMT_FLAG_COMPRESSED,
916 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
917 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
918 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
919 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
920 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
921 EXT_PACKED_DEPTH_STENCIL, NULL},
922 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
923 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
924 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
925 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
926 ARB_FRAMEBUFFER_OBJECT, NULL},
927 {WINED3DFMT_NULL, GL_RGBA8, GL_RGBA8, 0,
928 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
929 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET,
930 ARB_FRAMEBUFFER_OBJECT, NULL},
931 };
932
933 static inline int getFmtIdx(enum wined3d_format_id format_id)
934 {
935 /* First check if the format is at the position of its value.
936 * This will catch the argb formats before the loop is entered. */
937 if (format_id < (sizeof(formats) / sizeof(*formats))
938 && formats[format_id].id == format_id)
939 {
940 return format_id;
941 }
942 else
943 {
944 unsigned int i;
945
946 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
947 {
948 if (formats[i].id == format_id) return i;
949 }
950 }
951 return -1;
952 }
953
954 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
955 {
956 UINT format_count = sizeof(formats) / sizeof(*formats);
957 UINT i;
958
959 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
960 if (!gl_info->formats)
961 {
962 ERR("Failed to allocate memory.\n");
963 return FALSE;
964 }
965
966 for (i = 0; i < format_count; ++i)
967 {
968 struct wined3d_format *format = &gl_info->formats[i];
969 format->id = formats[i].id;
970 format->red_size = formats[i].red_size;
971 format->green_size = formats[i].green_size;
972 format->blue_size = formats[i].blue_size;
973 format->alpha_size = formats[i].alpha_size;
974 format->red_offset = formats[i].red_offset;
975 format->green_offset = formats[i].green_offset;
976 format->blue_offset = formats[i].blue_offset;
977 format->alpha_offset = formats[i].alpha_offset;
978 format->byte_count = formats[i].bpp;
979 format->depth_size = formats[i].depth_size;
980 format->stencil_size = formats[i].stencil_size;
981 format->block_width = 1;
982 format->block_height = 1;
983 format->block_byte_count = formats[i].bpp;
984 }
985
986 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
987 {
988 int fmt_idx = getFmtIdx(format_base_flags[i].id);
989
990 if (fmt_idx == -1)
991 {
992 ERR("Format %s (%#x) not found.\n",
993 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
994 HeapFree(GetProcessHeap(), 0, gl_info->formats);
995 return FALSE;
996 }
997
998 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
999 }
1000
1001 return TRUE;
1002 }
1003
1004 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
1005 {
1006 unsigned int i;
1007
1008 for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i)
1009 {
1010 struct wined3d_format *format;
1011 int fmt_idx = getFmtIdx(format_block_info[i].id);
1012
1013 if (fmt_idx == -1)
1014 {
1015 ERR("Format %s (%#x) not found.\n",
1016 debug_d3dformat(format_block_info[i].id), format_block_info[i].id);
1017 return FALSE;
1018 }
1019
1020 format = &gl_info->formats[fmt_idx];
1021 format->block_width = format_block_info[i].block_width;
1022 format->block_height = format_block_info[i].block_height;
1023 format->block_byte_count = format_block_info[i].block_byte_count;
1024 format->flags |= WINED3DFMT_FLAG_BLOCKS;
1025 }
1026
1027 return TRUE;
1028 }
1029
1030 /* Context activation is done by the caller. */
1031 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
1032 {
1033 /* Check if the default internal format is supported as a frame buffer
1034 * target, otherwise fall back to the render target internal.
1035 *
1036 * Try to stick to the standard format if possible, this limits precision differences. */
1037 GLenum status;
1038 GLuint tex;
1039
1040 while (gl_info->gl_ops.gl.p_glGetError());
1041 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1042
1043 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1044 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1045
1046 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0,
1047 format->glFormat, format->glType, NULL);
1048 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1049 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1050
1051 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1052
1053 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1054 checkGLcall("Framebuffer format check");
1055
1056 if (status == GL_FRAMEBUFFER_COMPLETE)
1057 {
1058 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1059 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1060 format->rtInternal = format->glInternal;
1061 }
1062 else
1063 {
1064 if (!format->rtInternal)
1065 {
1066 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1067 {
1068 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1069 " and no fallback specified.\n", debug_d3dformat(format->id));
1070 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1071 }
1072 else
1073 {
1074 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1075 }
1076 format->rtInternal = format->glInternal;
1077 }
1078 else
1079 {
1080 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1081 debug_d3dformat(format->id));
1082
1083 while (gl_info->gl_ops.gl.p_glGetError());
1084
1085 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1086
1087 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0,
1088 format->glFormat, format->glType, NULL);
1089 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1090 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1091
1092 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1093
1094 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1095 checkGLcall("Framebuffer format check");
1096
1097 if (status == GL_FRAMEBUFFER_COMPLETE)
1098 {
1099 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1100 debug_d3dformat(format->id));
1101 }
1102 else
1103 {
1104 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1105 debug_d3dformat(format->id));
1106 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1107 }
1108 }
1109 }
1110
1111 if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1112 || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1113 && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
1114 && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA
1115 && (format->red_size || format->alpha_size))
1116 {
1117 DWORD readback[16 * 16], color, r_range, a_range;
1118 BYTE r, a;
1119 BOOL match = TRUE;
1120 GLuint rb;
1121
1122 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1123 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1124 {
1125 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1126 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1127 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1128 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1129 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1130 checkGLcall("RB attachment");
1131 }
1132
1133 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1134 gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1135 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1136 if (gl_info->gl_ops.gl.p_glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1137 {
1138 while (gl_info->gl_ops.gl.p_glGetError());
1139 TRACE("Format doesn't support post-pixelshader blending.\n");
1140 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1141 }
1142 else
1143 {
1144 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1145 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16);
1146 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1147 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1148 gl_info->gl_ops.gl.p_glLoadIdentity();
1149 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1150 gl_info->gl_ops.gl.p_glLoadIdentity();
1151
1152 gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1153
1154 /* Draw a full-black quad */
1155 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1156 gl_info->gl_ops.gl.p_glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
1157 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1158 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1159 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1160 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1161 gl_info->gl_ops.gl.p_glEnd();
1162
1163 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1164 /* Draw a half-transparent red quad */
1165 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1166 gl_info->gl_ops.gl.p_glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
1167 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1168 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1169 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1170 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1171 gl_info->gl_ops.gl.p_glEnd();
1172
1173 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1174
1175 /* Rebinding texture to workaround a fglrx bug. */
1176 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1177 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1178 checkGLcall("Post-pixelshader blending check");
1179
1180 color = readback[7 * 16 + 7];
1181 a = color >> 24;
1182 r = (color & 0x00ff0000) >> 16;
1183
1184 r_range = format->red_size < 8 ? 1 << (8 - format->red_size) : 1;
1185 a_range = format->alpha_size < 8 ? 1 << (8 - format->alpha_size) : 1;
1186 if (format->red_size && (r < 0x7f - r_range || r > 0x7f + r_range))
1187 match = FALSE;
1188 else if (format->alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range))
1189 match = FALSE;
1190 if (!match)
1191 {
1192 TRACE("Format doesn't support post-pixelshader blending.\n");
1193 TRACE("Color output: %#x\n", color);
1194 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1195 }
1196 else
1197 {
1198 TRACE("Format supports post-pixelshader blending.\n");
1199 TRACE("Color output: %#x\n", color);
1200 format->flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1201 }
1202 }
1203
1204 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1205 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1206 {
1207 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1208 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1209 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1210 checkGLcall("RB cleanup");
1211 }
1212 }
1213
1214 if (format->glInternal != format->glGammaInternal)
1215 {
1216 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0,
1217 format->glFormat, format->glType, NULL);
1218 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1219
1220 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1221 checkGLcall("Framebuffer format check");
1222
1223 if (status == GL_FRAMEBUFFER_COMPLETE)
1224 {
1225 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1226 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1227 }
1228 else
1229 {
1230 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1231 }
1232 }
1233 else if (status == GL_FRAMEBUFFER_COMPLETE)
1234 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1235
1236 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1237 }
1238
1239 /* Context activation is done by the caller. */
1240 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1241 {
1242 unsigned int i;
1243 GLuint fbo;
1244
1245 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1246 {
1247 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1248 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1249 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1250 gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0);
1251 }
1252
1253 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1254 {
1255 struct wined3d_format *format = &gl_info->formats[i];
1256
1257 if (!format->glInternal) continue;
1258
1259 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1260 {
1261 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1262 debug_d3dformat(format->id));
1263 continue;
1264 }
1265
1266 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1267 {
1268 TRACE("Skipping format %s because it's a compressed format.\n",
1269 debug_d3dformat(format->id));
1270 continue;
1271 }
1272
1273 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1274 {
1275 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1276 check_fbo_compat(gl_info, format);
1277 }
1278 else
1279 {
1280 format->rtInternal = format->glInternal;
1281 }
1282 }
1283
1284 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1285 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1286 }
1287
1288 static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1289 {
1290 struct fragment_caps fragment_caps;
1291 struct shader_caps shader_caps;
1292 BOOL srgb_write;
1293 unsigned int i;
1294
1295 adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
1296 adapter->shader_backend->shader_get_caps(gl_info, &shader_caps);
1297 srgb_write = (fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_SRGB_WRITE)
1298 && (shader_caps.wined3d_caps & WINED3D_SHADER_CAP_SRGB_WRITE);
1299
1300 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1301 {
1302 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1303 struct wined3d_format *format;
1304
1305 if (fmt_idx == -1)
1306 {
1307 ERR("Format %s (%#x) not found.\n",
1308 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1309 return FALSE;
1310 }
1311
1312 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1313
1314 format = &gl_info->formats[fmt_idx];
1315
1316 /* ARB_texture_rg defines floating point formats, but only if
1317 * ARB_texture_float is also supported. */
1318 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1319 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1320 continue;
1321
1322 format->glInternal = format_texture_info[i].gl_internal;
1323 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1324 format->rtInternal = format_texture_info[i].gl_rt_internal;
1325 format->glFormat = format_texture_info[i].gl_format;
1326 format->glType = format_texture_info[i].gl_type;
1327 format->color_fixup = COLOR_FIXUP_IDENTITY;
1328 format->flags |= format_texture_info[i].flags;
1329 format->height_scale.numerator = 1;
1330 format->height_scale.denominator = 1;
1331
1332 if (!gl_info->limits.vertex_samplers)
1333 format->flags &= ~WINED3DFMT_FLAG_VTF;
1334
1335 if (!(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1336 format->flags |= WINED3DFMT_FLAG_FILTERING;
1337 else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT)
1338 format->flags &= ~WINED3DFMT_FLAG_VTF;
1339
1340 if (format->glGammaInternal != format->glInternal)
1341 {
1342 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1343 if (!gl_info->supported[EXT_TEXTURE_SRGB])
1344 {
1345 format->glGammaInternal = format->glInternal;
1346 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1347 }
1348 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1349 {
1350 format->glInternal = format->glGammaInternal;
1351 }
1352 }
1353
1354 if ((format->flags & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write)
1355 format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
1356
1357 /* Texture conversion stuff */
1358 format->convert = format_texture_info[i].convert;
1359 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1360 }
1361
1362 return TRUE;
1363 }
1364
1365 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1366 {
1367 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1368 c1 >>= 8; c2 >>= 8;
1369 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1370 c1 >>= 8; c2 >>= 8;
1371 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1372 c1 >>= 8; c2 >>= 8;
1373 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1374 return TRUE;
1375 }
1376
1377 /* A context is provided by the caller */
1378 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1379 {
1380 static const DWORD data[] = {0x00000000, 0xffffffff};
1381 GLuint tex, fbo, buffer;
1382 DWORD readback[16 * 1];
1383 BOOL ret = FALSE;
1384
1385 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1386 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1387 * falling back to software. If this changes in the future this code will get fooled and
1388 * apps might hit the software path due to incorrectly advertised caps.
1389 *
1390 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1391 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1392 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1393 */
1394
1395 while (gl_info->gl_ops.gl.p_glGetError());
1396
1397 gl_info->gl_ops.gl.p_glGenTextures(1, &buffer);
1398 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1399 memset(readback, 0x7e, sizeof(readback));
1400 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0,
1401 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1402 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1403 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1404 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1405 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1406 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1407
1408 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1409 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1410 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0,
1411 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1412 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1413 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1414 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1415 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1416 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1417 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
1418
1419 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1420 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1421 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1422 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1423
1424 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1);
1425 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1426 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1427 gl_info->gl_ops.gl.p_glLoadIdentity();
1428 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1429 gl_info->gl_ops.gl.p_glLoadIdentity();
1430
1431 gl_info->gl_ops.gl.p_glClearColor(0, 1, 0, 0);
1432 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1433
1434 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1435 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 0.0);
1436 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, -1.0f);
1437 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 0.0);
1438 gl_info->gl_ops.gl.p_glVertex2f(1.0f, -1.0f);
1439 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 1.0);
1440 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, 1.0f);
1441 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 1.0);
1442 gl_info->gl_ops.gl.p_glVertex2f(1.0f, 1.0f);
1443 gl_info->gl_ops.gl.p_glEnd();
1444
1445 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1446 memset(readback, 0x7f, sizeof(readback));
1447 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1448 if (color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5)
1449 || color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1450 {
1451 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, assuming no filtering\n",
1452 readback[6], readback[9]);
1453 ret = FALSE;
1454 }
1455 else
1456 {
1457 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1458 readback[6], readback[9]);
1459 ret = TRUE;
1460 }
1461
1462 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1463 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1464 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1465 gl_info->gl_ops.gl.p_glDeleteTextures(1, &buffer);
1466
1467 if (gl_info->gl_ops.gl.p_glGetError())
1468 {
1469 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1470 ret = FALSE;
1471 }
1472
1473 return ret;
1474 }
1475
1476 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1477 {
1478 struct wined3d_format *format;
1479 unsigned int fmt_idx, i;
1480 static const enum wined3d_format_id fmts16[] =
1481 {
1482 WINED3DFMT_R16_FLOAT,
1483 WINED3DFMT_R16G16_FLOAT,
1484 WINED3DFMT_R16G16B16A16_FLOAT,
1485 };
1486 BOOL filtered;
1487
1488 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1489 {
1490 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1491 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1492 {
1493 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1494 filtered = TRUE;
1495 }
1496 else if (gl_info->limits.glsl_varyings > 44)
1497 {
1498 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1499 filtered = TRUE;
1500 }
1501 else
1502 {
1503 TRACE("Assuming no float16 blending\n");
1504 filtered = FALSE;
1505 }
1506
1507 if(filtered)
1508 {
1509 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1510 {
1511 fmt_idx = getFmtIdx(fmts16[i]);
1512 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1513 }
1514 }
1515 return;
1516 }
1517
1518 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1519 {
1520 fmt_idx = getFmtIdx(fmts16[i]);
1521 format = &gl_info->formats[fmt_idx];
1522 if (!format->glInternal) continue; /* Not supported by GL */
1523
1524 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1525 if(filtered)
1526 {
1527 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1528 format->flags |= WINED3DFMT_FLAG_FILTERING;
1529 }
1530 else
1531 {
1532 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1533 }
1534 }
1535 }
1536
1537 static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1538 {
1539 unsigned int i;
1540 int idx;
1541
1542 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1543 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1544 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1545
1546 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1547 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1548 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1549
1550 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1551 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1552 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1553
1554 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1555 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1556 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1557
1558 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1559 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1560 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1561
1562 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1563 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1564 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1565 * the only driver that implements it(fglrx) has a buggy implementation.
1566 *
1567 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1568 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1569 * conversion for this format.
1570 */
1571 if (!gl_info->supported[NV_TEXTURE_SHADER])
1572 {
1573 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1574 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1575 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1576 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1577 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1578 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1579 }
1580 else
1581 {
1582 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1583 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1584 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1585
1586 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1587 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1588 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1589 }
1590
1591 if (!gl_info->supported[NV_TEXTURE_SHADER])
1592 {
1593 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1594 * with each other
1595 */
1596 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1597 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1598 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1599 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1600 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1601 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1602 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1603 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1604 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1605 }
1606 else
1607 {
1608 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1609 * are converted at surface loading time, but they do not need any modification in
1610 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1611 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1612 */
1613 }
1614
1615 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1616 {
1617 idx = getFmtIdx(WINED3DFMT_ATI2N);
1618 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1619 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1620 }
1621 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1622 {
1623 idx = getFmtIdx(WINED3DFMT_ATI2N);
1624 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1625 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1626 }
1627
1628 if (!gl_info->supported[APPLE_YCBCR_422])
1629 {
1630 idx = getFmtIdx(WINED3DFMT_YUY2);
1631 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1632
1633 idx = getFmtIdx(WINED3DFMT_UYVY);
1634 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1635 }
1636
1637 idx = getFmtIdx(WINED3DFMT_YV12);
1638 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
1639 gl_info->formats[idx].height_scale.numerator = 3;
1640 gl_info->formats[idx].height_scale.denominator = 2;
1641 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1642
1643 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1644 {
1645 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1646 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1647 }
1648
1649 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1650 {
1651 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1652 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1653 }
1654
1655 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1656 {
1657 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1658 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1659 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1660 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1661
1662 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1663 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1664 }
1665
1666 if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
1667 {
1668 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1669 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1670
1671 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1672 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1673
1674 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1675 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1676 }
1677
1678 if (gl_info->quirks & WINED3D_QUIRK_BROKEN_RGBA16)
1679 {
1680 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_UNORM);
1681 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1682 }
1683
1684 /* ATI instancing hack: Although ATI cards do not support Shader Model
1685 * 3.0, they support instancing. To query if the card supports instancing
1686 * CheckDeviceFormat() with the special format MAKEFOURCC('I','N','S','T')
1687 * is used. Should an application check for this, provide a proper return
1688 * value. We can do instancing with all shader versions, but we need
1689 * vertex shaders.
1690 *
1691 * Additionally applications have to set the D3DRS_POINTSIZE render state
1692 * to MAKEFOURCC('I','N','S','T') once to enable instancing. Wined3d
1693 * doesn't need that and just ignores it.
1694 *
1695 * With Shader Model 3.0 capable cards Instancing 'just works' in Windows. */
1696 /* FIXME: This should just check the shader backend caps. */
1697 if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
1698 {
1699 idx = getFmtIdx(WINED3DFMT_INST);
1700 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
1701 }
1702
1703 /* Depth bound test. To query if the card supports it CheckDeviceFormat()
1704 * with the special format MAKEFOURCC('N','V','D','B') is used. It is
1705 * enabled by setting D3DRS_ADAPTIVETESS_X render state to
1706 * MAKEFOURCC('N','V','D','B') and then controlled by setting
1707 * D3DRS_ADAPTIVETESS_Z (zMin) and D3DRS_ADAPTIVETESS_W (zMax) to test
1708 * value. */
1709 if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST])
1710 {
1711 idx = getFmtIdx(WINED3DFMT_NVDB);
1712 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
1713 }
1714
1715 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1716 {
1717 struct wined3d_format *format = &gl_info->formats[idx];
1718
1719 if (!(format->flags & WINED3DFMT_FLAG_TEXTURE))
1720 continue;
1721
1722 if (!adapter->shader_backend->shader_color_fixup_supported(format->color_fixup)
1723 || !adapter->fragment_pipe->color_fixup_supported(format->color_fixup))
1724 format->flags &= ~WINED3DFMT_FLAG_TEXTURE;
1725 }
1726 }
1727
1728 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1729 {
1730 unsigned int i;
1731
1732 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1733 {
1734 struct wined3d_format *format;
1735 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1736
1737 if (fmt_idx == -1)
1738 {
1739 ERR("Format %s (%#x) not found.\n",
1740 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1741 return FALSE;
1742 }
1743
1744 format = &gl_info->formats[fmt_idx];
1745 format->emit_idx = format_vertex_info[i].emit_idx;
1746 format->component_count = format_vertex_info[i].component_count;
1747 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1748 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1749 format->gl_normalized = format_vertex_info[i].gl_normalized;
1750 format->component_size = format_vertex_info[i].component_size;
1751 }
1752
1753 return TRUE;
1754 }
1755
1756 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1757 {
1758 if (!init_format_base_info(gl_info)) return FALSE;
1759
1760 if (!init_format_block_info(gl_info))
1761 {
1762 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1763 gl_info->formats = NULL;
1764 return FALSE;
1765 }
1766
1767 return TRUE;
1768 }
1769
1770 /* Context activation is done by the caller. */
1771 BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter)
1772 {
1773 struct wined3d_gl_info *gl_info = &adapter->gl_info;
1774
1775 if (!init_format_base_info(gl_info)) return FALSE;
1776
1777 if (!init_format_block_info(gl_info)) goto fail;
1778 if (!init_format_texture_info(adapter, gl_info)) goto fail;
1779 if (!init_format_vertex_info(gl_info)) goto fail;
1780
1781 apply_format_fixups(adapter, gl_info);
1782 init_format_fbo_compat_info(gl_info);
1783 init_format_filter_info(gl_info, adapter->driver_info.vendor);
1784
1785 return TRUE;
1786
1787 fail:
1788 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1789 gl_info->formats = NULL;
1790 return FALSE;
1791 }
1792
1793 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1794 enum wined3d_format_id format_id)
1795 {
1796 int idx = getFmtIdx(format_id);
1797
1798 if (idx == -1)
1799 {
1800 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1801 debug_d3dformat(format_id), format_id);
1802 /* Get the caller a valid pointer */
1803 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1804 }
1805
1806 return &gl_info->formats[idx];
1807 }
1808
1809 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1810 {
1811 UINT size;
1812
1813 if (format->id == WINED3DFMT_UNKNOWN)
1814 {
1815 size = 0;
1816 }
1817 else if (format->flags & WINED3DFMT_FLAG_BLOCKS)
1818 {
1819 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1820 UINT row_count = (height + format->block_height - 1) / format->block_height;
1821 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1822 }
1823 else
1824 {
1825 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1826 }
1827
1828 if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
1829 {
1830 /* The D3D format requirements make sure that the resulting format is an integer again */
1831 size *= format->height_scale.numerator;
1832 size /= format->height_scale.denominator;
1833 }
1834
1835 return size;
1836 }
1837
1838 /*****************************************************************************
1839 * Trace formatting of useful values
1840 */
1841 const char *debug_d3dformat(enum wined3d_format_id format_id)
1842 {
1843 switch (format_id)
1844 {
1845 #define FMT_TO_STR(format_id) case format_id: return #format_id
1846 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1847 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1848 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1849 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1850 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1851 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1852 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1853 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1854 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1855 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1856 FMT_TO_STR(WINED3DFMT_P8_UINT);
1857 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1858 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1859 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1860 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1861 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1862 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1863 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1864 FMT_TO_STR(WINED3DFMT_UYVY);
1865 FMT_TO_STR(WINED3DFMT_YUY2);
1866 FMT_TO_STR(WINED3DFMT_YV12);
1867 FMT_TO_STR(WINED3DFMT_DXT1);
1868 FMT_TO_STR(WINED3DFMT_DXT2);
1869 FMT_TO_STR(WINED3DFMT_DXT3);
1870 FMT_TO_STR(WINED3DFMT_DXT4);
1871 FMT_TO_STR(WINED3DFMT_DXT5);
1872 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1873 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1874 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1875 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1876 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1877 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1878 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1879 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1880 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1881 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1882 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1883 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1884 FMT_TO_STR(WINED3DFMT_ATI2N);
1885 FMT_TO_STR(WINED3DFMT_NVDB);
1886 FMT_TO_STR(WINED3DFMT_NVHU);
1887 FMT_TO_STR(WINED3DFMT_NVHS);
1888 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1889 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1890 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1891 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1892 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1893 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1894 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1895 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1896 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1897 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1898 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1899 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1900 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1901 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1902 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1903 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1904 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1905 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1906 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1907 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1908 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1909 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1910 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1911 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1912 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1913 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1914 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1915 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1916 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1917 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1918 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1919 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1920 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1921 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1922 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1923 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1924 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1925 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1926 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1927 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1928 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1929 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1930 FMT_TO_STR(WINED3DFMT_R32_UINT);
1931 FMT_TO_STR(WINED3DFMT_R32_SINT);
1932 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1933 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1934 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1935 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1936 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1937 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1938 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1939 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1940 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1941 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1942 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1943 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1944 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1945 FMT_TO_STR(WINED3DFMT_R16_UINT);
1946 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1947 FMT_TO_STR(WINED3DFMT_R16_SINT);
1948 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1949 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1950 FMT_TO_STR(WINED3DFMT_R8_UINT);
1951 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1952 FMT_TO_STR(WINED3DFMT_R8_SINT);
1953 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1954 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1955 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1956 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1957 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1958 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1959 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1960 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1961 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1962 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1963 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1964 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1965 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1966 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1967 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1968 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1969 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1970 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1971 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1972 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1973 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1974 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1975 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1976 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1977 FMT_TO_STR(WINED3DFMT_INTZ);
1978 FMT_TO_STR(WINED3DFMT_NULL);
1979 FMT_TO_STR(WINED3DFMT_R16);
1980 FMT_TO_STR(WINED3DFMT_AL16);
1981 #undef FMT_TO_STR
1982 default:
1983 {
1984 char fourcc[5];
1985 fourcc[0] = (char)(format_id);
1986 fourcc[1] = (char)(format_id >> 8);
1987 fourcc[2] = (char)(format_id >> 16);
1988 fourcc[3] = (char)(format_id >> 24);
1989 fourcc[4] = 0;
1990 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1991 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1992 else
1993 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1994 }
1995 return "unrecognized";
1996 }
1997 }
1998
1999 const char *debug_d3ddevicetype(enum wined3d_device_type device_type)
2000 {
2001 switch (device_type)
2002 {
2003 #define DEVTYPE_TO_STR(dev) case dev: return #dev
2004 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_HAL);
2005 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_REF);
2006 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_SW);
2007 #undef DEVTYPE_TO_STR
2008 default:
2009 FIXME("Unrecognized device type %#x.\n", device_type);
2010 return "unrecognized";
2011 }
2012 }
2013
2014 const char *debug_d3dusage(DWORD usage)
2015 {
2016 char buf[333];
2017
2018 buf[0] = '\0';
2019 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
2020 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
2021 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
2022 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
2023 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
2024 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
2025 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
2026 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
2027 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
2028 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
2029 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
2030 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
2031 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
2032 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
2033 #undef WINED3DUSAGE_TO_STR
2034 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
2035
2036 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2037 }
2038
2039 const char *debug_d3dusagequery(DWORD usagequery)
2040 {
2041 char buf[238];
2042
2043 buf[0] = '\0';
2044 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
2045 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
2046 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
2047 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
2048 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
2049 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
2050 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
2051 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
2052 #undef WINED3DUSAGEQUERY_TO_STR
2053 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
2054
2055 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2056 }
2057
2058 const char *debug_d3ddeclmethod(enum wined3d_decl_method method)
2059 {
2060 switch (method)
2061 {
2062 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
2063 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_DEFAULT);
2064 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_U);
2065 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_V);
2066 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_CROSS_UV);
2067 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_UV);
2068 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP);
2069 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP_PRESAMPLED);
2070 #undef WINED3DDECLMETHOD_TO_STR
2071 default:
2072 FIXME("Unrecognized declaration method %#x.\n", method);
2073 return "unrecognized";
2074 }
2075 }
2076
2077 const char *debug_d3ddeclusage(enum wined3d_decl_usage usage)
2078 {
2079 switch (usage)
2080 {
2081 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
2082 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITION);
2083 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_WEIGHT);
2084 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_INDICES);
2085 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_NORMAL);
2086 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_PSIZE);
2087 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TEXCOORD);
2088 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TANGENT);
2089 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BINORMAL);
2090 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TESS_FACTOR);
2091 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITIONT);
2092 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_COLOR);
2093 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_FOG);
2094 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_DEPTH);
2095 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_SAMPLE);
2096 #undef WINED3DDECLUSAGE_TO_STR
2097 default:
2098 FIXME("Unrecognized %u declaration usage!\n", usage);
2099 return "unrecognized";
2100 }
2101 }
2102
2103 const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
2104 {
2105 switch (resource_type)
2106 {
2107 #define RES_TO_STR(res) case res: return #res
2108 RES_TO_STR(WINED3D_RTYPE_SURFACE);
2109 RES_TO_STR(WINED3D_RTYPE_VOLUME);
2110 RES_TO_STR(WINED3D_RTYPE_TEXTURE);
2111 RES_TO_STR(WINED3D_RTYPE_VOLUME_TEXTURE);
2112 RES_TO_STR(WINED3D_RTYPE_CUBE_TEXTURE);
2113 RES_TO_STR(WINED3D_RTYPE_BUFFER);
2114 #undef RES_TO_STR
2115 default:
2116 FIXME("Unrecognized resource type %#x.\n", resource_type);
2117 return "unrecognized";
2118 }
2119 }
2120
2121 const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type)
2122 {
2123 switch (primitive_type)
2124 {
2125 #define PRIM_TO_STR(prim) case prim: return #prim
2126 PRIM_TO_STR(WINED3D_PT_UNDEFINED);
2127 PRIM_TO_STR(WINED3D_PT_POINTLIST);
2128 PRIM_TO_STR(WINED3D_PT_LINELIST);
2129 PRIM_TO_STR(WINED3D_PT_LINESTRIP);
2130 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST);
2131 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP);
2132 PRIM_TO_STR(WINED3D_PT_TRIANGLEFAN);
2133 PRIM_TO_STR(WINED3D_PT_LINELIST_ADJ);
2134 PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ);
2135 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ);
2136 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ);
2137 #undef PRIM_TO_STR
2138 default:
2139 FIXME("Unrecognized %u primitive type!\n", primitive_type);
2140 return "unrecognized";
2141 }
2142 }
2143
2144 const char *debug_d3drenderstate(enum wined3d_render_state state)
2145 {
2146 switch (state)
2147 {
2148 #define D3DSTATE_TO_STR(u) case u: return #u
2149 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIAS);
2150 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREPERSPECTIVE);
2151 D3DSTATE_TO_STR(WINED3D_RS_WRAPU);
2152 D3DSTATE_TO_STR(WINED3D_RS_WRAPV);
2153 D3DSTATE_TO_STR(WINED3D_RS_ZENABLE);
2154 D3DSTATE_TO_STR(WINED3D_RS_FILLMODE);
2155 D3DSTATE_TO_STR(WINED3D_RS_SHADEMODE);
2156 D3DSTATE_TO_STR(WINED3D_RS_LINEPATTERN);
2157 D3DSTATE_TO_STR(WINED3D_RS_MONOENABLE);
2158 D3DSTATE_TO_STR(WINED3D_RS_ROP2);
2159 D3DSTATE_TO_STR(WINED3D_RS_PLANEMASK);
2160 D3DSTATE_TO_STR(WINED3D_RS_ZWRITEENABLE);
2161 D3DSTATE_TO_STR(WINED3D_RS_ALPHATESTENABLE);
2162 D3DSTATE_TO_STR(WINED3D_RS_LASTPIXEL);
2163 D3DSTATE_TO_STR(WINED3D_RS_SRCBLEND);
2164 D3DSTATE_TO_STR(WINED3D_RS_DESTBLEND);
2165 D3DSTATE_TO_STR(WINED3D_RS_CULLMODE);
2166 D3DSTATE_TO_STR(WINED3D_RS_ZFUNC);
2167 D3DSTATE_TO_STR(WINED3D_RS_ALPHAREF);
2168 D3DSTATE_TO_STR(WINED3D_RS_ALPHAFUNC);
2169 D3DSTATE_TO_STR(WINED3D_RS_DITHERENABLE);
2170 D3DSTATE_TO_STR(WINED3D_RS_ALPHABLENDENABLE);
2171 D3DSTATE_TO_STR(WINED3D_RS_FOGENABLE);
2172 D3DSTATE_TO_STR(WINED3D_RS_SPECULARENABLE);
2173 D3DSTATE_TO_STR(WINED3D_RS_ZVISIBLE);
2174 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXEL);
2175 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXELX);
2176 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEDALPHA);
2177 D3DSTATE_TO_STR(WINED3D_RS_FOGCOLOR);
2178 D3DSTATE_TO_STR(WINED3D_RS_FOGTABLEMODE);
2179 D3DSTATE_TO_STR(WINED3D_RS_FOGSTART);
2180 D3DSTATE_TO_STR(WINED3D_RS_FOGEND);
2181 D3DSTATE_TO_STR(WINED3D_RS_FOGDENSITY);
2182 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEENABLE);
2183 D3DSTATE_TO_STR(WINED3D_RS_EDGEANTIALIAS);
2184 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYENABLE);
2185 D3DSTATE_TO_STR(WINED3D_RS_MIPMAPLODBIAS);
2186 D3DSTATE_TO_STR(WINED3D_RS_RANGEFOGENABLE);
2187 D3DSTATE_TO_STR(WINED3D_RS_ANISOTROPY);
2188 D3DSTATE_TO_STR(WINED3D_RS_FLUSHBATCH);
2189 D3DSTATE_TO_STR(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT);
2190 D3DSTATE_TO_STR(WINED3D_RS_STENCILENABLE);
2191 D3DSTATE_TO_STR(WINED3D_RS_STENCILFAIL);
2192 D3DSTATE_TO_STR(WINED3D_RS_STENCILZFAIL);
2193 D3DSTATE_TO_STR(WINED3D_RS_STENCILPASS);
2194 D3DSTATE_TO_STR(WINED3D_RS_STENCILFUNC);
2195 D3DSTATE_TO_STR(WINED3D_RS_STENCILREF);
2196 D3DSTATE_TO_STR(WINED3D_RS_STENCILMASK);
2197 D3DSTATE_TO_STR(WINED3D_RS_STENCILWRITEMASK);
2198 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREFACTOR);
2199 D3DSTATE_TO_STR(WINED3D_RS_WRAP0);
2200 D3DSTATE_TO_STR(WINED3D_RS_WRAP1);
2201 D3DSTATE_TO_STR(WINED3D_RS_WRAP2);
2202 D3DSTATE_TO_STR(WINED3D_RS_WRAP3);
2203 D3DSTATE_TO_STR(WINED3D_RS_WRAP4);
2204 D3DSTATE_TO_STR(WINED3D_RS_WRAP5);
2205 D3DSTATE_TO_STR(WINED3D_RS_WRAP6);
2206 D3DSTATE_TO_STR(WINED3D_RS_WRAP7);
2207 D3DSTATE_TO_STR(WINED3D_RS_CLIPPING);
2208 D3DSTATE_TO_STR(WINED3D_RS_LIGHTING);
2209 D3DSTATE_TO_STR(WINED3D_RS_EXTENTS);
2210 D3DSTATE_TO_STR(WINED3D_RS_AMBIENT);
2211 D3DSTATE_TO_STR(WINED3D_RS_FOGVERTEXMODE);
2212 D3DSTATE_TO_STR(WINED3D_RS_COLORVERTEX);
2213 D3DSTATE_TO_STR(WINED3D_RS_LOCALVIEWER);
2214 D3DSTATE_TO_STR(WINED3D_RS_NORMALIZENORMALS);
2215 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYBLENDENABLE);
2216 D3DSTATE_TO_STR(WINED3D_RS_DIFFUSEMATERIALSOURCE);
2217 D3DSTATE_TO_STR(WINED3D_RS_SPECULARMATERIALSOURCE);
2218 D3DSTATE_TO_STR(WINED3D_RS_AMBIENTMATERIALSOURCE);
2219 D3DSTATE_TO_STR(WINED3D_RS_EMISSIVEMATERIALSOURCE);
2220 D3DSTATE_TO_STR(WINED3D_RS_VERTEXBLEND);
2221 D3DSTATE_TO_STR(WINED3D_RS_CLIPPLANEENABLE);
2222 D3DSTATE_TO_STR(WINED3D_RS_SOFTWAREVERTEXPROCESSING);
2223 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE);
2224 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MIN);
2225 D3DSTATE_TO_STR(WINED3D_RS_POINTSPRITEENABLE);
2226 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALEENABLE);
2227 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_A);
2228 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_B);
2229 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_C);
2230 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEANTIALIAS);
2231 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEMASK);
2232 D3DSTATE_TO_STR(WINED3D_RS_PATCHEDGESTYLE);
2233 D3DSTATE_TO_STR(WINED3D_RS_PATCHSEGMENTS);
2234 D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN);
2235 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX);
2236 D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE);
2237 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
2238 D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR);
2239 D3DSTATE_TO_STR(WINED3D_RS_BLENDOP);
2240 D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE);
2241 D3DSTATE_TO_STR(WINED3D_RS_NORMALDEGREE);
2242 D3DSTATE_TO_STR(WINED3D_RS_SCISSORTESTENABLE);
2243 D3DSTATE_TO_STR(WINED3D_RS_SLOPESCALEDEPTHBIAS);
2244 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIASEDLINEENABLE);
2245 D3DSTATE_TO_STR(WINED3D_RS_MINTESSELLATIONLEVEL);
2246 D3DSTATE_TO_STR(WINED3D_RS_MAXTESSELLATIONLEVEL);
2247 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_X);
2248 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Y);
2249 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Z);
2250 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_W);
2251 D3DSTATE_TO_STR(WINED3D_RS_ENABLEADAPTIVETESSELLATION);
2252 D3DSTATE_TO_STR(WINED3D_RS_TWOSIDEDSTENCILMODE);
2253 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFAIL);
2254 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILZFAIL);
2255 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILPASS);
2256 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFUNC);
2257 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1);
2258 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2);
2259 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3);
2260 D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR);
2261 D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE);
2262 D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS);
2263 D3DSTATE_TO_STR(WINED3D_RS_WRAP8);
2264 D3DSTATE_TO_STR(WINED3D_RS_WRAP9);
2265 D3DSTATE_TO_STR(WINED3D_RS_WRAP10);
2266 D3DSTATE_TO_STR(WINED3D_RS_WRAP11);
2267 D3DSTATE_TO_STR(WINED3D_RS_WRAP12);
2268 D3DSTATE_TO_STR(WINED3D_RS_WRAP13);
2269 D3DSTATE_TO_STR(WINED3D_RS_WRAP14);
2270 D3DSTATE_TO_STR(WINED3D_RS_WRAP15);
2271 D3DSTATE_TO_STR(WINED3D_RS_SEPARATEALPHABLENDENABLE);
2272 D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
2273 D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
2274 D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
2275 #undef D3DSTATE_TO_STR
2276 default:
2277 FIXME("Unrecognized %u render state!\n", state);
2278 return "unrecognized";
2279 }
2280 }
2281
2282 const char *debug_d3dsamplerstate(enum wined3d_sampler_state state)
2283 {
2284 switch (state)
2285 {
2286 #define D3DSTATE_TO_STR(u) case u: return #u
2287 D3DSTATE_TO_STR(WINED3D_SAMP_BORDER_COLOR);
2288 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_U);
2289 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_V);
2290 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_W);
2291 D3DSTATE_TO_STR(WINED3D_SAMP_MAG_FILTER);
2292 D3DSTATE_TO_STR(WINED3D_SAMP_MIN_FILTER);
2293 D3DSTATE_TO_STR(WINED3D_SAMP_MIP_FILTER);
2294 D3DSTATE_TO_STR(WINED3D_SAMP_MIPMAP_LOD_BIAS);
2295 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_MIP_LEVEL);
2296 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_ANISOTROPY);
2297 D3DSTATE_TO_STR(WINED3D_SAMP_SRGB_TEXTURE);
2298 D3DSTATE_TO_STR(WINED3D_SAMP_ELEMENT_INDEX);
2299 D3DSTATE_TO_STR(WINED3D_SAMP_DMAP_OFFSET);
2300 #undef D3DSTATE_TO_STR
2301 default:
2302 FIXME("Unrecognized %u sampler state!\n", state);
2303 return "unrecognized";
2304 }
2305 }
2306
2307 const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type)
2308 {
2309 switch (filter_type)
2310 {
2311 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2312 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_NONE);
2313 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_POINT);
2314 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_LINEAR);
2315 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_ANISOTROPIC);
2316 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_FLAT_CUBIC);
2317 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_CUBIC);
2318 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_PYRAMIDAL_QUAD);
2319 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_QUAD);
2320 #undef D3DTEXTUREFILTERTYPE_TO_STR
2321 default:
2322 FIXME("Unrecognied texture filter type 0x%08x.\n", filter_type);
2323 return "unrecognized";
2324 }
2325 }
2326
2327 const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state)
2328 {
2329 switch (state)
2330 {
2331 #define D3DSTATE_TO_STR(u) case u: return #u
2332 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_OP);
2333 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG1);
2334 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG2);
2335 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_OP);
2336 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG1);
2337 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG2);
2338 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT00);
2339 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT01);
2340 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT10);
2341 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT11);
2342 D3DSTATE_TO_STR(WINED3D_TSS_TEXCOORD_INDEX);
2343 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LSCALE);
2344 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LOFFSET);
2345 D3DSTATE_TO_STR(WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS);
2346 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG0);
2347 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG0);
2348 D3DSTATE_TO_STR(WINED3D_TSS_RESULT_ARG);
2349 D3DSTATE_TO_STR(WINED3D_TSS_CONSTANT);
2350 #undef D3DSTATE_TO_STR
2351 default:
2352 FIXME("Unrecognized %u texture state!\n", state);
2353 return "unrecognized";
2354 }
2355 }
2356
2357 const char *debug_d3dtop(enum wined3d_texture_op d3dtop)
2358 {
2359 switch (d3dtop)
2360 {
2361 #define D3DTOP_TO_STR(u) case u: return #u
2362 D3DTOP_TO_STR(WINED3D_TOP_DISABLE);
2363 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG1);
2364 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG2);
2365 D3DTOP_TO_STR(WINED3D_TOP_MODULATE);
2366 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_2X);
2367 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_4X);
2368 D3DTOP_TO_STR(WINED3D_TOP_ADD);
2369 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED);
2370 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED_2X);
2371 D3DTOP_TO_STR(WINED3D_TOP_SUBTRACT);
2372 D3DTOP_TO_STR(WINED3D_TOP_ADD_SMOOTH);
2373 D3DTOP_TO_STR(WINED3D_TOP_BLEND_DIFFUSE_ALPHA);
2374 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA);
2375 D3DTOP_TO_STR(WINED3D_TOP_BLEND_FACTOR_ALPHA);
2376 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM);
2377 D3DTOP_TO_STR(WINED3D_TOP_BLEND_CURRENT_ALPHA);
2378 D3DTOP_TO_STR(WINED3D_TOP_PREMODULATE);
2379 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR);
2380 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA);
2381 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR);
2382 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA);
2383 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP);
2384 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP_LUMINANCE);
2385 D3DTOP_TO_STR(WINED3D_TOP_DOTPRODUCT3);
2386 D3DTOP_TO_STR(WINED3D_TOP_MULTIPLY_ADD);
2387 D3DTOP_TO_STR(WINED3D_TOP_LERP);
2388 #undef D3DTOP_TO_STR
2389 default:
2390 FIXME("Unrecognized texture op %#x.\n", d3dtop);
2391 return "unrecognized";
2392 }
2393 }
2394
2395 const char *debug_d3dtstype(enum wined3d_transform_state tstype)
2396 {
2397 switch (tstype)
2398 {
2399 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2400 TSTYPE_TO_STR(WINED3D_TS_VIEW);
2401 TSTYPE_TO_STR(WINED3D_TS_PROJECTION);
2402 TSTYPE_TO_STR(WINED3D_TS_TEXTURE0);
2403 TSTYPE_TO_STR(WINED3D_TS_TEXTURE1);
2404 TSTYPE_TO_STR(WINED3D_TS_TEXTURE2);
2405 TSTYPE_TO_STR(WINED3D_TS_TEXTURE3);
2406 TSTYPE_TO_STR(WINED3D_TS_TEXTURE4);
2407 TSTYPE_TO_STR(WINED3D_TS_TEXTURE5);
2408 TSTYPE_TO_STR(WINED3D_TS_TEXTURE6);
2409 TSTYPE_TO_STR(WINED3D_TS_TEXTURE7);
2410 TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(0));
2411 #undef TSTYPE_TO_STR
2412 default:
2413 if (tstype > 256 && tstype < 512)
2414 {
2415 FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype);
2416 return ("WINED3D_TS_WORLD_MATRIX > 0");
2417 }
2418 FIXME("Unrecognized transform state %#x.\n", tstype);
2419 return "unrecognized";
2420 }
2421 }
2422
2423 const char *debug_d3dstate(DWORD state)
2424 {
2425 if (STATE_IS_RENDER(state))
2426 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2427 if (STATE_IS_TEXTURESTAGE(state))
2428 {
2429 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2430 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2431 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2432 texture_stage, debug_d3dtexturestate(texture_state));
2433 }
2434 if (STATE_IS_SAMPLER(state))
2435 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2436 if (STATE_IS_PIXELSHADER(state))
2437 return "STATE_PIXELSHADER";
2438 if (STATE_IS_TRANSFORM(state))
2439 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2440 if (STATE_IS_STREAMSRC(state))
2441 return "STATE_STREAMSRC";
2442 if (STATE_IS_INDEXBUFFER(state))
2443 return "STATE_INDEXBUFFER";
2444 if (STATE_IS_VDECL(state))
2445 return "STATE_VDECL";
2446 if (STATE_IS_VSHADER(state))
2447 return "STATE_VSHADER";
2448 if (STATE_IS_GEOMETRY_SHADER(state))
2449 return "STATE_GEOMETRY_SHADER";
2450 if (STATE_IS_VIEWPORT(state))
2451 return "STATE_VIEWPORT";
2452 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2453 return "STATE_VERTEXSHADERCONSTANT";
2454 if (STATE_IS_PIXELSHADERCONSTANT(state))
2455 return "STATE_PIXELSHADERCONSTANT";
2456 if (STATE_IS_ACTIVELIGHT(state))
2457 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2458 if (STATE_IS_SCISSORRECT(state))
2459 return "STATE_SCISSORRECT";
2460 if (STATE_IS_CLIPPLANE(state))
2461 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2462 if (STATE_IS_MATERIAL(state))
2463 return "STATE_MATERIAL";
2464 if (STATE_IS_FRONTFACE(state))
2465 return "STATE_FRONTFACE";
2466 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2467 return "STATE_POINTSPRITECOORDORIGIN";
2468 if (STATE_IS_BASEVERTEXINDEX(state))
2469 return "STATE_BASEVERTEXINDEX";
2470 if (STATE_IS_FRAMEBUFFER(state))
2471 return "STATE_FRAMEBUFFER";
2472
2473 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2474 }
2475
2476 const char *debug_d3dpool(enum wined3d_pool pool)
2477 {
2478 switch (pool)
2479 {
2480 #define POOL_TO_STR(p) case p: return #p
2481 POOL_TO_STR(WINED3D_POOL_DEFAULT);
2482 POOL_TO_STR(WINED3D_POOL_MANAGED);
2483 POOL_TO_STR(WINED3D_POOL_SYSTEM_MEM);
2484 POOL_TO_STR(WINED3D_POOL_SCRATCH);
2485 #undef POOL_TO_STR
2486 default:
2487 FIXME("Unrecognized pool %#x.\n", pool);
2488 return "unrecognized";
2489 }
2490 }
2491
2492 const char *debug_fbostatus(GLenum status) {
2493 switch(status) {
2494 #define FBOSTATUS_TO_STR(u) case u: return #u
2495 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2496 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2497 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2498 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2499 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2500 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2501 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2502 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2503 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2504 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2505 #undef FBOSTATUS_TO_STR
2506 default:
2507 FIXME("Unrecognied FBO status 0x%08x\n", status);
2508 return "unrecognized";
2509 }
2510 }
2511
2512 const char *debug_glerror(GLenum error) {
2513 switch(error) {
2514 #define GLERROR_TO_STR(u) case u: return #u
2515 GLERROR_TO_STR(GL_NO_ERROR);
2516 GLERROR_TO_STR(GL_INVALID_ENUM);
2517 GLERROR_TO_STR(GL_INVALID_VALUE);
2518 GLERROR_TO_STR(GL_INVALID_OPERATION);
2519 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2520 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2521 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2522 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2523 #undef GLERROR_TO_STR
2524 default:
2525 FIXME("Unrecognied GL error 0x%08x\n", error);
2526 return "unrecognized";
2527 }
2528 }
2529
2530 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2531 {
2532 switch(source)
2533 {
2534 #define WINED3D_TO_STR(x) case x: return #x
2535 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2536 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2537 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2538 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2539 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2540 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2541 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2542 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2543 #undef WINED3D_TO_STR
2544 default:
2545 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2546 return "unrecognized";
2547 }
2548 }
2549
2550 static const char *debug_complex_fixup(enum complex_fixup fixup)
2551 {
2552 switch(fixup)
2553 {
2554 #define WINED3D_TO_STR(x) case x: return #x
2555 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2556 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2557 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2558 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2559 #undef WINED3D_TO_STR
2560 default:
2561 FIXME("Unrecognized complex fixup %#x\n", fixup);
2562 return "unrecognized";
2563 }
2564 }
2565
2566 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2567 {
2568 if (is_complex_fixup(fixup))
2569 {
2570 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2571 return;
2572 }
2573
2574 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2575 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2576 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2577 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2578 }
2579
2580 const char *debug_surflocation(DWORD flag) {
2581 char buf[128];
2582
2583 buf[0] = 0;
2584 if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM"); /* 17 */
2585 if (flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE"); /* 19 */
2586 if (flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE"); /* 18 */
2587 if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX"); /* 18 */
2588 if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE"); /* 25 */
2589 if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED"); /* 22 */
2590 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2591 }
2592
2593 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2594 enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2595 {
2596 if (op == WINED3D_TOP_DISABLE)
2597 return FALSE;
2598 if (state->textures[stage])
2599 return FALSE;
2600
2601 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2602 && op != WINED3D_TOP_SELECT_ARG2)
2603 return TRUE;
2604 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2605 && op != WINED3D_TOP_SELECT_ARG1)
2606 return TRUE;
2607 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2608 && (op == WINED3D_TOP_MULTIPLY_ADD || op == WINED3D_TOP_LERP))
2609 return TRUE;
2610
2611 return FALSE;
2612 }
2613
2614 /* Setup this textures matrix according to the texture flags. */
2615 /* Context activation is done by the caller (state handler). */
2616 void set_texture_matrix(const struct wined3d_gl_info *gl_info, const float *smat, DWORD flags,
2617 BOOL calculatedCoords, BOOL transformed, enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2618 {
2619 float mat[16];
2620
2621 gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
2622 checkGLcall("glMatrixMode(GL_TEXTURE)");
2623
2624 if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed)
2625 {
2626 gl_info->gl_ops.gl.p_glLoadIdentity();
2627 checkGLcall("glLoadIdentity()");
2628 return;
2629 }
2630
2631 if (flags == (WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED))
2632 {
2633 ERR("Invalid texture transform flags: WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED.\n");
2634 return;
2635 }
2636
2637 memcpy(mat, smat, 16 * sizeof(float));
2638
2639 if (flags & WINED3D_TTFF_PROJECTED)
2640 {
2641 if (!ffp_proj_control)
2642 {
2643 switch (flags & ~WINED3D_TTFF_PROJECTED)
2644 {
2645 case WINED3D_TTFF_COUNT2:
2646 mat[ 3] = mat[ 1];
2647 mat[ 7] = mat[ 5];
2648 mat[11] = mat[ 9];
2649 mat[15] = mat[13];
2650 mat[ 1] = mat[ 5] = mat[ 9] = mat[13] = 0.0f;
2651 break;
2652 case WINED3D_TTFF_COUNT3:
2653 mat[ 3] = mat[ 2];
2654 mat[ 7] = mat[ 6];
2655 mat[11] = mat[10];
2656 mat[15] = mat[14];
2657 mat[ 2] = mat[ 6] = mat[10] = mat[14] = 0.0f;
2658 break;
2659 }
2660 }
2661 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2662 if(!calculatedCoords) {
2663 switch(vtx_fmt)
2664 {
2665 case WINED3DFMT_R32_FLOAT:
2666 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2667 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2668 * the input value to the transformation will be 0, so the matrix value is irrelevant
2669 */
2670 mat[12] = mat[4];
2671 mat[13] = mat[5];
2672 mat[14] = mat[6];
2673 mat[15] = mat[7];
2674 break;
2675 case WINED3DFMT_R32G32_FLOAT:
2676 /* See above, just 3rd and 4th coord
2677 */
2678 mat[12] = mat[8];
2679 mat[13] = mat[9];
2680 mat[14] = mat[10];
2681 mat[15] = mat[11];
2682 break;
2683 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2684 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2685
2686 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2687 * into a bad place. The division elimination below will apply to make sure the
2688 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2689 */
2690 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2691 break;
2692 default:
2693 FIXME("Unexpected fixed function texture coord input\n");
2694 }
2695 }
2696 if (!ffp_proj_control)
2697 {
2698 switch (flags & ~WINED3D_TTFF_PROJECTED)
2699 {
2700 /* case WINED3D_TTFF_COUNT1: Won't ever get here. */
2701 case WINED3D_TTFF_COUNT2:
2702 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2703 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2704 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2705 * the 4th coord evaluates to 1.0 to eliminate that.
2706 *
2707 * If the fixed function pipeline is used, the 4th value remains unused,
2708 * so there is no danger in doing this. With vertex shaders we have a
2709 * problem. Should an app hit that problem, the code here would have to
2710 * check for pixel shaders, and the shader has to undo the default gl divide.
2711 *
2712 * A more serious problem occurs if the app passes 4 coordinates in, and the
2713 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2714 * or a replacement shader. */
2715 default:
2716 mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2717 }
2718 }
2719 }
2720
2721 gl_info->gl_ops.gl.p_glLoadMatrixf(mat);
2722 checkGLcall("glLoadMatrixf(mat)");
2723 }
2724
2725 /* This small helper function is used to convert a bitmask into the number of masked bits */
2726 unsigned int count_bits(unsigned int mask)
2727 {
2728 unsigned int count;
2729 for (count = 0; mask; ++count)
2730 {
2731 mask &= mask - 1;
2732 }
2733 return count;
2734 }
2735
2736 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2737 * The later function requires individual color components. */
2738 BOOL getColorBits(const struct wined3d_format *format,
2739 BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2740 {
2741 TRACE("format %s.\n", debug_d3dformat(format->id));
2742
2743 switch (format->id)
2744 {
2745 case WINED3DFMT_B10G10R10A2_UNORM:
2746 case WINED3DFMT_R10G10B10A2_UNORM:
2747 case WINED3DFMT_B8G8R8X8_UNORM:
2748 case WINED3DFMT_B8G8R8_UNORM:
2749 case WINED3DFMT_B8G8R8A8_UNORM:
2750 case WINED3DFMT_R8G8B8A8_UNORM:
2751 case WINED3DFMT_B5G5R5X1_UNORM:
2752 case WINED3DFMT_B5G5R5A1_UNORM:
2753 case WINED3DFMT_B5G6R5_UNORM:
2754 case WINED3DFMT_B4G4R4X4_UNORM:
2755 case WINED3DFMT_B4G4R4A4_UNORM:
2756 case WINED3DFMT_B2G3R3_UNORM:
2757 case WINED3DFMT_P8_UINT_A8_UNORM:
2758 case WINED3DFMT_P8_UINT:
2759 break;
2760 default:
2761 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2762 return FALSE;
2763 }
2764
2765 *redSize = format->red_size;
2766 *greenSize = format->green_size;
2767 *blueSize = format->blue_size;
2768 *alphaSize = format->alpha_size;
2769 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2770
2771 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2772 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2773 return TRUE;
2774 }
2775
2776 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2777 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
2778 {
2779 TRACE("format %s.\n", debug_d3dformat(format->id));
2780
2781 switch (format->id)
2782 {
2783 case WINED3DFMT_D16_LOCKABLE:
2784 case WINED3DFMT_D16_UNORM:
2785 case WINED3DFMT_S1_UINT_D15_UNORM:
2786 case WINED3DFMT_X8D24_UNORM:
2787 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2788 case WINED3DFMT_D24_UNORM_S8_UINT:
2789 case WINED3DFMT_S8_UINT_D24_FLOAT:
2790 case WINED3DFMT_D32_UNORM:
2791 case WINED3DFMT_D32_FLOAT:
2792 case WINED3DFMT_INTZ:
2793 break;
2794 default:
2795 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2796 return FALSE;
2797 }
2798
2799 *depthSize = format->depth_size;
2800 *stencilSize = format->stencil_size;
2801
2802 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2803 *depthSize, *stencilSize, debug_d3dformat(format->id));
2804 return TRUE;
2805 }
2806
2807 /* Note: It's the caller's responsibility to ensure values can be expressed
2808 * in the requested format. UNORM formats for example can only express values
2809 * in the range 0.0f -> 1.0f. */
2810 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color)
2811 {
2812 static const struct
2813 {
2814 enum wined3d_format_id format_id;
2815 float r_mul;
2816 float g_mul;
2817 float b_mul;
2818 float a_mul;
2819 BYTE r_shift;
2820 BYTE g_shift;
2821 BYTE b_shift;
2822 BYTE a_shift;
2823 }
2824 conv[] =
2825 {
2826 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2827 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2828 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2829 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2830 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2831 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2832 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2833 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2834 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2835 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2836 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2837 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2838 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2839 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2840 };
2841 const struct wined3d_format *format = surface->resource.format;
2842 unsigned int i;
2843
2844 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2845 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2846
2847 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2848 {
2849 DWORD ret;
2850
2851 if (format->id != conv[i].format_id) continue;
2852
2853 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2854 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2855 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2856 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2857
2858 TRACE("Returning 0x%08x.\n", ret);
2859
2860 return ret;
2861 }
2862
2863 if (format->id == WINED3DFMT_P8_UINT)
2864 {
2865 PALETTEENTRY *e;
2866 BYTE r, g, b, a;
2867
2868 if (!surface->palette)
2869 {
2870 WARN("Surface doesn't have a palette, returning 0.\n");
2871 return 0;
2872 }
2873
2874 r = (BYTE)((color->r * 255.0f) + 0.5f);
2875 g = (BYTE)((color->g * 255.0f) + 0.5f);
2876 b = (BYTE)((color->b * 255.0f) + 0.5f);
2877 a = (BYTE)((color->a * 255.0f) + 0.5f);
2878
2879 e = &surface->palette->palents[a];
2880 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2881 return a;
2882
2883 WARN("Alpha didn't match index, searching full palette.\n");
2884
2885 for (i = 0; i < 256; ++i)
2886 {
2887 e = &surface->palette->palents[i];
2888 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2889 return i;
2890 }
2891
2892 FIXME("Unable to convert color to palette index.\n");
2893
2894 return 0;
2895 }
2896
2897 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2898
2899 return 0;
2900 }
2901
2902 /* DirectDraw stuff */
2903 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2904 {
2905 switch (depth)
2906 {
2907 case 8: return WINED3DFMT_P8_UINT;
2908 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2909 case 16: return WINED3DFMT_B5G6R5_UNORM;
2910 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2911 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2912 default: return WINED3DFMT_UNKNOWN;
2913 }
2914 }
2915
2916 void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
2917 const struct wined3d_matrix *src2)
2918 {
2919 struct wined3d_matrix temp;
2920
2921 /* Now do the multiplication 'by hand'.
2922 I know that all this could be optimised, but this will be done later :-) */
2923 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);
2924 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);
2925 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);
2926 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);
2927
2928 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);
2929 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);
2930 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);
2931 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);
2932
2933 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);
2934 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);
2935 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);
2936 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);
2937
2938 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);
2939 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);
2940 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);
2941 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);
2942
2943 /* And copy the new matrix in the good storage.. */
2944 memcpy(dest, &temp, 16 * sizeof(float));
2945 }
2946
2947 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2948 DWORD size = 0;
2949 int i;
2950 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2951
2952 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2953 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2954 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2955 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2956 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2957 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2958 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2959 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2960 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2961 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2962 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2963 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2964 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2965 default: ERR("Unexpected position mask\n");
2966 }
2967 for (i = 0; i < numTextures; i++) {
2968 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2969 }
2970
2971 return size;
2972 }
2973
2974 void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_state *state,
2975 struct ffp_frag_settings *settings, BOOL ignore_textype)
2976 {
2977 #define ARG1 0x01
2978 #define ARG2 0x02
2979 #define ARG0 0x04
2980 static const unsigned char args[WINED3D_TOP_LERP + 1] =
2981 {
2982 /* undefined */ 0,
2983 /* D3DTOP_DISABLE */ 0,
2984 /* D3DTOP_SELECTARG1 */ ARG1,
2985 /* D3DTOP_SELECTARG2 */ ARG2,
2986 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2987 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2988 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2989 /* D3DTOP_ADD */ ARG1 | ARG2,
2990 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2991 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2992 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2993 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2994 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2995 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2996 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2997 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2998 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2999 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
3000 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
3001 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
3002 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
3003 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
3004 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
3005 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
3006 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
3007 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
3008 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
3009 };
3010 unsigned int i;
3011 DWORD ttff;
3012 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
3013 const struct wined3d_surface *rt = state->fb->render_targets[0];
3014 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
3015
3016 for (i = 0; i < gl_info->limits.texture_stages; ++i)
3017 {
3018 const struct wined3d_texture *texture;
3019
3020 settings->op[i].padding = 0;
3021 if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
3022 {
3023 settings->op[i].cop = WINED3D_TOP_DISABLE;
3024 settings->op[i].aop = WINED3D_TOP_DISABLE;
3025 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
3026 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
3027 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
3028 settings->op[i].dst = resultreg;
3029 settings->op[i].tex_type = tex_1d;
3030 settings->op[i].projected = proj_none;
3031 i++;
3032 break;
3033 }
3034
3035 if ((texture = state->textures[i]))
3036 {
3037 settings->op[i].color_fixup = texture->resource.format->color_fixup;
3038 if (ignore_textype)
3039 {
3040 settings->op[i].tex_type = tex_1d;
3041 }
3042 else
3043 {
3044 switch (texture->target)
3045 {
3046 case GL_TEXTURE_1D:
3047 settings->op[i].tex_type = tex_1d;
3048 break;
3049 case GL_TEXTURE_2D:
3050 settings->op[i].tex_type = tex_2d;
3051 break;
3052 case GL_TEXTURE_3D:
3053 settings->op[i].tex_type = tex_3d;
3054 break;
3055 case GL_TEXTURE_CUBE_MAP_ARB:
3056 settings->op[i].tex_type = tex_cube;
3057 break;
3058 case GL_TEXTURE_RECTANGLE_ARB:
3059 settings->op[i].tex_type = tex_rect;
3060 break;
3061 }
3062 }
3063 } else {
3064 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
3065 settings->op[i].tex_type = tex_1d;
3066 }
3067
3068 cop = state->texture_states[i][WINED3D_TSS_COLOR_OP];
3069 aop = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
3070
3071 carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG1] : ARG_UNUSED;
3072 carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG2] : ARG_UNUSED;
3073 carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG0] : ARG_UNUSED;
3074
3075 if (is_invalid_op(state, i, cop, carg1, carg2, carg0))
3076 {
3077 carg0 = ARG_UNUSED;
3078 carg2 = ARG_UNUSED;
3079 carg1 = WINED3DTA_CURRENT;
3080 cop = WINED3D_TOP_SELECT_ARG1;
3081 }
3082
3083 if (cop == WINED3D_TOP_DOTPRODUCT3)
3084 {
3085 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
3086 * the color result to the alpha component of the destination
3087 */
3088 aop = cop;
3089 aarg1 = carg1;
3090 aarg2 = carg2;
3091 aarg0 = carg0;
3092 }
3093 else
3094 {
3095 aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] : ARG_UNUSED;
3096 aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] : ARG_UNUSED;
3097 aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] : ARG_UNUSED;
3098 }
3099
3100 if (!i && state->textures[0] && state->render_states[WINED3D_RS_COLORKEYENABLE])
3101 {
3102 GLenum texture_dimensions;
3103
3104 texture = state->textures[0];
3105 texture_dimensions = texture->target;
3106
3107 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3108 {
3109 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3110
3111 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size)
3112 {
3113 if (aop == WINED3D_TOP_DISABLE)
3114 {
3115 aarg1 = WINED3DTA_TEXTURE;
3116 aop = WINED3D_TOP_SELECT_ARG1;
3117 }
3118 else if (aop == WINED3D_TOP_SELECT_ARG1 && aarg1 != WINED3DTA_TEXTURE)
3119 {
3120 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3121 {
3122 aarg2 = WINED3DTA_TEXTURE;
3123 aop = WINED3D_TOP_MODULATE;
3124 }
3125 else aarg1 = WINED3DTA_TEXTURE;
3126 }
3127 else if (aop == WINED3D_TOP_SELECT_ARG2 && aarg2 != WINED3DTA_TEXTURE)
3128 {
3129 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3130 {
3131 aarg1 = WINED3DTA_TEXTURE;
3132 aop = WINED3D_TOP_MODULATE;
3133 }
3134 else aarg2 = WINED3DTA_TEXTURE;
3135 }
3136 }
3137 }
3138 }
3139
3140 if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0))
3141 {
3142 aarg0 = ARG_UNUSED;
3143 aarg2 = ARG_UNUSED;
3144 aarg1 = WINED3DTA_CURRENT;
3145 aop = WINED3D_TOP_SELECT_ARG1;
3146 }
3147
3148 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
3149 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
3150 {
3151 ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
3152 if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3))
3153 settings->op[i].projected = proj_count3;
3154 else if (ttff & WINED3D_TTFF_PROJECTED)
3155 settings->op[i].projected = proj_count4;
3156 else
3157 settings->op[i].projected = proj_none;
3158 }
3159 else
3160 {
3161 settings->op[i].projected = proj_none;
3162 }
3163
3164 settings->op[i].cop = cop;
3165 settings->op[i].aop = aop;
3166 settings->op[i].carg0 = carg0;
3167 settings->op[i].carg1 = carg1;
3168 settings->op[i].carg2 = carg2;
3169 settings->op[i].aarg0 = aarg0;
3170 settings->op[i].aarg1 = aarg1;
3171 settings->op[i].aarg2 = aarg2;
3172
3173 if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP)
3174 settings->op[i].dst = tempreg;
3175 else
3176 settings->op[i].dst = resultreg;
3177 }
3178
3179 /* Clear unsupported stages */
3180 for(; i < MAX_TEXTURES; i++) {
3181 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
3182 }
3183
3184 if (!state->render_states[WINED3D_RS_FOGENABLE])
3185 {
3186 settings->fog = FOG_OFF;
3187 }
3188 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
3189 {
3190 if (use_vs(state) || state->vertex_declaration->position_transformed)
3191 {
3192 settings->fog = FOG_LINEAR;
3193 }
3194 else
3195 {
3196 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
3197 {
3198 case WINED3D_FOG_NONE:
3199 case WINED3D_FOG_LINEAR:
3200 settings->fog = FOG_LINEAR;
3201 break;
3202 case WINED3D_FOG_EXP:
3203 settings->fog = FOG_EXP;
3204 break;
3205 case WINED3D_FOG_EXP2:
3206 settings->fog = FOG_EXP2;
3207 break;
3208 }
3209 }
3210 }
3211 else
3212 {
3213 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
3214 {
3215 case WINED3D_FOG_LINEAR:
3216 settings->fog = FOG_LINEAR;
3217 break;
3218 case WINED3D_FOG_EXP:
3219 settings->fog = FOG_EXP;
3220 break;
3221 case WINED3D_FOG_EXP2:
3222 settings->fog = FOG_EXP2;
3223 break;
3224 }
3225 }
3226 if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB]
3227 && state->render_states[WINED3D_RS_SRGBWRITEENABLE]
3228 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
3229 {
3230 settings->sRGB_write = 1;
3231 } else {
3232 settings->sRGB_write = 0;
3233 }
3234 if (device->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
3235 || !state->render_states[WINED3D_RS_CLIPPLANEENABLE])
3236 {
3237 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3238 * the fixed function vertex pipeline is used(which always supports clipplanes), or
3239 * if no clipplane is enabled
3240 */
3241 settings->emul_clipplanes = 0;
3242 } else {
3243 settings->emul_clipplanes = 1;
3244 }
3245 }
3246
3247 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3248 const struct ffp_frag_settings *settings)
3249 {
3250 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3251 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3252 }
3253
3254 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3255 {
3256 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3257 * whereas desc points to an extended structure with implementation specific parts. */
3258 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3259 {
3260 ERR("Failed to insert ffp frag shader.\n");
3261 }
3262 }
3263
3264 /* Activates the texture dimension according to the bound D3D texture. Does
3265 * not care for the colorop or correct gl texture unit (when using nvrc).
3266 * Requires the caller to activate the correct unit. */
3267 /* Context activation is done by the caller (state handler). */
3268 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3269 {
3270 if (texture)
3271 {
3272 switch (texture->target)
3273 {
3274 case GL_TEXTURE_2D:
3275 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3276 checkGLcall("glDisable(GL_TEXTURE_3D)");
3277 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3278 {
3279 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3280 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3281 }
3282 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3283 {
3284 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3285 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3286 }
3287 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3288 checkGLcall("glEnable(GL_TEXTURE_2D)");
3289 break;
3290 case GL_TEXTURE_RECTANGLE_ARB:
3291 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3292 checkGLcall("glDisable(GL_TEXTURE_2D)");
3293 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3294 checkGLcall("glDisable(GL_TEXTURE_3D)");
3295 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3296 {
3297 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3298 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3299 }
3300 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_RECTANGLE_ARB);
3301 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3302 break;
3303 case GL_TEXTURE_3D:
3304 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3305 {
3306 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3307 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3308 }
3309 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3310 {
3311 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3312 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3313 }
3314 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3315 checkGLcall("glDisable(GL_TEXTURE_2D)");
3316 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D);
3317 checkGLcall("glEnable(GL_TEXTURE_3D)");
3318 break;
3319 case GL_TEXTURE_CUBE_MAP_ARB:
3320 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3321 checkGLcall("glDisable(GL_TEXTURE_2D)");
3322 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3323 checkGLcall("glDisable(GL_TEXTURE_3D)");
3324 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3325 {
3326 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3327 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3328 }
3329 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3330 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3331 break;
3332 }
3333 }
3334 else
3335 {
3336 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3337 checkGLcall("glEnable(GL_TEXTURE_2D)");
3338 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3339 checkGLcall("glDisable(GL_TEXTURE_3D)");
3340 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3341 {
3342 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3343 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3344 }
3345 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3346 {
3347 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3348 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3349 }
3350 /* Binding textures is done by samplers. A dummy texture will be bound */
3351 }
3352 }
3353
3354 /* Context activation is done by the caller (state handler). */
3355 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3356 {
3357 DWORD sampler = state_id - STATE_SAMPLER(0);
3358 DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
3359
3360 /* No need to enable / disable anything here for unused samplers. The
3361 * tex_colorop handler takes care. Also no action is needed with pixel
3362 * shaders, or if tex_colorop will take care of this business. */
3363 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
3364 return;
3365 if (sampler >= state->lowest_disabled_stage)
3366 return;
3367 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)))
3368 return;
3369
3370 texture_activate_dimensions(state->textures[sampler], context->gl_info);
3371 }
3372
3373 void *wined3d_rb_alloc(size_t size)
3374 {
3375 return HeapAlloc(GetProcessHeap(), 0, size);
3376 }
3377
3378 void *wined3d_rb_realloc(void *ptr, size_t size)
3379 {
3380 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3381 }
3382
3383 void wined3d_rb_free(void *ptr)
3384 {
3385 HeapFree(GetProcessHeap(), 0, ptr);
3386 }
3387
3388 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3389 {
3390 const struct ffp_frag_settings *ka = key;
3391 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3392
3393 return memcmp(ka, kb, sizeof(*ka));
3394 }
3395
3396 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3397 {
3398 wined3d_rb_alloc,
3399 wined3d_rb_realloc,
3400 wined3d_rb_free,
3401 ffp_frag_program_key_compare,
3402 };
3403
3404 UINT wined3d_log2i(UINT32 x)
3405 {
3406 static const UINT l[] =
3407 {
3408 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3409 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3410 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3411 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3412 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3413 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3414 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3415 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3416 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3417 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3418 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3419 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3420 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3421 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3422 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3423 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3424 };
3425 UINT32 i;
3426
3427 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3428 }
3429
3430 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3431 const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
3432 const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
3433 {
3434 static const struct blit_shader * const blitters[] =
3435 {
3436 &arbfp_blit,
3437 &ffp_blit,
3438 &cpu_blit,
3439 };
3440 unsigned int i;
3441
3442 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3443 {
3444 if (blitters[i]->blit_supported(gl_info, blit_op,
3445 src_rect, src_usage, src_pool, src_format,
3446 dst_rect, dst_usage, dst_pool, dst_format))
3447 return blitters[i];
3448 }
3449
3450 return NULL;
3451 }
3452
3453 void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
3454 {
3455 const struct wined3d_viewport *vp = &state->viewport;
3456
3457 SetRect(rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
3458
3459 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
3460 IntersectRect(rect, rect, &state->scissor_rect);
3461 }