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