wined3d: Don't use floating point textures without ARB_texture_float.
[wine/multimedia.git] / dlls / wined3d / utils.c
blob8770f047ab7c4d7e80b211e630491bb786d91401
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 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 "wined3d_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
32 struct StaticPixelFormatDesc
34 enum wined3d_format_id id;
35 DWORD alphaMask, redMask, greenMask, blueMask;
36 UINT bpp;
37 short depthSize, stencilSize;
40 /*****************************************************************************
41 * Pixel format array
43 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
44 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
45 * high masks do not fit into the 32 bit values needed for ddraw. It is only
46 * used for ddraw mostly, and to figure out if the format has alpha at all, so
47 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
48 * formats are not usable in 2D rendering because ddraw doesn't support them.
50 static const struct StaticPixelFormatDesc formats[] =
52 /* format id alphamask redmask greenmask bluemask bpp depth stencil */
53 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
54 /* FourCC formats */
55 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
56 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
57 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
58 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
59 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
60 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
61 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
62 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
63 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
64 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
65 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
66 /* IEEE formats */
67 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
68 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
69 {WINED3DFMT_R32G32B32_FLOAT, 0x0, 0x0, 0x0, 0x0, 12, 0, 0},
70 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0},
71 /* Hmm? */
72 {WINED3DFMT_R8G8_SNORM_Cx, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
73 /* Float */
74 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
75 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
76 {WINED3DFMT_R16G16_SINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
77 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
78 {WINED3DFMT_R16G16B16A16_SINT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
79 /* Palettized formats */
80 {WINED3DFMT_P8_UINT_A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
81 {WINED3DFMT_P8_UINT, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
82 /* Standard ARGB formats. */
83 {WINED3DFMT_B8G8R8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0},
84 {WINED3DFMT_B8G8R8A8_UNORM, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
85 {WINED3DFMT_B8G8R8X8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
86 {WINED3DFMT_B5G6R5_UNORM, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0},
87 {WINED3DFMT_B5G5R5X1_UNORM, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
88 {WINED3DFMT_B5G5R5A1_UNORM, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
89 {WINED3DFMT_B4G4R4A4_UNORM, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
90 {WINED3DFMT_B2G3R3_UNORM, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0},
91 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0},
92 {WINED3DFMT_B2G3R3A8_UNORM, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0},
93 {WINED3DFMT_B4G4R4X4_UNORM, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
94 {WINED3DFMT_R10G10B10A2_UNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
95 {WINED3DFMT_R10G10B10A2_UINT, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
96 {WINED3DFMT_R10G10B10A2_SNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
97 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
98 {WINED3DFMT_R8G8B8A8_UINT, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
99 {WINED3DFMT_R8G8B8X8_UNORM, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
100 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0},
101 {WINED3DFMT_B10G10R10A2_UNORM, 0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0},
102 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0},
103 /* Luminance */
104 {WINED3DFMT_L8_UNORM, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
105 {WINED3DFMT_L8A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
106 {WINED3DFMT_L4A4_UNORM, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0},
107 {WINED3DFMT_L16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
108 /* Bump mapping stuff */
109 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
110 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
111 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
112 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
113 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
114 {WINED3DFMT_R10G11B11_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
115 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0},
116 /* Depth stencil formats */
117 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
118 {WINED3DFMT_D32_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
119 {WINED3DFMT_S1_UINT_D15_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 15, 1},
120 {WINED3DFMT_D24_UNORM_S8_UINT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
121 {WINED3DFMT_X8D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 0},
122 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 4},
123 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
124 {WINED3DFMT_D32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
125 {WINED3DFMT_S8_UINT_D24_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
126 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
127 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
128 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
129 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
130 /* Vendor-specific formats */
131 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
132 {WINED3DFMT_NVDB, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
133 {WINED3DFMT_INTZ, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
134 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
135 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 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_UYVY, WINED3DFMT_FLAG_FOURCC},
150 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
151 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
152 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
153 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
156 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
157 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
158 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
159 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
160 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
161 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
162 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
163 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
164 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
165 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
166 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
171 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
172 {WINED3DFMT_NVDB, WINED3DFMT_FLAG_FOURCC},
173 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
174 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
175 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
176 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
177 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
178 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
179 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
181 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
182 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
186 struct wined3d_format_compression_info
188 enum wined3d_format_id id;
189 UINT block_width;
190 UINT block_height;
191 UINT block_byte_count;
194 static const struct wined3d_format_compression_info format_compression_info[] =
196 {WINED3DFMT_DXT1, 4, 4, 8},
197 {WINED3DFMT_DXT2, 4, 4, 16},
198 {WINED3DFMT_DXT3, 4, 4, 16},
199 {WINED3DFMT_DXT4, 4, 4, 16},
200 {WINED3DFMT_DXT5, 4, 4, 16},
201 {WINED3DFMT_ATI2N, 4, 4, 16},
204 struct wined3d_format_vertex_info
206 enum wined3d_format_id id;
207 enum wined3d_ffp_emit_idx emit_idx;
208 GLint component_count;
209 GLenum gl_vtx_type;
210 GLint gl_vtx_format;
211 GLboolean gl_normalized;
212 unsigned int component_size;
215 static const struct wined3d_format_vertex_info format_vertex_info[] =
217 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
218 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
219 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
220 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
221 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
222 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
223 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
224 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
225 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
226 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
227 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
228 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
229 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
230 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
231 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
232 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
233 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
236 struct wined3d_format_texture_info
238 enum wined3d_format_id id;
239 GLint gl_internal;
240 GLint gl_srgb_internal;
241 GLint gl_rt_internal;
242 GLint gl_format;
243 GLint gl_type;
244 unsigned int conv_byte_count;
245 unsigned int flags;
246 GL_SupportedExt extension;
247 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
250 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
252 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
253 * format+type combination to load it. Thus convert it to A8L8, then load it
254 * with A4L4 internal, but A8L8 format+type
256 unsigned int x, y;
257 const unsigned char *Source;
258 unsigned char *Dest;
259 UINT outpitch = pitch * 2;
261 for(y = 0; y < height; y++) {
262 Source = src + y * pitch;
263 Dest = dst + y * outpitch;
264 for (x = 0; x < width; x++ ) {
265 unsigned char color = (*Source++);
266 /* A */ Dest[1] = (color & 0xf0) << 0;
267 /* L */ Dest[0] = (color & 0x0f) << 4;
268 Dest += 2;
273 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
275 unsigned int x, y;
276 const WORD *Source;
278 for(y = 0; y < height; y++)
280 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
281 Source = (const WORD *)(src + y * pitch);
282 for (x = 0; x < width; x++ )
284 short color = (*Source++);
285 unsigned char l = ((color >> 10) & 0xfc);
286 short v = ((color >> 5) & 0x3e);
287 short u = ((color ) & 0x1f);
288 short v_conv = v + 16;
289 short u_conv = u + 16;
291 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
292 Dest_s += 1;
297 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
299 unsigned int x, y;
300 const WORD *Source;
301 unsigned char *Dest;
302 UINT outpitch = (pitch * 3)/2;
304 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
305 * fixed function and shaders without further conversion once the surface is
306 * loaded
308 for(y = 0; y < height; y++) {
309 Source = (const WORD *)(src + y * pitch);
310 Dest = dst + y * outpitch;
311 for (x = 0; x < width; x++ ) {
312 short color = (*Source++);
313 unsigned char l = ((color >> 10) & 0xfc);
314 char v = ((color >> 5) & 0x3e);
315 char u = ((color ) & 0x1f);
317 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
318 * and doubles the positive range. Thus shift left only once, gl does the 2nd
319 * shift. GL reads a signed value and converts it into an unsigned value.
321 /* M */ Dest[2] = l << 1;
323 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
324 * from 5 bit values to 8 bit values.
326 /* V */ Dest[1] = v << 3;
327 /* U */ Dest[0] = u << 3;
328 Dest += 3;
333 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
335 unsigned int x, y;
336 const short *Source;
337 unsigned char *Dest;
338 UINT outpitch = (pitch * 3)/2;
340 for(y = 0; y < height; y++)
342 Source = (const short *)(src + y * pitch);
343 Dest = dst + y * outpitch;
344 for (x = 0; x < width; x++ )
346 LONG color = (*Source++);
347 /* B */ Dest[0] = 0xff;
348 /* G */ Dest[1] = (color >> 8) + 128; /* V */
349 /* R */ Dest[2] = (color) + 128; /* U */
350 Dest += 3;
355 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
357 unsigned int x, y;
358 const DWORD *Source;
359 unsigned char *Dest;
361 /* Doesn't work correctly with the fixed function pipeline, but can work in
362 * shaders if the shader is adjusted. (There's no use for this format in gl's
363 * standard fixed function pipeline anyway).
365 for(y = 0; y < height; y++)
367 Source = (const DWORD *)(src + y * pitch);
368 Dest = dst + y * pitch;
369 for (x = 0; x < width; x++ )
371 LONG color = (*Source++);
372 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
373 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
374 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
375 Dest += 4;
380 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
382 unsigned int x, y;
383 const DWORD *Source;
384 unsigned char *Dest;
386 /* This implementation works with the fixed function pipeline and shaders
387 * without further modification after converting the surface.
389 for(y = 0; y < height; y++)
391 Source = (const DWORD *)(src + y * pitch);
392 Dest = dst + y * pitch;
393 for (x = 0; x < width; x++ )
395 LONG color = (*Source++);
396 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
397 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
398 /* U */ Dest[0] = (color & 0xff); /* U */
399 /* I */ Dest[3] = 255; /* X */
400 Dest += 4;
405 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
407 unsigned int x, y;
408 const DWORD *Source;
409 unsigned char *Dest;
411 for(y = 0; y < height; y++)
413 Source = (const DWORD *)(src + y * pitch);
414 Dest = dst + y * pitch;
415 for (x = 0; x < width; x++ )
417 LONG color = (*Source++);
418 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
419 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
420 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
421 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
422 Dest += 4;
427 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
429 unsigned int x, y;
430 const DWORD *Source;
431 unsigned short *Dest;
432 UINT outpitch = (pitch * 3)/2;
434 for(y = 0; y < height; y++)
436 Source = (const DWORD *)(src + y * pitch);
437 Dest = (unsigned short *) (dst + y * outpitch);
438 for (x = 0; x < width; x++ )
440 DWORD color = (*Source++);
441 /* B */ Dest[0] = 0xffff;
442 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
443 /* R */ Dest[2] = (color ) + 32768; /* U */
444 Dest += 3;
449 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
451 unsigned int x, y;
452 const WORD *Source;
453 WORD *Dest;
454 UINT outpitch = (pitch * 3)/2;
456 for(y = 0; y < height; y++)
458 Source = (const WORD *)(src + y * pitch);
459 Dest = (WORD *) (dst + y * outpitch);
460 for (x = 0; x < width; x++ )
462 WORD green = (*Source++);
463 WORD red = (*Source++);
464 Dest[0] = green;
465 Dest[1] = red;
466 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
467 * shader overwrites it anyway
469 Dest[2] = 0xffff;
470 Dest += 3;
475 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
477 unsigned int x, y;
478 const float *Source;
479 float *Dest;
480 UINT outpitch = (pitch * 3)/2;
482 for(y = 0; y < height; y++)
484 Source = (const float *)(src + y * pitch);
485 Dest = (float *) (dst + y * outpitch);
486 for (x = 0; x < width; x++ )
488 float green = (*Source++);
489 float red = (*Source++);
490 Dest[0] = green;
491 Dest[1] = red;
492 Dest[2] = 1.0f;
493 Dest += 3;
498 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
500 unsigned int x, y;
501 UINT outpitch = pitch * 2;
503 for (y = 0; y < height; ++y)
505 const WORD *source = (const WORD *)(src + y * pitch);
506 DWORD *dest = (DWORD *)(dst + y * outpitch);
508 for (x = 0; x < width; ++x)
510 /* The depth data is normalized, so needs to be scaled,
511 * the stencil data isn't. Scale depth data by
512 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
513 WORD d15 = source[x] >> 1;
514 DWORD d24 = (d15 << 9) + (d15 >> 6);
515 dest[x] = (d24 << 8) | (source[x] & 0x1);
520 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
522 unsigned int x, y;
524 for (y = 0; y < height; ++y)
526 const DWORD *source = (const DWORD *)(src + y * pitch);
527 DWORD *dest = (DWORD *)(dst + y * pitch);
529 for (x = 0; x < width; ++x)
531 /* Just need to clear out the X4 part. */
532 dest[x] = source[x] & ~0xf0;
537 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
539 unsigned int x, y;
540 UINT outpitch = pitch * 2;
542 for (y = 0; y < height; ++y)
544 const DWORD *source = (const DWORD *)(src + y * pitch);
545 float *dest_f = (float *)(dst + y * outpitch);
546 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
548 for (x = 0; x < width; ++x)
550 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
551 dest_s[x * 2 + 1] = source[x] & 0xff;
556 static const struct wined3d_format_texture_info format_texture_info[] =
558 /* format id internal srgbInternal rtInternal
559 format type
560 flags
561 extension */
562 /* FourCC formats */
563 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
564 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
565 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
566 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
567 * endian machine
569 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
570 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
571 WINED3DFMT_FLAG_FILTERING,
572 WINED3D_GL_EXT_NONE, NULL},
573 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
574 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
575 WINED3DFMT_FLAG_FILTERING,
576 APPLE_YCBCR_422, NULL},
577 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
578 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
579 WINED3DFMT_FLAG_FILTERING,
580 WINED3D_GL_EXT_NONE, NULL},
581 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
582 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
583 WINED3DFMT_FLAG_FILTERING,
584 APPLE_YCBCR_422, NULL},
585 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
586 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
587 WINED3DFMT_FLAG_FILTERING,
588 WINED3D_GL_EXT_NONE, NULL},
589 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
590 GL_RGBA, GL_UNSIGNED_BYTE, 0,
591 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
592 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
593 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
594 GL_RGBA, GL_UNSIGNED_BYTE, 0,
595 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
596 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
597 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
598 GL_RGBA, GL_UNSIGNED_BYTE, 0,
599 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
600 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
601 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
602 GL_RGBA, GL_UNSIGNED_BYTE, 0,
603 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
604 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
605 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
606 GL_RGBA, GL_UNSIGNED_BYTE, 0,
607 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
608 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
609 /* IEEE formats */
610 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
611 GL_RED, GL_FLOAT, 0,
612 WINED3DFMT_FLAG_RENDERTARGET,
613 ARB_TEXTURE_FLOAT, NULL},
614 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
615 GL_RED, GL_FLOAT, 0,
616 WINED3DFMT_FLAG_RENDERTARGET,
617 ARB_TEXTURE_RG, NULL},
618 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
619 GL_RGB, GL_FLOAT, 12,
620 WINED3DFMT_FLAG_RENDERTARGET,
621 ARB_TEXTURE_FLOAT, &convert_r32g32_float},
622 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
623 GL_RG, GL_FLOAT, 0,
624 WINED3DFMT_FLAG_RENDERTARGET,
625 ARB_TEXTURE_RG, NULL},
626 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
627 GL_RGBA, GL_FLOAT, 0,
628 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
629 ARB_TEXTURE_FLOAT, NULL},
630 /* Float */
631 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
632 GL_RED, GL_HALF_FLOAT_ARB, 0,
633 WINED3DFMT_FLAG_RENDERTARGET,
634 ARB_TEXTURE_FLOAT, NULL},
635 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
636 GL_RED, GL_HALF_FLOAT_ARB, 0,
637 WINED3DFMT_FLAG_RENDERTARGET,
638 ARB_TEXTURE_RG, NULL},
639 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
640 GL_RGB, GL_HALF_FLOAT_ARB, 6,
641 WINED3DFMT_FLAG_RENDERTARGET,
642 ARB_TEXTURE_FLOAT, &convert_r16g16},
643 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
644 GL_RG, GL_HALF_FLOAT_ARB, 0,
645 WINED3DFMT_FLAG_RENDERTARGET,
646 ARB_TEXTURE_RG, NULL},
647 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
648 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
649 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
650 ARB_TEXTURE_FLOAT, NULL},
651 /* Palettized formats */
652 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
653 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
655 ARB_FRAGMENT_PROGRAM, NULL},
656 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
657 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
659 EXT_PALETTED_TEXTURE, NULL},
660 /* Standard ARGB formats */
661 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
662 GL_BGR, GL_UNSIGNED_BYTE, 0,
663 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
664 WINED3D_GL_EXT_NONE, NULL},
665 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
666 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
667 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
668 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
669 WINED3D_GL_EXT_NONE, NULL},
670 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
671 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
672 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
673 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
674 WINED3D_GL_EXT_NONE, NULL},
675 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
676 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
677 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
678 WINED3D_GL_EXT_NONE, NULL},
679 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
680 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
681 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
682 WINED3D_GL_EXT_NONE, NULL},
683 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
684 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
685 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
686 WINED3D_GL_EXT_NONE, NULL},
687 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
688 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
689 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
690 WINED3D_GL_EXT_NONE, NULL},
691 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
692 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
693 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
694 WINED3D_GL_EXT_NONE, NULL},
695 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
696 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
697 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
698 WINED3D_GL_EXT_NONE, NULL},
699 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
700 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
701 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
702 WINED3D_GL_EXT_NONE, NULL},
703 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
704 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
705 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
706 WINED3D_GL_EXT_NONE, NULL},
707 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
708 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
709 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
710 WINED3D_GL_EXT_NONE, NULL},
711 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
712 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
713 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
714 WINED3D_GL_EXT_NONE, NULL},
715 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
716 GL_RGB, GL_UNSIGNED_SHORT, 6,
717 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
718 WINED3D_GL_EXT_NONE, &convert_r16g16},
719 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
720 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
721 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
722 WINED3D_GL_EXT_NONE, NULL},
723 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
724 GL_RGBA, GL_UNSIGNED_SHORT, 0,
725 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
726 WINED3D_GL_EXT_NONE, NULL},
727 /* Luminance */
728 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
729 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
730 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
731 WINED3D_GL_EXT_NONE, NULL},
732 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
733 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
734 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
735 WINED3D_GL_EXT_NONE, NULL},
736 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
737 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
739 WINED3D_GL_EXT_NONE, &convert_l4a4_unorm},
740 /* Bump mapping stuff */
741 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
742 GL_BGR, GL_UNSIGNED_BYTE, 3,
743 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
744 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm},
745 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
746 GL_DSDT_NV, GL_BYTE, 0,
747 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
748 NV_TEXTURE_SHADER, NULL},
749 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
750 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
751 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
752 WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm},
753 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
754 GL_DSDT_MAG_NV, GL_BYTE, 3,
755 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
756 NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv},
757 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
758 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
759 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
760 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm},
761 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
762 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
763 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
764 NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv},
765 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
766 GL_BGRA, GL_UNSIGNED_BYTE, 4,
767 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
768 WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm},
769 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
770 GL_RGBA, GL_BYTE, 0,
771 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
772 NV_TEXTURE_SHADER, NULL},
773 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
774 GL_BGR, GL_UNSIGNED_SHORT, 6,
775 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
776 WINED3D_GL_EXT_NONE, &convert_r16g16_snorm},
777 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
778 GL_HILO_NV, GL_SHORT, 0,
779 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
780 NV_TEXTURE_SHADER, NULL},
781 /* Depth stencil formats */
782 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
783 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
784 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
785 ARB_DEPTH_TEXTURE, NULL},
786 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
787 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
788 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
789 ARB_DEPTH_TEXTURE, NULL},
790 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
791 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
792 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
793 ARB_DEPTH_TEXTURE, NULL},
794 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
795 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
796 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
797 EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm},
798 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
799 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
800 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
801 ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm},
802 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
803 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
804 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
805 | WINED3DFMT_FLAG_SHADOW,
806 ARB_DEPTH_TEXTURE, NULL},
807 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
808 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
809 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
810 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
811 EXT_PACKED_DEPTH_STENCIL, NULL},
812 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
813 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
814 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
815 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
816 ARB_FRAMEBUFFER_OBJECT, NULL},
817 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
818 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
819 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
820 | WINED3DFMT_FLAG_SHADOW,
821 ARB_DEPTH_TEXTURE, NULL},
822 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
823 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
824 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
825 ARB_DEPTH_TEXTURE, NULL},
826 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
827 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
828 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
829 EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm},
830 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
831 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
832 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
833 ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm},
834 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
835 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
836 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
837 | WINED3DFMT_FLAG_SHADOW,
838 ARB_DEPTH_TEXTURE, NULL},
839 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
840 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
841 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
842 WINED3D_GL_EXT_NONE, NULL},
843 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
844 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
845 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
846 ARB_DEPTH_BUFFER_FLOAT, NULL},
847 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
848 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
849 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
850 ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float},
851 /* Vendor-specific formats */
852 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
853 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
854 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
855 ATI_TEXTURE_COMPRESSION_3DC, NULL},
856 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2, GL_COMPRESSED_RED_GREEN_RGTC2, 0,
857 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
858 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
859 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
860 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
861 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
862 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
863 | WINED3DFMT_FLAG_STENCIL,
864 EXT_PACKED_DEPTH_STENCIL, NULL},
865 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
866 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
867 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
868 | WINED3DFMT_FLAG_STENCIL,
869 ARB_FRAMEBUFFER_OBJECT, NULL},
872 static inline int getFmtIdx(enum wined3d_format_id format_id)
874 /* First check if the format is at the position of its value.
875 * This will catch the argb formats before the loop is entered. */
876 if (format_id < (sizeof(formats) / sizeof(*formats))
877 && formats[format_id].id == format_id)
879 return format_id;
881 else
883 unsigned int i;
885 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
887 if (formats[i].id == format_id) return i;
890 return -1;
893 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
895 UINT format_count = sizeof(formats) / sizeof(*formats);
896 UINT i;
898 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
899 if (!gl_info->formats)
901 ERR("Failed to allocate memory.\n");
902 return FALSE;
905 for (i = 0; i < format_count; ++i)
907 struct wined3d_format *format = &gl_info->formats[i];
908 format->id = formats[i].id;
909 format->red_mask = formats[i].redMask;
910 format->green_mask = formats[i].greenMask;
911 format->blue_mask = formats[i].blueMask;
912 format->alpha_mask = formats[i].alphaMask;
913 format->byte_count = formats[i].bpp;
914 format->depth_size = formats[i].depthSize;
915 format->stencil_size = formats[i].stencilSize;
918 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
920 int fmt_idx = getFmtIdx(format_base_flags[i].id);
922 if (fmt_idx == -1)
924 ERR("Format %s (%#x) not found.\n",
925 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
926 HeapFree(GetProcessHeap(), 0, gl_info->formats);
927 return FALSE;
930 gl_info->formats[fmt_idx].Flags |= format_base_flags[i].flags;
933 return TRUE;
936 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
938 unsigned int i;
940 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
942 struct wined3d_format *format;
943 int fmt_idx = getFmtIdx(format_compression_info[i].id);
945 if (fmt_idx == -1)
947 ERR("Format %s (%#x) not found.\n",
948 debug_d3dformat(format_compression_info[i].id), format_compression_info[i].id);
949 return FALSE;
952 format = &gl_info->formats[fmt_idx];
953 format->block_width = format_compression_info[i].block_width;
954 format->block_height = format_compression_info[i].block_height;
955 format->block_byte_count = format_compression_info[i].block_byte_count;
956 format->Flags |= WINED3DFMT_FLAG_COMPRESSED;
959 return TRUE;
962 /* Context activation is done by the caller. */
963 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
965 /* Check if the default internal format is supported as a frame buffer
966 * target, otherwise fall back to the render target internal.
968 * Try to stick to the standard format if possible, this limits precision differences. */
969 GLenum status;
970 GLuint tex;
972 ENTER_GL();
974 while(glGetError());
975 glDisable(GL_BLEND);
977 glGenTextures(1, &tex);
978 glBindTexture(GL_TEXTURE_2D, tex);
980 glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
981 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
982 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
984 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
986 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
987 checkGLcall("Framebuffer format check");
989 if (status == GL_FRAMEBUFFER_COMPLETE)
991 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
992 format->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
993 format->rtInternal = format->glInternal;
995 else
997 if (!format->rtInternal)
999 if (format->Flags & WINED3DFMT_FLAG_RENDERTARGET)
1001 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1002 " and no fallback specified.\n", debug_d3dformat(format->id));
1003 format->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1005 else
1007 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1009 format->rtInternal = format->glInternal;
1011 else
1013 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1014 debug_d3dformat(format->id));
1016 while(glGetError());
1018 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1020 glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1021 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1022 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1024 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1026 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1027 checkGLcall("Framebuffer format check");
1029 if (status == GL_FRAMEBUFFER_COMPLETE)
1031 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1032 debug_d3dformat(format->id));
1034 else
1036 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1037 debug_d3dformat(format->id));
1038 format->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1043 if (status == GL_FRAMEBUFFER_COMPLETE && format->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1045 GLuint rb;
1047 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1048 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1050 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1051 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1052 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1053 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1054 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1055 checkGLcall("RB attachment");
1058 glEnable(GL_BLEND);
1059 glClear(GL_COLOR_BUFFER_BIT);
1060 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1062 while(glGetError());
1063 TRACE("Format doesn't support post-pixelshader blending.\n");
1064 format->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1067 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1068 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1070 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1071 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1072 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1073 checkGLcall("RB cleanup");
1077 if (format->glInternal != format->glGammaInternal)
1079 glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1080 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1082 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1083 checkGLcall("Framebuffer format check");
1085 if (status == GL_FRAMEBUFFER_COMPLETE)
1087 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1088 format->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1090 else
1092 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1096 glDeleteTextures(1, &tex);
1098 LEAVE_GL();
1101 /* Context activation is done by the caller. */
1102 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1104 unsigned int i;
1105 GLuint fbo;
1107 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1109 ENTER_GL();
1111 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1112 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1114 LEAVE_GL();
1117 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1119 struct wined3d_format *format = &gl_info->formats[i];
1121 if (!format->glInternal) continue;
1123 if (format->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1125 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1126 debug_d3dformat(format->id));
1127 continue;
1130 if (format->Flags & WINED3DFMT_FLAG_COMPRESSED)
1132 TRACE("Skipping format %s because it's a compressed format.\n",
1133 debug_d3dformat(format->id));
1134 continue;
1137 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1139 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1140 check_fbo_compat(gl_info, format);
1142 else
1144 format->rtInternal = format->glInternal;
1148 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1150 ENTER_GL();
1152 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1154 LEAVE_GL();
1158 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1160 unsigned int i;
1162 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1164 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1165 struct wined3d_format *format;
1167 if (fmt_idx == -1)
1169 ERR("Format %s (%#x) not found.\n",
1170 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1171 return FALSE;
1174 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1176 format = &gl_info->formats[fmt_idx];
1178 /* ARB_texture_rg defines floating point formats, but only if
1179 * ARB_texture_float is also supported. */
1180 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1181 && (format->Flags & WINED3DFMT_FLAG_FLOAT))
1182 continue;
1184 format->glInternal = format_texture_info[i].gl_internal;
1185 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1186 format->rtInternal = format_texture_info[i].gl_rt_internal;
1187 format->glFormat = format_texture_info[i].gl_format;
1188 format->glType = format_texture_info[i].gl_type;
1189 format->color_fixup = COLOR_FIXUP_IDENTITY;
1190 format->Flags |= format_texture_info[i].flags;
1191 format->heightscale = 1.0f;
1193 /* Texture conversion stuff */
1194 format->convert = format_texture_info[i].convert;
1195 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1198 return TRUE;
1201 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1203 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1204 c1 >>= 8; c2 >>= 8;
1205 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1206 c1 >>= 8; c2 >>= 8;
1207 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1208 c1 >>= 8; c2 >>= 8;
1209 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1210 return TRUE;
1213 /* A context is provided by the caller */
1214 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1216 static const DWORD data[] = {0x00000000, 0xffffffff};
1217 GLuint tex, fbo, buffer;
1218 DWORD readback[16 * 1];
1219 BOOL ret = FALSE;
1221 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1222 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1223 * falling back to software. If this changes in the future this code will get fooled and
1224 * apps might hit the software path due to incorrectly advertised caps.
1226 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1227 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1228 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1231 ENTER_GL();
1232 while(glGetError());
1234 glGenTextures(1, &buffer);
1235 glBindTexture(GL_TEXTURE_2D, buffer);
1236 memset(readback, 0x7e, sizeof(readback));
1237 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1238 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1239 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1240 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1241 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1242 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1244 glGenTextures(1, &tex);
1245 glBindTexture(GL_TEXTURE_2D, tex);
1246 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1247 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1248 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1249 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1250 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1251 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1252 glEnable(GL_TEXTURE_2D);
1254 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1255 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1256 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1257 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1259 glViewport(0, 0, 16, 1);
1260 glDisable(GL_LIGHTING);
1261 glMatrixMode(GL_MODELVIEW);
1262 glLoadIdentity();
1263 glMatrixMode(GL_PROJECTION);
1264 glLoadIdentity();
1266 glClearColor(0, 1, 0, 0);
1267 glClear(GL_COLOR_BUFFER_BIT);
1269 glBegin(GL_TRIANGLE_STRIP);
1270 glTexCoord2f(0.0, 0.0);
1271 glVertex2f(-1.0f, -1.0f);
1272 glTexCoord2f(1.0, 0.0);
1273 glVertex2f(1.0f, -1.0f);
1274 glTexCoord2f(0.0, 1.0);
1275 glVertex2f(-1.0f, 1.0f);
1276 glTexCoord2f(1.0, 1.0);
1277 glVertex2f(1.0f, 1.0f);
1278 glEnd();
1280 glBindTexture(GL_TEXTURE_2D, buffer);
1281 memset(readback, 0x7f, sizeof(readback));
1282 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1283 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1284 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1286 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1287 readback[6], readback[9]);
1288 ret = FALSE;
1290 else
1292 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1293 readback[6], readback[9]);
1294 ret = TRUE;
1297 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1298 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1299 glDeleteTextures(1, &tex);
1300 glDeleteTextures(1, &buffer);
1302 if(glGetError())
1304 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1305 ret = FALSE;
1307 LEAVE_GL();
1308 return ret;
1311 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1313 struct wined3d_format *format;
1314 unsigned int fmt_idx, i;
1315 static const enum wined3d_format_id fmts16[] =
1317 WINED3DFMT_R16_FLOAT,
1318 WINED3DFMT_R16G16_FLOAT,
1319 WINED3DFMT_R16G16B16A16_FLOAT,
1321 BOOL filtered;
1323 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1325 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1326 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1328 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1329 filtered = TRUE;
1331 else if (gl_info->limits.glsl_varyings > 44)
1333 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1334 filtered = TRUE;
1336 else
1338 TRACE("Assuming no float16 blending\n");
1339 filtered = FALSE;
1342 if(filtered)
1344 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1346 fmt_idx = getFmtIdx(fmts16[i]);
1347 gl_info->formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
1350 return;
1353 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1355 fmt_idx = getFmtIdx(fmts16[i]);
1356 format = &gl_info->formats[fmt_idx];
1357 if (!format->glInternal) continue; /* Not supported by GL */
1359 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1360 if(filtered)
1362 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1363 format->Flags |= WINED3DFMT_FLAG_FILTERING;
1365 else
1367 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1372 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1374 int idx;
1376 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1377 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1378 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1380 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1381 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1382 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1384 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1385 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1386 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1388 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1389 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1390 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1392 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1393 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1394 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1396 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1397 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1398 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1399 * the only driver that implements it(fglrx) has a buggy implementation.
1401 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1402 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1403 * conversion for this format.
1405 if (!gl_info->supported[NV_TEXTURE_SHADER])
1407 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1408 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1409 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1410 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1411 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1412 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1414 else
1416 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1417 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1418 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1420 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1421 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1422 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1425 if (!gl_info->supported[NV_TEXTURE_SHADER])
1427 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1428 * with each other
1430 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1431 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1432 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1433 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1434 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1435 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1436 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1437 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1438 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1440 else
1442 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1443 * are converted at surface loading time, but they do not need any modification in
1444 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1445 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1449 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1451 idx = getFmtIdx(WINED3DFMT_ATI2N);
1452 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1453 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1455 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1457 idx = getFmtIdx(WINED3DFMT_ATI2N);
1458 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1459 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1462 if (!gl_info->supported[APPLE_YCBCR_422])
1464 idx = getFmtIdx(WINED3DFMT_YUY2);
1465 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1467 idx = getFmtIdx(WINED3DFMT_UYVY);
1468 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1471 idx = getFmtIdx(WINED3DFMT_YV12);
1472 gl_info->formats[idx].heightscale = 1.5f;
1473 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1475 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1477 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1478 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1481 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1483 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1484 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1487 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1489 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1490 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1491 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1492 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1494 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1495 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1499 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1501 unsigned int i;
1503 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1505 struct wined3d_format *format;
1506 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1508 if (fmt_idx == -1)
1510 ERR("Format %s (%#x) not found.\n",
1511 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1512 return FALSE;
1515 format = &gl_info->formats[fmt_idx];
1516 format->emit_idx = format_vertex_info[i].emit_idx;
1517 format->component_count = format_vertex_info[i].component_count;
1518 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1519 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1520 format->gl_normalized = format_vertex_info[i].gl_normalized;
1521 format->component_size = format_vertex_info[i].component_size;
1524 return TRUE;
1527 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1529 if (!init_format_base_info(gl_info)) return FALSE;
1531 if (!init_format_compression_info(gl_info))
1533 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1534 gl_info->formats = NULL;
1535 return FALSE;
1538 return TRUE;
1541 /* Context activation is done by the caller. */
1542 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1544 if (!init_format_base_info(gl_info)) return FALSE;
1546 if (!init_format_compression_info(gl_info)) goto fail;
1547 if (!init_format_texture_info(gl_info)) goto fail;
1548 if (!init_format_vertex_info(gl_info)) goto fail;
1550 apply_format_fixups(gl_info);
1551 init_format_fbo_compat_info(gl_info);
1552 init_format_filter_info(gl_info, vendor);
1554 return TRUE;
1556 fail:
1557 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1558 gl_info->formats = NULL;
1559 return FALSE;
1562 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1563 enum wined3d_format_id format_id)
1565 int idx = getFmtIdx(format_id);
1567 if (idx == -1)
1569 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1570 debug_d3dformat(format_id), format_id);
1571 /* Get the caller a valid pointer */
1572 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1575 return &gl_info->formats[idx];
1578 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1580 UINT size;
1582 if (format->id == WINED3DFMT_UNKNOWN)
1584 size = 0;
1586 else if (format->Flags & WINED3DFMT_FLAG_COMPRESSED)
1588 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1589 UINT row_count = (height + format->block_height - 1) / format->block_height;
1590 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1592 else
1594 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1597 if (format->heightscale != 0.0f) size *= format->heightscale;
1599 return size;
1602 /*****************************************************************************
1603 * Trace formatting of useful values
1605 const char *debug_d3dformat(enum wined3d_format_id format_id)
1607 switch (format_id)
1609 #define FMT_TO_STR(format_id) case format_id: return #format_id
1610 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1611 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1612 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1613 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1614 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1615 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1616 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1617 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1618 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1619 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1620 FMT_TO_STR(WINED3DFMT_P8_UINT);
1621 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1622 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1623 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1624 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1625 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1626 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1627 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1628 FMT_TO_STR(WINED3DFMT_UYVY);
1629 FMT_TO_STR(WINED3DFMT_YUY2);
1630 FMT_TO_STR(WINED3DFMT_YV12);
1631 FMT_TO_STR(WINED3DFMT_DXT1);
1632 FMT_TO_STR(WINED3DFMT_DXT2);
1633 FMT_TO_STR(WINED3DFMT_DXT3);
1634 FMT_TO_STR(WINED3DFMT_DXT4);
1635 FMT_TO_STR(WINED3DFMT_DXT5);
1636 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1637 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1638 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1639 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1640 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1641 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1642 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1643 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1644 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1645 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1646 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1647 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1648 FMT_TO_STR(WINED3DFMT_ATI2N);
1649 FMT_TO_STR(WINED3DFMT_NVDB);
1650 FMT_TO_STR(WINED3DFMT_NVHU);
1651 FMT_TO_STR(WINED3DFMT_NVHS);
1652 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1653 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1654 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1655 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1656 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1657 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1658 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1659 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1660 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1661 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1662 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1663 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1664 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1665 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1666 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1667 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1668 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1669 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1670 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1671 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1672 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1673 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1674 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1675 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1676 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1677 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1678 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1679 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1680 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1681 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1682 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1683 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1684 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1685 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1686 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1687 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1688 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1689 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1690 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1691 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1692 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1693 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1694 FMT_TO_STR(WINED3DFMT_R32_UINT);
1695 FMT_TO_STR(WINED3DFMT_R32_SINT);
1696 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1697 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1698 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1699 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1700 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1701 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1702 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1703 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1704 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1705 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1706 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1707 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1708 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1709 FMT_TO_STR(WINED3DFMT_R16_UINT);
1710 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1711 FMT_TO_STR(WINED3DFMT_R16_SINT);
1712 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1713 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1714 FMT_TO_STR(WINED3DFMT_R8_UINT);
1715 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1716 FMT_TO_STR(WINED3DFMT_R8_SINT);
1717 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1718 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1719 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1720 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1721 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1722 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1723 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1724 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1725 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1726 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1727 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1728 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1729 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1730 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1731 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1732 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1733 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1734 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1735 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1736 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1737 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1738 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1739 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1740 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1741 FMT_TO_STR(WINED3DFMT_INTZ);
1742 #undef FMT_TO_STR
1743 default:
1745 char fourcc[5];
1746 fourcc[0] = (char)(format_id);
1747 fourcc[1] = (char)(format_id >> 8);
1748 fourcc[2] = (char)(format_id >> 16);
1749 fourcc[3] = (char)(format_id >> 24);
1750 fourcc[4] = 0;
1751 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1752 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1753 else
1754 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1756 return "unrecognized";
1760 const char *debug_d3ddevicetype(WINED3DDEVTYPE devtype)
1762 switch (devtype)
1764 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1765 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1766 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1767 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1768 #undef DEVTYPE_TO_STR
1769 default:
1770 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1771 return "unrecognized";
1775 const char *debug_d3dusage(DWORD usage)
1777 char buf[333];
1779 buf[0] = '\0';
1780 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1781 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1782 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1783 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1784 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1785 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1786 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1787 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1788 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1789 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1790 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1791 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1792 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1793 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1794 #undef WINED3DUSAGE_TO_STR
1795 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1797 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1800 const char *debug_d3dusagequery(DWORD usagequery)
1802 char buf[238];
1804 buf[0] = '\0';
1805 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1806 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1807 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1808 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1809 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1810 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1811 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1812 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1813 #undef WINED3DUSAGEQUERY_TO_STR
1814 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1816 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1819 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1820 switch (method) {
1821 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1822 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1823 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1824 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1825 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1826 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1827 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1828 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1829 #undef WINED3DDECLMETHOD_TO_STR
1830 default:
1831 FIXME("Unrecognized %u declaration method!\n", method);
1832 return "unrecognized";
1836 const char* debug_d3ddeclusage(BYTE usage) {
1837 switch (usage) {
1838 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1839 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1840 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1841 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1842 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1843 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1844 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1845 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1846 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1847 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1848 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1849 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1850 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1851 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1852 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1853 #undef WINED3DDECLUSAGE_TO_STR
1854 default:
1855 FIXME("Unrecognized %u declaration usage!\n", usage);
1856 return "unrecognized";
1860 const char *debug_d3dresourcetype(WINED3DRESOURCETYPE res)
1862 switch (res)
1864 #define RES_TO_STR(res) case res: return #res
1865 RES_TO_STR(WINED3DRTYPE_SURFACE);
1866 RES_TO_STR(WINED3DRTYPE_VOLUME);
1867 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1868 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1869 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1870 RES_TO_STR(WINED3DRTYPE_BUFFER);
1871 #undef RES_TO_STR
1872 default:
1873 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1874 return "unrecognized";
1878 const char *debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType)
1880 switch (PrimitiveType)
1882 #define PRIM_TO_STR(prim) case prim: return #prim
1883 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1884 PRIM_TO_STR(WINED3DPT_POINTLIST);
1885 PRIM_TO_STR(WINED3DPT_LINELIST);
1886 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1887 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1888 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1889 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1890 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1891 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1892 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1893 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1894 #undef PRIM_TO_STR
1895 default:
1896 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1897 return "unrecognized";
1901 const char *debug_d3drenderstate(WINED3DRENDERSTATETYPE state)
1903 switch (state)
1905 #define D3DSTATE_TO_STR(u) case u: return #u
1906 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS);
1907 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE);
1908 D3DSTATE_TO_STR(WINED3DRS_WRAPU);
1909 D3DSTATE_TO_STR(WINED3DRS_WRAPV);
1910 D3DSTATE_TO_STR(WINED3DRS_ZENABLE);
1911 D3DSTATE_TO_STR(WINED3DRS_FILLMODE);
1912 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE);
1913 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN);
1914 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE);
1915 D3DSTATE_TO_STR(WINED3DRS_ROP2);
1916 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK);
1917 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE);
1918 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE);
1919 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL);
1920 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND);
1921 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND);
1922 D3DSTATE_TO_STR(WINED3DRS_CULLMODE);
1923 D3DSTATE_TO_STR(WINED3DRS_ZFUNC);
1924 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF);
1925 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC);
1926 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE);
1927 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE);
1928 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE);
1929 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE);
1930 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE);
1931 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL);
1932 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX);
1933 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA);
1934 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR);
1935 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE);
1936 D3DSTATE_TO_STR(WINED3DRS_FOGSTART);
1937 D3DSTATE_TO_STR(WINED3DRS_FOGEND);
1938 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY);
1939 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE);
1940 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS);
1941 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE);
1942 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS);
1943 D3DSTATE_TO_STR(WINED3DRS_ZBIAS);
1944 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE);
1945 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY);
1946 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH);
1947 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1948 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE);
1949 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL);
1950 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL);
1951 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS);
1952 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC);
1953 D3DSTATE_TO_STR(WINED3DRS_STENCILREF);
1954 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK);
1955 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK);
1956 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR);
1957 D3DSTATE_TO_STR(WINED3DRS_WRAP0);
1958 D3DSTATE_TO_STR(WINED3DRS_WRAP1);
1959 D3DSTATE_TO_STR(WINED3DRS_WRAP2);
1960 D3DSTATE_TO_STR(WINED3DRS_WRAP3);
1961 D3DSTATE_TO_STR(WINED3DRS_WRAP4);
1962 D3DSTATE_TO_STR(WINED3DRS_WRAP5);
1963 D3DSTATE_TO_STR(WINED3DRS_WRAP6);
1964 D3DSTATE_TO_STR(WINED3DRS_WRAP7);
1965 D3DSTATE_TO_STR(WINED3DRS_CLIPPING);
1966 D3DSTATE_TO_STR(WINED3DRS_LIGHTING);
1967 D3DSTATE_TO_STR(WINED3DRS_EXTENTS);
1968 D3DSTATE_TO_STR(WINED3DRS_AMBIENT);
1969 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE);
1970 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX);
1971 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER);
1972 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS);
1973 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE);
1974 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE);
1975 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE);
1976 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE);
1977 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE);
1978 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND);
1979 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE);
1980 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING);
1981 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE);
1982 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN);
1983 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE);
1984 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE);
1985 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A);
1986 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B);
1987 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C);
1988 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS);
1989 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK);
1990 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE);
1991 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS);
1992 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN);
1993 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX);
1994 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE);
1995 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE);
1996 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR);
1997 D3DSTATE_TO_STR(WINED3DRS_BLENDOP);
1998 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE);
1999 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE);
2000 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE);
2001 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS);
2002 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE);
2003 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL);
2004 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL);
2005 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X);
2006 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y);
2007 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z);
2008 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W);
2009 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
2010 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE);
2011 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL);
2012 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL);
2013 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS);
2014 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC);
2015 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1);
2016 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2);
2017 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3);
2018 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR);
2019 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE);
2020 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS);
2021 D3DSTATE_TO_STR(WINED3DRS_WRAP8);
2022 D3DSTATE_TO_STR(WINED3DRS_WRAP9);
2023 D3DSTATE_TO_STR(WINED3DRS_WRAP10);
2024 D3DSTATE_TO_STR(WINED3DRS_WRAP11);
2025 D3DSTATE_TO_STR(WINED3DRS_WRAP12);
2026 D3DSTATE_TO_STR(WINED3DRS_WRAP13);
2027 D3DSTATE_TO_STR(WINED3DRS_WRAP14);
2028 D3DSTATE_TO_STR(WINED3DRS_WRAP15);
2029 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE);
2030 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA);
2031 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA);
2032 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA);
2033 #undef D3DSTATE_TO_STR
2034 default:
2035 FIXME("Unrecognized %u render state!\n", state);
2036 return "unrecognized";
2040 const char *debug_d3dsamplerstate(DWORD state)
2042 switch (state)
2044 #define D3DSTATE_TO_STR(u) case u: return #u
2045 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR);
2046 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU);
2047 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV);
2048 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW);
2049 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER);
2050 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER);
2051 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER);
2052 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
2053 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL);
2054 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
2055 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE);
2056 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX);
2057 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET);
2058 #undef D3DSTATE_TO_STR
2059 default:
2060 FIXME("Unrecognized %u sampler state!\n", state);
2061 return "unrecognized";
2065 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2066 switch (filter_type) {
2067 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2068 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2069 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2070 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2071 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2072 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2073 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2074 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2075 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2076 #undef D3DTEXTUREFILTERTYPE_TO_STR
2077 default:
2078 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2079 return "unrecognized";
2083 const char *debug_d3dtexturestate(DWORD state)
2085 switch (state)
2087 #define D3DSTATE_TO_STR(u) case u: return #u
2088 D3DSTATE_TO_STR(WINED3DTSS_COLOROP);
2089 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1);
2090 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2);
2091 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP);
2092 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1);
2093 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2);
2094 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00);
2095 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01);
2096 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10);
2097 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11);
2098 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX);
2099 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE);
2100 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET);
2101 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS);
2102 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0);
2103 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0);
2104 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG);
2105 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT);
2106 #undef D3DSTATE_TO_STR
2107 default:
2108 FIXME("Unrecognized %u texture state!\n", state);
2109 return "unrecognized";
2113 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2114 switch (d3dtop) {
2115 #define D3DTOP_TO_STR(u) case u: return #u
2116 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2117 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2118 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2119 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2120 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2121 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2122 D3DTOP_TO_STR(WINED3DTOP_ADD);
2123 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2124 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2125 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2126 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2127 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2128 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2129 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2130 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2131 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2132 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2133 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2134 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2135 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2136 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2137 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2138 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2139 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2140 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2141 D3DTOP_TO_STR(WINED3DTOP_LERP);
2142 #undef D3DTOP_TO_STR
2143 default:
2144 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2145 return "unrecognized";
2149 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2150 switch (tstype) {
2151 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2152 TSTYPE_TO_STR(WINED3DTS_VIEW);
2153 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2154 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2155 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2156 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2157 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2158 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2159 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2160 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2161 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2162 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2163 #undef TSTYPE_TO_STR
2164 default:
2165 if (tstype > 256 && tstype < 512) {
2166 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2167 return ("WINED3DTS_WORLDMATRIX > 0");
2169 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2170 return "unrecognized";
2174 const char *debug_d3dstate(DWORD state)
2176 if (STATE_IS_RENDER(state))
2177 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2178 if (STATE_IS_TEXTURESTAGE(state))
2180 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2181 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2182 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2183 texture_stage, debug_d3dtexturestate(texture_state));
2185 if (STATE_IS_SAMPLER(state))
2186 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2187 if (STATE_IS_PIXELSHADER(state))
2188 return "STATE_PIXELSHADER";
2189 if (STATE_IS_TRANSFORM(state))
2190 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2191 if (STATE_IS_STREAMSRC(state))
2192 return "STATE_STREAMSRC";
2193 if (STATE_IS_INDEXBUFFER(state))
2194 return "STATE_INDEXBUFFER";
2195 if (STATE_IS_VDECL(state))
2196 return "STATE_VDECL";
2197 if (STATE_IS_VSHADER(state))
2198 return "STATE_VSHADER";
2199 if (STATE_IS_VIEWPORT(state))
2200 return "STATE_VIEWPORT";
2201 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2202 return "STATE_VERTEXSHADERCONSTANT";
2203 if (STATE_IS_PIXELSHADERCONSTANT(state))
2204 return "STATE_PIXELSHADERCONSTANT";
2205 if (STATE_IS_ACTIVELIGHT(state))
2206 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2207 if (STATE_IS_SCISSORRECT(state))
2208 return "STATE_SCISSORRECT";
2209 if (STATE_IS_CLIPPLANE(state))
2210 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2211 if (STATE_IS_MATERIAL(state))
2212 return "STATE_MATERIAL";
2213 if (STATE_IS_FRONTFACE(state))
2214 return "STATE_FRONTFACE";
2216 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2219 const char *debug_d3dpool(WINED3DPOOL pool)
2221 switch (pool)
2223 #define POOL_TO_STR(p) case p: return #p
2224 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2225 POOL_TO_STR(WINED3DPOOL_MANAGED);
2226 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2227 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2228 #undef POOL_TO_STR
2229 default:
2230 FIXME("Unrecognized %u WINED3DPOOL!\n", pool);
2231 return "unrecognized";
2235 const char *debug_fbostatus(GLenum status) {
2236 switch(status) {
2237 #define FBOSTATUS_TO_STR(u) case u: return #u
2238 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2239 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2240 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2241 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2242 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2243 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2244 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2245 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2246 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2247 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2248 #undef FBOSTATUS_TO_STR
2249 default:
2250 FIXME("Unrecognied FBO status 0x%08x\n", status);
2251 return "unrecognized";
2255 const char *debug_glerror(GLenum error) {
2256 switch(error) {
2257 #define GLERROR_TO_STR(u) case u: return #u
2258 GLERROR_TO_STR(GL_NO_ERROR);
2259 GLERROR_TO_STR(GL_INVALID_ENUM);
2260 GLERROR_TO_STR(GL_INVALID_VALUE);
2261 GLERROR_TO_STR(GL_INVALID_OPERATION);
2262 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2263 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2264 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2265 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2266 #undef GLERROR_TO_STR
2267 default:
2268 FIXME("Unrecognied GL error 0x%08x\n", error);
2269 return "unrecognized";
2273 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2274 switch(basis) {
2275 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2276 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2277 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2278 default: return "unrecognized";
2282 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2283 switch(degree) {
2284 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2285 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2286 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2287 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2288 default: return "unrecognized";
2292 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2294 switch(source)
2296 #define WINED3D_TO_STR(x) case x: return #x
2297 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2298 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2299 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2300 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2301 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2302 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2303 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2304 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2305 #undef WINED3D_TO_STR
2306 default:
2307 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2308 return "unrecognized";
2312 static const char *debug_complex_fixup(enum complex_fixup fixup)
2314 switch(fixup)
2316 #define WINED3D_TO_STR(x) case x: return #x
2317 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2318 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2319 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2320 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2321 #undef WINED3D_TO_STR
2322 default:
2323 FIXME("Unrecognized complex fixup %#x\n", fixup);
2324 return "unrecognized";
2328 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2330 if (is_complex_fixup(fixup))
2332 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2333 return;
2336 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2337 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2338 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2339 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2342 const char *debug_surflocation(DWORD flag) {
2343 char buf[128];
2345 buf[0] = 0;
2346 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2347 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2348 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2349 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2350 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2353 /*****************************************************************************
2354 * Useful functions mapping GL <-> D3D values
2356 GLenum StencilOp(DWORD op) {
2357 switch(op) {
2358 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2359 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2360 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2361 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2362 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2363 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2364 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2365 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2366 default:
2367 FIXME("Unrecognized stencil op %d\n", op);
2368 return GL_KEEP;
2372 GLenum CompareFunc(DWORD func) {
2373 switch ((WINED3DCMPFUNC)func) {
2374 case WINED3DCMP_NEVER : return GL_NEVER;
2375 case WINED3DCMP_LESS : return GL_LESS;
2376 case WINED3DCMP_EQUAL : return GL_EQUAL;
2377 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2378 case WINED3DCMP_GREATER : return GL_GREATER;
2379 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2380 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2381 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2382 default:
2383 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2384 return 0;
2388 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2389 WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
2391 if (op == WINED3DTOP_DISABLE) return FALSE;
2392 if (state->textures[stage]) return FALSE;
2394 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2395 && op != WINED3DTOP_SELECTARG2) return TRUE;
2396 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2397 && op != WINED3DTOP_SELECTARG1) return TRUE;
2398 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2399 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2401 return FALSE;
2404 /* Setup this textures matrix according to the texture flags*/
2405 /* GL locking is done by the caller (state handler) */
2406 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2407 enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2409 float mat[16];
2411 glMatrixMode(GL_TEXTURE);
2412 checkGLcall("glMatrixMode(GL_TEXTURE)");
2414 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2415 glLoadIdentity();
2416 checkGLcall("glLoadIdentity()");
2417 return;
2420 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2421 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2422 return;
2425 memcpy(mat, smat, 16 * sizeof(float));
2427 if (flags & WINED3DTTFF_PROJECTED) {
2428 if(!ffp_proj_control) {
2429 switch (flags & ~WINED3DTTFF_PROJECTED) {
2430 case WINED3DTTFF_COUNT2:
2431 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2432 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2433 break;
2434 case WINED3DTTFF_COUNT3:
2435 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2436 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2437 break;
2440 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2441 if(!calculatedCoords) {
2442 switch(vtx_fmt)
2444 case WINED3DFMT_R32_FLOAT:
2445 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2446 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2447 * the input value to the transformation will be 0, so the matrix value is irrelevant
2449 mat[12] = mat[4];
2450 mat[13] = mat[5];
2451 mat[14] = mat[6];
2452 mat[15] = mat[7];
2453 break;
2454 case WINED3DFMT_R32G32_FLOAT:
2455 /* See above, just 3rd and 4th coord
2457 mat[12] = mat[8];
2458 mat[13] = mat[9];
2459 mat[14] = mat[10];
2460 mat[15] = mat[11];
2461 break;
2462 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2463 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2465 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2466 * into a bad place. The division elimination below will apply to make sure the
2467 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2469 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2470 break;
2471 default:
2472 FIXME("Unexpected fixed function texture coord input\n");
2475 if(!ffp_proj_control) {
2476 switch (flags & ~WINED3DTTFF_PROJECTED) {
2477 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2478 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2479 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2480 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2481 * the 4th coord evaluates to 1.0 to eliminate that.
2483 * If the fixed function pipeline is used, the 4th value remains unused,
2484 * so there is no danger in doing this. With vertex shaders we have a
2485 * problem. Should an app hit that problem, the code here would have to
2486 * check for pixel shaders, and the shader has to undo the default gl divide.
2488 * A more serious problem occurs if the app passes 4 coordinates in, and the
2489 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2490 * or a replacement shader
2492 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2497 glLoadMatrixf(mat);
2498 checkGLcall("glLoadMatrixf(mat)");
2501 /* This small helper function is used to convert a bitmask into the number of masked bits */
2502 unsigned int count_bits(unsigned int mask)
2504 unsigned int count;
2505 for (count = 0; mask; ++count)
2507 mask &= mask - 1;
2509 return count;
2512 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2513 * The later function requires individual color components. */
2514 BOOL getColorBits(const struct wined3d_format *format,
2515 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2517 TRACE("format %s.\n", debug_d3dformat(format->id));
2519 switch (format->id)
2521 case WINED3DFMT_B10G10R10A2_UNORM:
2522 case WINED3DFMT_R10G10B10A2_UNORM:
2523 case WINED3DFMT_B8G8R8X8_UNORM:
2524 case WINED3DFMT_B8G8R8_UNORM:
2525 case WINED3DFMT_B8G8R8A8_UNORM:
2526 case WINED3DFMT_R8G8B8A8_UNORM:
2527 case WINED3DFMT_B5G5R5X1_UNORM:
2528 case WINED3DFMT_B5G5R5A1_UNORM:
2529 case WINED3DFMT_B5G6R5_UNORM:
2530 case WINED3DFMT_B4G4R4X4_UNORM:
2531 case WINED3DFMT_B4G4R4A4_UNORM:
2532 case WINED3DFMT_B2G3R3_UNORM:
2533 case WINED3DFMT_P8_UINT_A8_UNORM:
2534 case WINED3DFMT_P8_UINT:
2535 break;
2536 default:
2537 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2538 return FALSE;
2541 *redSize = count_bits(format->red_mask);
2542 *greenSize = count_bits(format->green_mask);
2543 *blueSize = count_bits(format->blue_mask);
2544 *alphaSize = count_bits(format->alpha_mask);
2545 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2547 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2548 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2549 return TRUE;
2552 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2553 BOOL getDepthStencilBits(const struct wined3d_format *format, short *depthSize, short *stencilSize)
2555 TRACE("format %s.\n", debug_d3dformat(format->id));
2557 switch (format->id)
2559 case WINED3DFMT_D16_LOCKABLE:
2560 case WINED3DFMT_D16_UNORM:
2561 case WINED3DFMT_S1_UINT_D15_UNORM:
2562 case WINED3DFMT_X8D24_UNORM:
2563 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2564 case WINED3DFMT_D24_UNORM_S8_UINT:
2565 case WINED3DFMT_S8_UINT_D24_FLOAT:
2566 case WINED3DFMT_D32_UNORM:
2567 case WINED3DFMT_D32_FLOAT:
2568 case WINED3DFMT_INTZ:
2569 break;
2570 default:
2571 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2572 return FALSE;
2575 *depthSize = format->depth_size;
2576 *stencilSize = format->stencil_size;
2578 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2579 *depthSize, *stencilSize, debug_d3dformat(format->id));
2580 return TRUE;
2583 /* Note: It's the caller's responsibility to ensure values can be expressed
2584 * in the requested format. UNORM formats for example can only express values
2585 * in the range 0.0f -> 1.0f. */
2586 DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, const WINED3DCOLORVALUE *color)
2588 static const struct
2590 enum wined3d_format_id format_id;
2591 float r_mul;
2592 float g_mul;
2593 float b_mul;
2594 float a_mul;
2595 BYTE r_shift;
2596 BYTE g_shift;
2597 BYTE b_shift;
2598 BYTE a_shift;
2600 conv[] =
2602 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2603 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2604 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2605 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2606 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2607 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2608 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2609 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2610 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2611 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2612 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2613 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2614 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2615 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2617 unsigned int i;
2619 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2620 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2622 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2624 DWORD ret;
2626 if (format->id != conv[i].format_id) continue;
2628 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2629 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2630 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2631 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2633 TRACE("Returning 0x%08x.\n", ret);
2635 return ret;
2638 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2640 return 0;
2643 /* DirectDraw stuff */
2644 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2646 switch (depth)
2648 case 8: return WINED3DFMT_P8_UINT;
2649 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2650 case 16: return WINED3DFMT_B5G6R5_UNORM;
2651 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2652 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2653 default: return WINED3DFMT_UNKNOWN;
2657 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2658 WINED3DMATRIX temp;
2660 /* Now do the multiplication 'by hand'.
2661 I know that all this could be optimised, but this will be done later :-) */
2662 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);
2663 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);
2664 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);
2665 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);
2667 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);
2668 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);
2669 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);
2670 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);
2672 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);
2673 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);
2674 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);
2675 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);
2677 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);
2678 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);
2679 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);
2680 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);
2682 /* And copy the new matrix in the good storage.. */
2683 memcpy(dest, &temp, 16 * sizeof(float));
2686 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2687 DWORD size = 0;
2688 int i;
2689 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2691 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2692 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2693 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2694 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2695 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2696 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2697 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2698 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2699 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2700 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2701 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2702 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2703 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2704 default: ERR("Unexpected position mask\n");
2706 for (i = 0; i < numTextures; i++) {
2707 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2710 return size;
2713 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2714 #define ARG1 0x01
2715 #define ARG2 0x02
2716 #define ARG0 0x04
2717 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2718 /* undefined */ 0,
2719 /* D3DTOP_DISABLE */ 0,
2720 /* D3DTOP_SELECTARG1 */ ARG1,
2721 /* D3DTOP_SELECTARG2 */ ARG2,
2722 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2723 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2724 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2725 /* D3DTOP_ADD */ ARG1 | ARG2,
2726 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2727 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2728 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2729 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2730 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2731 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2732 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2733 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2734 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2735 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2736 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2737 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2738 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2739 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2740 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2741 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2742 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2743 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2744 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2746 unsigned int i;
2747 DWORD ttff;
2748 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2749 IWineD3DDeviceImpl *device = stateblock->device;
2750 IWineD3DSurfaceImpl *rt = device->render_targets[0];
2751 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2753 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2755 IWineD3DBaseTextureImpl *texture;
2756 settings->op[i].padding = 0;
2757 if (stateblock->state.texture_states[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE)
2759 settings->op[i].cop = WINED3DTOP_DISABLE;
2760 settings->op[i].aop = WINED3DTOP_DISABLE;
2761 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2762 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2763 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2764 settings->op[i].dst = resultreg;
2765 settings->op[i].tex_type = tex_1d;
2766 settings->op[i].projected = proj_none;
2767 i++;
2768 break;
2771 if ((texture = stateblock->state.textures[i]))
2773 settings->op[i].color_fixup = texture->resource.format->color_fixup;
2774 if (ignore_textype)
2776 settings->op[i].tex_type = tex_1d;
2778 else
2780 switch (texture->baseTexture.target)
2782 case GL_TEXTURE_1D:
2783 settings->op[i].tex_type = tex_1d;
2784 break;
2785 case GL_TEXTURE_2D:
2786 settings->op[i].tex_type = tex_2d;
2787 break;
2788 case GL_TEXTURE_3D:
2789 settings->op[i].tex_type = tex_3d;
2790 break;
2791 case GL_TEXTURE_CUBE_MAP_ARB:
2792 settings->op[i].tex_type = tex_cube;
2793 break;
2794 case GL_TEXTURE_RECTANGLE_ARB:
2795 settings->op[i].tex_type = tex_rect;
2796 break;
2799 } else {
2800 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2801 settings->op[i].tex_type = tex_1d;
2804 cop = stateblock->state.texture_states[i][WINED3DTSS_COLOROP];
2805 aop = stateblock->state.texture_states[i][WINED3DTSS_ALPHAOP];
2807 carg1 = (args[cop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2808 carg2 = (args[cop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2809 carg0 = (args[cop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2811 if (is_invalid_op(&stateblock->state, i, cop, carg1, carg2, carg0))
2813 carg0 = ARG_UNUSED;
2814 carg2 = ARG_UNUSED;
2815 carg1 = WINED3DTA_CURRENT;
2816 cop = WINED3DTOP_SELECTARG1;
2819 if(cop == WINED3DTOP_DOTPRODUCT3) {
2820 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2821 * the color result to the alpha component of the destination
2823 aop = cop;
2824 aarg1 = carg1;
2825 aarg2 = carg2;
2826 aarg0 = carg0;
2828 else
2830 aarg1 = (args[aop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2831 aarg2 = (args[aop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2832 aarg0 = (args[aop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2835 if (!i && stateblock->state.textures[0] && stateblock->state.render_states[WINED3DRS_COLORKEYENABLE])
2837 IWineD3DBaseTextureImpl *texture = stateblock->state.textures[0];
2838 GLenum texture_dimensions = texture->baseTexture.target;
2840 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2842 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
2844 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
2846 if (aop == WINED3DTOP_DISABLE)
2848 aarg1 = WINED3DTA_TEXTURE;
2849 aop = WINED3DTOP_SELECTARG1;
2851 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2853 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2855 aarg2 = WINED3DTA_TEXTURE;
2856 aop = WINED3DTOP_MODULATE;
2858 else aarg1 = WINED3DTA_TEXTURE;
2860 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2862 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2864 aarg1 = WINED3DTA_TEXTURE;
2865 aop = WINED3DTOP_MODULATE;
2867 else aarg2 = WINED3DTA_TEXTURE;
2873 if (is_invalid_op(&stateblock->state, i, aop, aarg1, aarg2, aarg0))
2875 aarg0 = ARG_UNUSED;
2876 aarg2 = ARG_UNUSED;
2877 aarg1 = WINED3DTA_CURRENT;
2878 aop = WINED3DTOP_SELECTARG1;
2881 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
2882 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
2884 ttff = stateblock->state.texture_states[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2885 if (ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3))
2887 settings->op[i].projected = proj_count3;
2888 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2889 settings->op[i].projected = proj_count4;
2890 } else {
2891 settings->op[i].projected = proj_none;
2893 } else {
2894 settings->op[i].projected = proj_none;
2897 settings->op[i].cop = cop;
2898 settings->op[i].aop = aop;
2899 settings->op[i].carg0 = carg0;
2900 settings->op[i].carg1 = carg1;
2901 settings->op[i].carg2 = carg2;
2902 settings->op[i].aarg0 = aarg0;
2903 settings->op[i].aarg1 = aarg1;
2904 settings->op[i].aarg2 = aarg2;
2906 if (stateblock->state.texture_states[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP)
2908 settings->op[i].dst = tempreg;
2909 } else {
2910 settings->op[i].dst = resultreg;
2914 /* Clear unsupported stages */
2915 for(; i < MAX_TEXTURES; i++) {
2916 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2919 if (!stateblock->state.render_states[WINED3DRS_FOGENABLE])
2921 settings->fog = FOG_OFF;
2923 else if (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
2925 if (use_vs(&stateblock->state) || stateblock->state.vertex_declaration->position_transformed)
2927 settings->fog = FOG_LINEAR;
2929 else
2931 switch (stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE])
2933 case WINED3DFOG_NONE:
2934 case WINED3DFOG_LINEAR:
2935 settings->fog = FOG_LINEAR;
2936 break;
2937 case WINED3DFOG_EXP:
2938 settings->fog = FOG_EXP;
2939 break;
2940 case WINED3DFOG_EXP2:
2941 settings->fog = FOG_EXP2;
2942 break;
2946 else
2948 switch (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE])
2950 case WINED3DFOG_LINEAR:
2951 settings->fog = FOG_LINEAR;
2952 break;
2953 case WINED3DFOG_EXP:
2954 settings->fog = FOG_EXP;
2955 break;
2956 case WINED3DFOG_EXP2:
2957 settings->fog = FOG_EXP2;
2958 break;
2961 if (stateblock->state.render_states[WINED3DRS_SRGBWRITEENABLE]
2962 && rt->resource.format->Flags & WINED3DFMT_FLAG_SRGB_WRITE)
2964 settings->sRGB_write = 1;
2965 } else {
2966 settings->sRGB_write = 0;
2968 if (device->vs_clipping || !use_vs(&stateblock->state) || !stateblock->state.render_states[WINED3DRS_CLIPPING]
2969 || !stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE])
2971 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2972 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2973 * if no clipplane is enabled
2975 settings->emul_clipplanes = 0;
2976 } else {
2977 settings->emul_clipplanes = 1;
2981 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2982 const struct ffp_frag_settings *settings)
2984 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2985 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2988 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2990 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2991 * whereas desc points to an extended structure with implementation specific parts. */
2992 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2994 ERR("Failed to insert ffp frag shader.\n");
2998 /* Activates the texture dimension according to the bound D3D texture.
2999 * Does not care for the colorop or correct gl texture unit(when using nvrc)
3000 * Requires the caller to activate the correct unit before
3002 /* GL locking is done by the caller (state handler) */
3003 void texture_activate_dimensions(IWineD3DBaseTextureImpl *texture, const struct wined3d_gl_info *gl_info)
3005 if (texture)
3007 switch (texture->baseTexture.target)
3009 case GL_TEXTURE_2D:
3010 glDisable(GL_TEXTURE_3D);
3011 checkGLcall("glDisable(GL_TEXTURE_3D)");
3012 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3014 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3015 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3017 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3019 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3020 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3022 glEnable(GL_TEXTURE_2D);
3023 checkGLcall("glEnable(GL_TEXTURE_2D)");
3024 break;
3025 case GL_TEXTURE_RECTANGLE_ARB:
3026 glDisable(GL_TEXTURE_2D);
3027 checkGLcall("glDisable(GL_TEXTURE_2D)");
3028 glDisable(GL_TEXTURE_3D);
3029 checkGLcall("glDisable(GL_TEXTURE_3D)");
3030 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3032 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3033 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3035 glEnable(GL_TEXTURE_RECTANGLE_ARB);
3036 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3037 break;
3038 case GL_TEXTURE_3D:
3039 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3041 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3042 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3044 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3046 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3047 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3049 glDisable(GL_TEXTURE_2D);
3050 checkGLcall("glDisable(GL_TEXTURE_2D)");
3051 glEnable(GL_TEXTURE_3D);
3052 checkGLcall("glEnable(GL_TEXTURE_3D)");
3053 break;
3054 case GL_TEXTURE_CUBE_MAP_ARB:
3055 glDisable(GL_TEXTURE_2D);
3056 checkGLcall("glDisable(GL_TEXTURE_2D)");
3057 glDisable(GL_TEXTURE_3D);
3058 checkGLcall("glDisable(GL_TEXTURE_3D)");
3059 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3061 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3062 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3064 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3065 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3066 break;
3068 } else {
3069 glEnable(GL_TEXTURE_2D);
3070 checkGLcall("glEnable(GL_TEXTURE_2D)");
3071 glDisable(GL_TEXTURE_3D);
3072 checkGLcall("glDisable(GL_TEXTURE_3D)");
3073 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3075 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3076 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3078 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3080 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3081 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3083 /* Binding textures is done by samplers. A dummy texture will be bound */
3087 /* GL locking is done by the caller (state handler) */
3088 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3090 DWORD sampler = state - STATE_SAMPLER(0);
3091 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3093 /* No need to enable / disable anything here for unused samplers. The tex_colorop
3094 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3095 * will take care of this business
3097 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3098 if (sampler >= stateblock->state.lowest_disabled_stage) return;
3099 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3101 texture_activate_dimensions(stateblock->state.textures[sampler], context->gl_info);
3104 void *wined3d_rb_alloc(size_t size)
3106 return HeapAlloc(GetProcessHeap(), 0, size);
3109 void *wined3d_rb_realloc(void *ptr, size_t size)
3111 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3114 void wined3d_rb_free(void *ptr)
3116 HeapFree(GetProcessHeap(), 0, ptr);
3119 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3121 const struct ffp_frag_settings *ka = key;
3122 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3124 return memcmp(ka, kb, sizeof(*ka));
3127 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3129 wined3d_rb_alloc,
3130 wined3d_rb_realloc,
3131 wined3d_rb_free,
3132 ffp_frag_program_key_compare,
3135 UINT wined3d_log2i(UINT32 x)
3137 static const UINT l[] =
3139 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3140 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3141 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3142 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3143 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3144 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3145 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3146 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3147 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3148 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3149 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3150 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3151 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3152 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3153 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3154 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3156 UINT32 i;
3158 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3161 /* Set the shader type for this device, depending on the given capabilities
3162 * and the user preferences in wined3d_settings. */
3163 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3165 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3167 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3168 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3170 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3171 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3172 * shaders only on this card. */
3173 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3174 else *vs_selected = SHADER_GLSL;
3176 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3177 else *vs_selected = SHADER_NONE;
3179 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3180 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3181 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3182 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3183 else *ps_selected = SHADER_NONE;
3186 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
3187 const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format *src_format,
3188 const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format *dst_format)
3190 static const struct blit_shader * const blitters[] =
3192 &arbfp_blit,
3193 &ffp_blit,
3194 &cpu_blit,
3196 unsigned int i;
3198 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3200 if (blitters[i]->blit_supported(gl_info, blit_op,
3201 src_rect, src_usage, src_pool, src_format,
3202 dst_rect, dst_usage, dst_pool, dst_format))
3203 return blitters[i];
3206 return NULL;