wined3d: Recognize the SM4 NULL register type.
[wine/multimedia.git] / dlls / wined3d / utils.c
blob2957c5a3e4e8fc06886a550c559f9fb8ab128240
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_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
134 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
137 struct wined3d_format_base_flags
139 enum wined3d_format_id id;
140 DWORD flags;
143 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
144 * still needs to use the correct block based calculation for e.g. the
145 * resource size. */
146 static const struct wined3d_format_base_flags format_base_flags[] =
148 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
149 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
150 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
151 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
152 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
153 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
156 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
157 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
158 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
159 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
160 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
161 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
162 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
163 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
164 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
165 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
166 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
171 {WINED3DFMT_NVDB, WINED3DFMT_FLAG_FOURCC},
172 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
173 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
174 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
175 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
176 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
177 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
178 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
179 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
181 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
182 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
185 struct wined3d_format_compression_info
187 enum wined3d_format_id id;
188 UINT block_width;
189 UINT block_height;
190 UINT block_byte_count;
193 static const struct wined3d_format_compression_info format_compression_info[] =
195 {WINED3DFMT_DXT1, 4, 4, 8},
196 {WINED3DFMT_DXT2, 4, 4, 16},
197 {WINED3DFMT_DXT3, 4, 4, 16},
198 {WINED3DFMT_DXT4, 4, 4, 16},
199 {WINED3DFMT_DXT5, 4, 4, 16},
200 {WINED3DFMT_ATI2N, 4, 4, 16},
203 struct wined3d_format_vertex_info
205 enum wined3d_format_id id;
206 enum wined3d_ffp_emit_idx emit_idx;
207 GLint component_count;
208 GLenum gl_vtx_type;
209 GLint gl_vtx_format;
210 GLboolean gl_normalized;
211 unsigned int component_size;
214 static const struct wined3d_format_vertex_info format_vertex_info[] =
216 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
217 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
218 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
219 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
220 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
221 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
222 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
223 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
224 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
225 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
226 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
227 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
228 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
229 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
230 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
231 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
232 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
235 struct wined3d_format_texture_info
237 enum wined3d_format_id id;
238 GLint gl_internal;
239 GLint gl_srgb_internal;
240 GLint gl_rt_internal;
241 GLint gl_format;
242 GLint gl_type;
243 unsigned int conv_byte_count;
244 unsigned int flags;
245 GL_SupportedExt extension;
246 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
249 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
251 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
252 * format+type combination to load it. Thus convert it to A8L8, then load it
253 * with A4L4 internal, but A8L8 format+type
255 unsigned int x, y;
256 const unsigned char *Source;
257 unsigned char *Dest;
258 UINT outpitch = pitch * 2;
260 for(y = 0; y < height; y++) {
261 Source = src + y * pitch;
262 Dest = dst + y * outpitch;
263 for (x = 0; x < width; x++ ) {
264 unsigned char color = (*Source++);
265 /* A */ Dest[1] = (color & 0xf0) << 0;
266 /* L */ Dest[0] = (color & 0x0f) << 4;
267 Dest += 2;
272 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
274 unsigned int x, y;
275 const WORD *Source;
277 for(y = 0; y < height; y++)
279 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
280 Source = (const WORD *)(src + y * pitch);
281 for (x = 0; x < width; x++ )
283 short color = (*Source++);
284 unsigned char l = ((color >> 10) & 0xfc);
285 short v = ((color >> 5) & 0x3e);
286 short u = ((color ) & 0x1f);
287 short v_conv = v + 16;
288 short u_conv = u + 16;
290 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
291 Dest_s += 1;
296 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
298 unsigned int x, y;
299 const WORD *Source;
300 unsigned char *Dest;
301 UINT outpitch = (pitch * 3)/2;
303 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
304 * fixed function and shaders without further conversion once the surface is
305 * loaded
307 for(y = 0; y < height; y++) {
308 Source = (const WORD *)(src + y * pitch);
309 Dest = dst + y * outpitch;
310 for (x = 0; x < width; x++ ) {
311 short color = (*Source++);
312 unsigned char l = ((color >> 10) & 0xfc);
313 char v = ((color >> 5) & 0x3e);
314 char u = ((color ) & 0x1f);
316 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
317 * and doubles the positive range. Thus shift left only once, gl does the 2nd
318 * shift. GL reads a signed value and converts it into an unsigned value.
320 /* M */ Dest[2] = l << 1;
322 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
323 * from 5 bit values to 8 bit values.
325 /* V */ Dest[1] = v << 3;
326 /* U */ Dest[0] = u << 3;
327 Dest += 3;
332 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
334 unsigned int x, y;
335 const short *Source;
336 unsigned char *Dest;
337 UINT outpitch = (pitch * 3)/2;
339 for(y = 0; y < height; y++)
341 Source = (const short *)(src + y * pitch);
342 Dest = dst + y * outpitch;
343 for (x = 0; x < width; x++ )
345 LONG color = (*Source++);
346 /* B */ Dest[0] = 0xff;
347 /* G */ Dest[1] = (color >> 8) + 128; /* V */
348 /* R */ Dest[2] = (color) + 128; /* U */
349 Dest += 3;
354 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
356 unsigned int x, y;
357 const DWORD *Source;
358 unsigned char *Dest;
360 /* Doesn't work correctly with the fixed function pipeline, but can work in
361 * shaders if the shader is adjusted. (There's no use for this format in gl's
362 * standard fixed function pipeline anyway).
364 for(y = 0; y < height; y++)
366 Source = (const DWORD *)(src + y * pitch);
367 Dest = dst + y * pitch;
368 for (x = 0; x < width; x++ )
370 LONG color = (*Source++);
371 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
372 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
373 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
374 Dest += 4;
379 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
381 unsigned int x, y;
382 const DWORD *Source;
383 unsigned char *Dest;
385 /* This implementation works with the fixed function pipeline and shaders
386 * without further modification after converting the surface.
388 for(y = 0; y < height; y++)
390 Source = (const DWORD *)(src + y * pitch);
391 Dest = dst + y * pitch;
392 for (x = 0; x < width; x++ )
394 LONG color = (*Source++);
395 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
396 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
397 /* U */ Dest[0] = (color & 0xff); /* U */
398 /* I */ Dest[3] = 255; /* X */
399 Dest += 4;
404 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
406 unsigned int x, y;
407 const DWORD *Source;
408 unsigned char *Dest;
410 for(y = 0; y < height; y++)
412 Source = (const DWORD *)(src + y * pitch);
413 Dest = dst + y * pitch;
414 for (x = 0; x < width; x++ )
416 LONG color = (*Source++);
417 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
418 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
419 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
420 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
421 Dest += 4;
426 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
428 unsigned int x, y;
429 const DWORD *Source;
430 unsigned short *Dest;
431 UINT outpitch = (pitch * 3)/2;
433 for(y = 0; y < height; y++)
435 Source = (const DWORD *)(src + y * pitch);
436 Dest = (unsigned short *) (dst + y * outpitch);
437 for (x = 0; x < width; x++ )
439 DWORD color = (*Source++);
440 /* B */ Dest[0] = 0xffff;
441 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
442 /* R */ Dest[2] = (color ) + 32768; /* U */
443 Dest += 3;
448 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
450 unsigned int x, y;
451 const WORD *Source;
452 WORD *Dest;
453 UINT outpitch = (pitch * 3)/2;
455 for(y = 0; y < height; y++)
457 Source = (const WORD *)(src + y * pitch);
458 Dest = (WORD *) (dst + y * outpitch);
459 for (x = 0; x < width; x++ )
461 WORD green = (*Source++);
462 WORD red = (*Source++);
463 Dest[0] = green;
464 Dest[1] = red;
465 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
466 * shader overwrites it anyway
468 Dest[2] = 0xffff;
469 Dest += 3;
474 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
476 unsigned int x, y;
477 const float *Source;
478 float *Dest;
479 UINT outpitch = (pitch * 3)/2;
481 for(y = 0; y < height; y++)
483 Source = (const float *)(src + y * pitch);
484 Dest = (float *) (dst + y * outpitch);
485 for (x = 0; x < width; x++ )
487 float green = (*Source++);
488 float red = (*Source++);
489 Dest[0] = green;
490 Dest[1] = red;
491 Dest[2] = 1.0f;
492 Dest += 3;
497 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
499 unsigned int x, y;
500 UINT outpitch = pitch * 2;
502 for (y = 0; y < height; ++y)
504 const WORD *source = (const WORD *)(src + y * pitch);
505 DWORD *dest = (DWORD *)(dst + y * outpitch);
507 for (x = 0; x < width; ++x)
509 /* The depth data is normalized, so needs to be scaled,
510 * the stencil data isn't. Scale depth data by
511 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
512 WORD d15 = source[x] >> 1;
513 DWORD d24 = (d15 << 9) + (d15 >> 6);
514 dest[x] = (d24 << 8) | (source[x] & 0x1);
519 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
521 unsigned int x, y;
523 for (y = 0; y < height; ++y)
525 const DWORD *source = (const DWORD *)(src + y * pitch);
526 DWORD *dest = (DWORD *)(dst + y * pitch);
528 for (x = 0; x < width; ++x)
530 /* Just need to clear out the X4 part. */
531 dest[x] = source[x] & ~0xf0;
536 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
538 unsigned int x, y;
539 UINT outpitch = pitch * 2;
541 for (y = 0; y < height; ++y)
543 const DWORD *source = (const DWORD *)(src + y * pitch);
544 float *dest_f = (float *)(dst + y * outpitch);
545 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
547 for (x = 0; x < width; ++x)
549 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
550 dest_s[x * 2 + 1] = source[x] & 0xff;
555 static const struct wined3d_format_texture_info format_texture_info[] =
557 /* format id internal srgbInternal rtInternal
558 format type
559 flags
560 extension */
561 /* FourCC formats */
562 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
563 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
564 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
565 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
566 * endian machine
568 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
569 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
570 WINED3DFMT_FLAG_FILTERING,
571 WINED3D_GL_EXT_NONE, NULL},
572 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
573 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
574 WINED3DFMT_FLAG_FILTERING,
575 APPLE_YCBCR_422, NULL},
576 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
577 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
578 WINED3DFMT_FLAG_FILTERING,
579 WINED3D_GL_EXT_NONE, NULL},
580 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
581 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
582 WINED3DFMT_FLAG_FILTERING,
583 APPLE_YCBCR_422, NULL},
584 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
585 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
586 WINED3DFMT_FLAG_FILTERING,
587 WINED3D_GL_EXT_NONE, NULL},
588 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
589 GL_RGBA, GL_UNSIGNED_BYTE, 0,
590 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
591 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
592 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
593 GL_RGBA, GL_UNSIGNED_BYTE, 0,
594 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
595 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
596 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
597 GL_RGBA, GL_UNSIGNED_BYTE, 0,
598 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
599 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
600 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
601 GL_RGBA, GL_UNSIGNED_BYTE, 0,
602 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
603 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
604 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
605 GL_RGBA, GL_UNSIGNED_BYTE, 0,
606 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
607 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
608 /* IEEE formats */
609 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
610 GL_RED, GL_FLOAT, 0,
611 WINED3DFMT_FLAG_RENDERTARGET,
612 ARB_TEXTURE_FLOAT, NULL},
613 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
614 GL_RED, GL_FLOAT, 0,
615 WINED3DFMT_FLAG_RENDERTARGET,
616 ARB_TEXTURE_RG, NULL},
617 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
618 GL_RGB, GL_FLOAT, 12,
619 WINED3DFMT_FLAG_RENDERTARGET,
620 ARB_TEXTURE_FLOAT, &convert_r32g32_float},
621 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
622 GL_RG, GL_FLOAT, 0,
623 WINED3DFMT_FLAG_RENDERTARGET,
624 ARB_TEXTURE_RG, NULL},
625 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
626 GL_RGBA, GL_FLOAT, 0,
627 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
628 ARB_TEXTURE_FLOAT, NULL},
629 /* Float */
630 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
631 GL_RED, GL_HALF_FLOAT_ARB, 0,
632 WINED3DFMT_FLAG_RENDERTARGET,
633 ARB_TEXTURE_FLOAT, NULL},
634 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
635 GL_RED, GL_HALF_FLOAT_ARB, 0,
636 WINED3DFMT_FLAG_RENDERTARGET,
637 ARB_TEXTURE_RG, NULL},
638 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
639 GL_RGB, GL_HALF_FLOAT_ARB, 6,
640 WINED3DFMT_FLAG_RENDERTARGET,
641 ARB_TEXTURE_FLOAT, &convert_r16g16},
642 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
643 GL_RG, GL_HALF_FLOAT_ARB, 0,
644 WINED3DFMT_FLAG_RENDERTARGET,
645 ARB_TEXTURE_RG, NULL},
646 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
647 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
648 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
649 ARB_TEXTURE_FLOAT, NULL},
650 /* Palettized formats */
651 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
652 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
654 ARB_FRAGMENT_PROGRAM, NULL},
655 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
656 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
658 EXT_PALETTED_TEXTURE, NULL},
659 /* Standard ARGB formats */
660 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
661 GL_BGR, GL_UNSIGNED_BYTE, 0,
662 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
663 WINED3D_GL_EXT_NONE, NULL},
664 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
665 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
666 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
667 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
668 WINED3D_GL_EXT_NONE, NULL},
669 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
670 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
671 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
672 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
673 WINED3D_GL_EXT_NONE, NULL},
674 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
675 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
676 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
677 WINED3D_GL_EXT_NONE, NULL},
678 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
679 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
680 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
681 WINED3D_GL_EXT_NONE, NULL},
682 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
683 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
684 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
685 WINED3D_GL_EXT_NONE, NULL},
686 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
687 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
688 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
689 WINED3D_GL_EXT_NONE, NULL},
690 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
691 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
692 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
693 WINED3D_GL_EXT_NONE, NULL},
694 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
695 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
696 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
697 WINED3D_GL_EXT_NONE, NULL},
698 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
699 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
700 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
701 WINED3D_GL_EXT_NONE, NULL},
702 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
703 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
704 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
705 WINED3D_GL_EXT_NONE, NULL},
706 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
707 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
708 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
709 WINED3D_GL_EXT_NONE, NULL},
710 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
711 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
712 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
713 WINED3D_GL_EXT_NONE, NULL},
714 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
715 GL_RGB, GL_UNSIGNED_SHORT, 6,
716 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
717 WINED3D_GL_EXT_NONE, &convert_r16g16},
718 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
719 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
720 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
721 WINED3D_GL_EXT_NONE, NULL},
722 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
723 GL_RGBA, GL_UNSIGNED_SHORT, 0,
724 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
725 WINED3D_GL_EXT_NONE, NULL},
726 /* Luminance */
727 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
728 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
729 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
730 WINED3D_GL_EXT_NONE, NULL},
731 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
732 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
733 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
734 WINED3D_GL_EXT_NONE, NULL},
735 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
736 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
738 WINED3D_GL_EXT_NONE, &convert_l4a4_unorm},
739 /* Bump mapping stuff */
740 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
741 GL_BGR, GL_UNSIGNED_BYTE, 3,
742 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
743 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm},
744 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
745 GL_DSDT_NV, GL_BYTE, 0,
746 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
747 NV_TEXTURE_SHADER, NULL},
748 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
749 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
750 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
751 WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm},
752 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
753 GL_DSDT_MAG_NV, GL_BYTE, 3,
754 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
755 NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv},
756 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
757 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
758 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
759 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm},
760 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
761 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
762 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
763 NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv},
764 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
765 GL_BGRA, GL_UNSIGNED_BYTE, 4,
766 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
767 WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm},
768 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
769 GL_RGBA, GL_BYTE, 0,
770 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
771 NV_TEXTURE_SHADER, NULL},
772 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
773 GL_BGR, GL_UNSIGNED_SHORT, 6,
774 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
775 WINED3D_GL_EXT_NONE, &convert_r16g16_snorm},
776 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
777 GL_HILO_NV, GL_SHORT, 0,
778 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
779 NV_TEXTURE_SHADER, NULL},
780 /* Depth stencil formats */
781 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
782 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
783 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
784 ARB_DEPTH_TEXTURE, NULL},
785 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
786 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
787 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
788 ARB_DEPTH_TEXTURE, NULL},
789 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
790 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
791 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
792 ARB_DEPTH_TEXTURE, NULL},
793 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
794 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
795 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
796 EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm},
797 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
798 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
799 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
800 ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm},
801 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
802 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
803 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
804 | WINED3DFMT_FLAG_SHADOW,
805 ARB_DEPTH_TEXTURE, NULL},
806 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
807 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
808 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
809 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
810 EXT_PACKED_DEPTH_STENCIL, NULL},
811 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
812 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
813 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
814 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
815 ARB_FRAMEBUFFER_OBJECT, NULL},
816 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
817 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
818 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
819 | WINED3DFMT_FLAG_SHADOW,
820 ARB_DEPTH_TEXTURE, NULL},
821 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
822 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
823 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
824 ARB_DEPTH_TEXTURE, NULL},
825 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
826 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
827 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
828 EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm},
829 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
830 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
831 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
832 ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm},
833 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
834 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
835 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
836 | WINED3DFMT_FLAG_SHADOW,
837 ARB_DEPTH_TEXTURE, NULL},
838 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
839 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
840 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
841 WINED3D_GL_EXT_NONE, NULL},
842 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
843 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
844 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
845 ARB_DEPTH_BUFFER_FLOAT, NULL},
846 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
847 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
848 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
849 ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float},
850 /* Vendor-specific formats */
851 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
852 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
853 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
854 ATI_TEXTURE_COMPRESSION_3DC, NULL},
855 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2, GL_COMPRESSED_RED_GREEN_RGTC2, 0,
856 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
857 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
858 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
861 static inline int getFmtIdx(enum wined3d_format_id format_id)
863 /* First check if the format is at the position of its value.
864 * This will catch the argb formats before the loop is entered. */
865 if (format_id < (sizeof(formats) / sizeof(*formats))
866 && formats[format_id].id == format_id)
868 return format_id;
870 else
872 unsigned int i;
874 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
876 if (formats[i].id == format_id) return i;
879 return -1;
882 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
884 UINT format_count = sizeof(formats) / sizeof(*formats);
885 UINT i;
887 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
888 if (!gl_info->formats)
890 ERR("Failed to allocate memory.\n");
891 return FALSE;
894 for (i = 0; i < format_count; ++i)
896 struct wined3d_format *format = &gl_info->formats[i];
897 format->id = formats[i].id;
898 format->red_mask = formats[i].redMask;
899 format->green_mask = formats[i].greenMask;
900 format->blue_mask = formats[i].blueMask;
901 format->alpha_mask = formats[i].alphaMask;
902 format->byte_count = formats[i].bpp;
903 format->depth_size = formats[i].depthSize;
904 format->stencil_size = formats[i].stencilSize;
907 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
909 int fmt_idx = getFmtIdx(format_base_flags[i].id);
911 if (fmt_idx == -1)
913 ERR("Format %s (%#x) not found.\n",
914 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
915 HeapFree(GetProcessHeap(), 0, gl_info->formats);
916 return FALSE;
919 gl_info->formats[fmt_idx].Flags |= format_base_flags[i].flags;
922 return TRUE;
925 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
927 unsigned int i;
929 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
931 struct wined3d_format *format;
932 int fmt_idx = getFmtIdx(format_compression_info[i].id);
934 if (fmt_idx == -1)
936 ERR("Format %s (%#x) not found.\n",
937 debug_d3dformat(format_compression_info[i].id), format_compression_info[i].id);
938 return FALSE;
941 format = &gl_info->formats[fmt_idx];
942 format->block_width = format_compression_info[i].block_width;
943 format->block_height = format_compression_info[i].block_height;
944 format->block_byte_count = format_compression_info[i].block_byte_count;
945 format->Flags |= WINED3DFMT_FLAG_COMPRESSED;
948 return TRUE;
951 /* Context activation is done by the caller. */
952 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
954 /* Check if the default internal format is supported as a frame buffer
955 * target, otherwise fall back to the render target internal.
957 * Try to stick to the standard format if possible, this limits precision differences. */
958 GLenum status;
959 GLuint tex;
961 ENTER_GL();
963 while(glGetError());
964 glDisable(GL_BLEND);
966 glGenTextures(1, &tex);
967 glBindTexture(GL_TEXTURE_2D, tex);
969 glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
970 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
971 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
973 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
975 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
976 checkGLcall("Framebuffer format check");
978 if (status == GL_FRAMEBUFFER_COMPLETE)
980 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
981 format->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
982 format->rtInternal = format->glInternal;
984 else
986 if (!format->rtInternal)
988 if (format->Flags & WINED3DFMT_FLAG_RENDERTARGET)
990 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
991 " and no fallback specified.\n", debug_d3dformat(format->id));
992 format->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
994 else
996 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
998 format->rtInternal = format->glInternal;
1000 else
1002 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1003 debug_d3dformat(format->id));
1005 while(glGetError());
1007 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1009 glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1010 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1011 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1013 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1015 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1016 checkGLcall("Framebuffer format check");
1018 if (status == GL_FRAMEBUFFER_COMPLETE)
1020 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1021 debug_d3dformat(format->id));
1023 else
1025 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1026 debug_d3dformat(format->id));
1027 format->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1032 if (status == GL_FRAMEBUFFER_COMPLETE && format->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1034 GLuint rb;
1036 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1037 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1039 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1040 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1041 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1042 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1043 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1044 checkGLcall("RB attachment");
1047 glEnable(GL_BLEND);
1048 glClear(GL_COLOR_BUFFER_BIT);
1049 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1051 while(glGetError());
1052 TRACE("Format doesn't support post-pixelshader blending.\n");
1053 format->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1056 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1057 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1059 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1060 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1061 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1062 checkGLcall("RB cleanup");
1066 if (format->glInternal != format->glGammaInternal)
1068 glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1069 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1071 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1072 checkGLcall("Framebuffer format check");
1074 if (status == GL_FRAMEBUFFER_COMPLETE)
1076 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1077 format->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1079 else
1081 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1085 glDeleteTextures(1, &tex);
1087 LEAVE_GL();
1090 /* Context activation is done by the caller. */
1091 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1093 unsigned int i;
1094 GLuint fbo;
1096 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1098 ENTER_GL();
1100 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1101 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1103 LEAVE_GL();
1106 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1108 struct wined3d_format *format = &gl_info->formats[i];
1110 if (!format->glInternal) continue;
1112 if (format->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1114 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1115 debug_d3dformat(format->id));
1116 continue;
1119 if (format->Flags & WINED3DFMT_FLAG_COMPRESSED)
1121 TRACE("Skipping format %s because it's a compressed format.\n",
1122 debug_d3dformat(format->id));
1123 continue;
1126 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1128 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1129 check_fbo_compat(gl_info, format);
1131 else
1133 format->rtInternal = format->glInternal;
1137 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1139 ENTER_GL();
1141 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1143 LEAVE_GL();
1147 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1149 unsigned int i;
1151 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1153 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1154 struct wined3d_format *format;
1156 if (fmt_idx == -1)
1158 ERR("Format %s (%#x) not found.\n",
1159 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1160 return FALSE;
1163 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1165 format = &gl_info->formats[fmt_idx];
1166 format->glInternal = format_texture_info[i].gl_internal;
1167 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1168 format->rtInternal = format_texture_info[i].gl_rt_internal;
1169 format->glFormat = format_texture_info[i].gl_format;
1170 format->glType = format_texture_info[i].gl_type;
1171 format->color_fixup = COLOR_FIXUP_IDENTITY;
1172 format->Flags |= format_texture_info[i].flags;
1173 format->heightscale = 1.0f;
1175 /* Texture conversion stuff */
1176 format->convert = format_texture_info[i].convert;
1177 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1180 return TRUE;
1183 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1185 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1186 c1 >>= 8; c2 >>= 8;
1187 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1188 c1 >>= 8; c2 >>= 8;
1189 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1190 c1 >>= 8; c2 >>= 8;
1191 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1192 return TRUE;
1195 /* A context is provided by the caller */
1196 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1198 static const DWORD data[] = {0x00000000, 0xffffffff};
1199 GLuint tex, fbo, buffer;
1200 DWORD readback[16 * 1];
1201 BOOL ret = FALSE;
1203 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1204 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1205 * falling back to software. If this changes in the future this code will get fooled and
1206 * apps might hit the software path due to incorrectly advertised caps.
1208 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1209 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1210 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1213 ENTER_GL();
1214 while(glGetError());
1216 glGenTextures(1, &buffer);
1217 glBindTexture(GL_TEXTURE_2D, buffer);
1218 memset(readback, 0x7e, sizeof(readback));
1219 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1220 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1221 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1222 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1223 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1224 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1226 glGenTextures(1, &tex);
1227 glBindTexture(GL_TEXTURE_2D, tex);
1228 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1230 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1231 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1232 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1233 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1234 glEnable(GL_TEXTURE_2D);
1236 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1237 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1238 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1239 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1241 glViewport(0, 0, 16, 1);
1242 glDisable(GL_LIGHTING);
1243 glMatrixMode(GL_MODELVIEW);
1244 glLoadIdentity();
1245 glMatrixMode(GL_PROJECTION);
1246 glLoadIdentity();
1248 glClearColor(0, 1, 0, 0);
1249 glClear(GL_COLOR_BUFFER_BIT);
1251 glBegin(GL_TRIANGLE_STRIP);
1252 glTexCoord2f(0.0, 0.0);
1253 glVertex2f(-1.0f, -1.0f);
1254 glTexCoord2f(1.0, 0.0);
1255 glVertex2f(1.0f, -1.0f);
1256 glTexCoord2f(0.0, 1.0);
1257 glVertex2f(-1.0f, 1.0f);
1258 glTexCoord2f(1.0, 1.0);
1259 glVertex2f(1.0f, 1.0f);
1260 glEnd();
1262 glBindTexture(GL_TEXTURE_2D, buffer);
1263 memset(readback, 0x7f, sizeof(readback));
1264 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1265 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1266 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1268 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1269 readback[6], readback[9]);
1270 ret = FALSE;
1272 else
1274 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1275 readback[6], readback[9]);
1276 ret = TRUE;
1279 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1280 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1281 glDeleteTextures(1, &tex);
1282 glDeleteTextures(1, &buffer);
1284 if(glGetError())
1286 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1287 ret = FALSE;
1289 LEAVE_GL();
1290 return ret;
1293 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1295 struct wined3d_format *format;
1296 unsigned int fmt_idx, i;
1297 static const enum wined3d_format_id fmts16[] =
1299 WINED3DFMT_R16_FLOAT,
1300 WINED3DFMT_R16G16_FLOAT,
1301 WINED3DFMT_R16G16B16A16_FLOAT,
1303 BOOL filtered;
1305 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1307 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1308 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1310 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1311 filtered = TRUE;
1313 else if (gl_info->limits.glsl_varyings > 44)
1315 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1316 filtered = TRUE;
1318 else
1320 TRACE("Assuming no float16 blending\n");
1321 filtered = FALSE;
1324 if(filtered)
1326 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1328 fmt_idx = getFmtIdx(fmts16[i]);
1329 gl_info->formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
1332 return;
1335 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1337 fmt_idx = getFmtIdx(fmts16[i]);
1338 format = &gl_info->formats[fmt_idx];
1339 if (!format->glInternal) continue; /* Not supported by GL */
1341 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1342 if(filtered)
1344 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1345 format->Flags |= WINED3DFMT_FLAG_FILTERING;
1347 else
1349 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1354 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1356 int idx;
1358 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1359 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1360 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1362 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1363 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1364 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1366 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1367 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1368 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1370 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1371 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1372 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1374 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1375 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1376 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1378 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1379 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1380 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1381 * the only driver that implements it(fglrx) has a buggy implementation.
1383 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1384 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1385 * conversion for this format.
1387 if (!gl_info->supported[NV_TEXTURE_SHADER])
1389 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1390 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1391 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1392 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1393 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1394 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1396 else
1398 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1399 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1400 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1402 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1403 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1404 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1407 if (!gl_info->supported[NV_TEXTURE_SHADER])
1409 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1410 * with each other
1412 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1413 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1414 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1415 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1416 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1417 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1418 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1419 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1420 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1422 else
1424 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1425 * are converted at surface loading time, but they do not need any modification in
1426 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1427 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1431 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1433 idx = getFmtIdx(WINED3DFMT_ATI2N);
1434 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1435 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1437 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1439 idx = getFmtIdx(WINED3DFMT_ATI2N);
1440 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1441 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1444 if (!gl_info->supported[APPLE_YCBCR_422])
1446 idx = getFmtIdx(WINED3DFMT_YUY2);
1447 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1449 idx = getFmtIdx(WINED3DFMT_UYVY);
1450 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1453 idx = getFmtIdx(WINED3DFMT_YV12);
1454 gl_info->formats[idx].heightscale = 1.5f;
1455 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1457 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1459 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1460 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1463 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1465 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1466 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1469 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1471 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1472 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1473 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1474 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1476 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1477 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1481 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1483 unsigned int i;
1485 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1487 struct wined3d_format *format;
1488 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1490 if (fmt_idx == -1)
1492 ERR("Format %s (%#x) not found.\n",
1493 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1494 return FALSE;
1497 format = &gl_info->formats[fmt_idx];
1498 format->emit_idx = format_vertex_info[i].emit_idx;
1499 format->component_count = format_vertex_info[i].component_count;
1500 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1501 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1502 format->gl_normalized = format_vertex_info[i].gl_normalized;
1503 format->component_size = format_vertex_info[i].component_size;
1506 return TRUE;
1509 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1511 if (!init_format_base_info(gl_info)) return FALSE;
1513 if (!init_format_compression_info(gl_info))
1515 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1516 gl_info->formats = NULL;
1517 return FALSE;
1520 return TRUE;
1523 /* Context activation is done by the caller. */
1524 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1526 if (!init_format_base_info(gl_info)) return FALSE;
1528 if (!init_format_compression_info(gl_info)) goto fail;
1529 if (!init_format_texture_info(gl_info)) goto fail;
1530 if (!init_format_vertex_info(gl_info)) goto fail;
1532 apply_format_fixups(gl_info);
1533 init_format_fbo_compat_info(gl_info);
1534 init_format_filter_info(gl_info, vendor);
1536 return TRUE;
1538 fail:
1539 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1540 gl_info->formats = NULL;
1541 return FALSE;
1544 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1545 enum wined3d_format_id format_id)
1547 int idx = getFmtIdx(format_id);
1549 if (idx == -1)
1551 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1552 debug_d3dformat(format_id), format_id);
1553 /* Get the caller a valid pointer */
1554 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1557 return &gl_info->formats[idx];
1560 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1562 UINT size;
1564 if (format->id == WINED3DFMT_UNKNOWN)
1566 size = 0;
1568 else if (format->Flags & WINED3DFMT_FLAG_COMPRESSED)
1570 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1571 UINT row_count = (height + format->block_height - 1) / format->block_height;
1572 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1574 else
1576 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1579 if (format->heightscale != 0.0f) size *= format->heightscale;
1581 return size;
1584 /*****************************************************************************
1585 * Trace formatting of useful values
1587 const char *debug_d3dformat(enum wined3d_format_id format_id)
1589 switch (format_id)
1591 #define FMT_TO_STR(format_id) case format_id: return #format_id
1592 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1593 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1594 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1595 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1596 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1597 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1598 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1599 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1600 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1601 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1602 FMT_TO_STR(WINED3DFMT_P8_UINT);
1603 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1604 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1605 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1606 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1607 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1608 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1609 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1610 FMT_TO_STR(WINED3DFMT_UYVY);
1611 FMT_TO_STR(WINED3DFMT_YUY2);
1612 FMT_TO_STR(WINED3DFMT_YV12);
1613 FMT_TO_STR(WINED3DFMT_DXT1);
1614 FMT_TO_STR(WINED3DFMT_DXT2);
1615 FMT_TO_STR(WINED3DFMT_DXT3);
1616 FMT_TO_STR(WINED3DFMT_DXT4);
1617 FMT_TO_STR(WINED3DFMT_DXT5);
1618 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1619 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1620 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1621 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1622 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1623 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1624 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1625 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1626 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1627 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1628 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1629 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1630 FMT_TO_STR(WINED3DFMT_ATI2N);
1631 FMT_TO_STR(WINED3DFMT_NVDB);
1632 FMT_TO_STR(WINED3DFMT_NVHU);
1633 FMT_TO_STR(WINED3DFMT_NVHS);
1634 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1635 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1636 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1637 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1638 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1639 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1640 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1641 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1642 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1643 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1644 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1645 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1646 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1647 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1648 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1649 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1650 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1651 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1652 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1653 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1654 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1655 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1656 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1657 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1658 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1659 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1660 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1661 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1662 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1663 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1664 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1665 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1666 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1667 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1668 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1669 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1670 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1671 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1672 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1673 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1674 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1675 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1676 FMT_TO_STR(WINED3DFMT_R32_UINT);
1677 FMT_TO_STR(WINED3DFMT_R32_SINT);
1678 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1679 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1680 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1681 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1682 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1683 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1684 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1685 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1686 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1687 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1688 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1689 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1690 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1691 FMT_TO_STR(WINED3DFMT_R16_UINT);
1692 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1693 FMT_TO_STR(WINED3DFMT_R16_SINT);
1694 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1695 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1696 FMT_TO_STR(WINED3DFMT_R8_UINT);
1697 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1698 FMT_TO_STR(WINED3DFMT_R8_SINT);
1699 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1700 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1701 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1702 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1703 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1704 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1705 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1706 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1707 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1708 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1709 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1710 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1711 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1712 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1713 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1714 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1715 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1716 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1717 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1718 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1719 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1720 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1721 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1722 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1723 #undef FMT_TO_STR
1724 default:
1726 char fourcc[5];
1727 fourcc[0] = (char)(format_id);
1728 fourcc[1] = (char)(format_id >> 8);
1729 fourcc[2] = (char)(format_id >> 16);
1730 fourcc[3] = (char)(format_id >> 24);
1731 fourcc[4] = 0;
1732 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1733 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1734 else
1735 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1737 return "unrecognized";
1741 const char *debug_d3ddevicetype(WINED3DDEVTYPE devtype)
1743 switch (devtype)
1745 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1746 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1747 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1748 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1749 #undef DEVTYPE_TO_STR
1750 default:
1751 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1752 return "unrecognized";
1756 const char *debug_d3dusage(DWORD usage)
1758 char buf[333];
1760 buf[0] = '\0';
1761 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1762 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1763 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1764 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1765 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1766 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1767 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1768 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1769 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1770 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1771 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1772 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1773 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1774 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1775 #undef WINED3DUSAGE_TO_STR
1776 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1778 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1781 const char *debug_d3dusagequery(DWORD usagequery)
1783 char buf[238];
1785 buf[0] = '\0';
1786 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1787 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1788 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1789 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1790 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1791 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1792 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1793 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1794 #undef WINED3DUSAGEQUERY_TO_STR
1795 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1797 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1800 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1801 switch (method) {
1802 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1803 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1804 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1805 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1806 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1807 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1808 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1809 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1810 #undef WINED3DDECLMETHOD_TO_STR
1811 default:
1812 FIXME("Unrecognized %u declaration method!\n", method);
1813 return "unrecognized";
1817 const char* debug_d3ddeclusage(BYTE usage) {
1818 switch (usage) {
1819 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1820 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1821 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1822 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1823 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1824 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1825 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1826 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1827 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1828 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1829 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1830 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1831 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1832 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1833 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1834 #undef WINED3DDECLUSAGE_TO_STR
1835 default:
1836 FIXME("Unrecognized %u declaration usage!\n", usage);
1837 return "unrecognized";
1841 const char *debug_d3dresourcetype(WINED3DRESOURCETYPE res)
1843 switch (res)
1845 #define RES_TO_STR(res) case res: return #res
1846 RES_TO_STR(WINED3DRTYPE_SURFACE);
1847 RES_TO_STR(WINED3DRTYPE_VOLUME);
1848 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1849 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1850 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1851 RES_TO_STR(WINED3DRTYPE_BUFFER);
1852 #undef RES_TO_STR
1853 default:
1854 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1855 return "unrecognized";
1859 const char *debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType)
1861 switch (PrimitiveType)
1863 #define PRIM_TO_STR(prim) case prim: return #prim
1864 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1865 PRIM_TO_STR(WINED3DPT_POINTLIST);
1866 PRIM_TO_STR(WINED3DPT_LINELIST);
1867 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1868 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1869 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1870 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1871 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1872 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1873 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1874 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1875 #undef PRIM_TO_STR
1876 default:
1877 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1878 return "unrecognized";
1882 const char *debug_d3drenderstate(WINED3DRENDERSTATETYPE state)
1884 switch (state)
1886 #define D3DSTATE_TO_STR(u) case u: return #u
1887 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS);
1888 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE);
1889 D3DSTATE_TO_STR(WINED3DRS_WRAPU);
1890 D3DSTATE_TO_STR(WINED3DRS_WRAPV);
1891 D3DSTATE_TO_STR(WINED3DRS_ZENABLE);
1892 D3DSTATE_TO_STR(WINED3DRS_FILLMODE);
1893 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE);
1894 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN);
1895 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE);
1896 D3DSTATE_TO_STR(WINED3DRS_ROP2);
1897 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK);
1898 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE);
1899 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE);
1900 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL);
1901 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND);
1902 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND);
1903 D3DSTATE_TO_STR(WINED3DRS_CULLMODE);
1904 D3DSTATE_TO_STR(WINED3DRS_ZFUNC);
1905 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF);
1906 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC);
1907 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE);
1908 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE);
1909 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE);
1910 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE);
1911 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE);
1912 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL);
1913 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX);
1914 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA);
1915 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR);
1916 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE);
1917 D3DSTATE_TO_STR(WINED3DRS_FOGSTART);
1918 D3DSTATE_TO_STR(WINED3DRS_FOGEND);
1919 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY);
1920 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE);
1921 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS);
1922 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE);
1923 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS);
1924 D3DSTATE_TO_STR(WINED3DRS_ZBIAS);
1925 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE);
1926 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY);
1927 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH);
1928 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1929 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE);
1930 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL);
1931 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL);
1932 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS);
1933 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC);
1934 D3DSTATE_TO_STR(WINED3DRS_STENCILREF);
1935 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK);
1936 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK);
1937 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR);
1938 D3DSTATE_TO_STR(WINED3DRS_WRAP0);
1939 D3DSTATE_TO_STR(WINED3DRS_WRAP1);
1940 D3DSTATE_TO_STR(WINED3DRS_WRAP2);
1941 D3DSTATE_TO_STR(WINED3DRS_WRAP3);
1942 D3DSTATE_TO_STR(WINED3DRS_WRAP4);
1943 D3DSTATE_TO_STR(WINED3DRS_WRAP5);
1944 D3DSTATE_TO_STR(WINED3DRS_WRAP6);
1945 D3DSTATE_TO_STR(WINED3DRS_WRAP7);
1946 D3DSTATE_TO_STR(WINED3DRS_CLIPPING);
1947 D3DSTATE_TO_STR(WINED3DRS_LIGHTING);
1948 D3DSTATE_TO_STR(WINED3DRS_EXTENTS);
1949 D3DSTATE_TO_STR(WINED3DRS_AMBIENT);
1950 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE);
1951 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX);
1952 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER);
1953 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS);
1954 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE);
1955 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE);
1956 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE);
1957 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE);
1958 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE);
1959 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND);
1960 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE);
1961 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING);
1962 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE);
1963 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN);
1964 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE);
1965 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE);
1966 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A);
1967 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B);
1968 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C);
1969 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS);
1970 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK);
1971 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE);
1972 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS);
1973 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN);
1974 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX);
1975 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE);
1976 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE);
1977 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR);
1978 D3DSTATE_TO_STR(WINED3DRS_BLENDOP);
1979 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE);
1980 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE);
1981 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE);
1982 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS);
1983 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE);
1984 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL);
1985 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL);
1986 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X);
1987 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y);
1988 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z);
1989 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W);
1990 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1991 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE);
1992 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL);
1993 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL);
1994 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS);
1995 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC);
1996 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1);
1997 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2);
1998 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3);
1999 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR);
2000 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE);
2001 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS);
2002 D3DSTATE_TO_STR(WINED3DRS_WRAP8);
2003 D3DSTATE_TO_STR(WINED3DRS_WRAP9);
2004 D3DSTATE_TO_STR(WINED3DRS_WRAP10);
2005 D3DSTATE_TO_STR(WINED3DRS_WRAP11);
2006 D3DSTATE_TO_STR(WINED3DRS_WRAP12);
2007 D3DSTATE_TO_STR(WINED3DRS_WRAP13);
2008 D3DSTATE_TO_STR(WINED3DRS_WRAP14);
2009 D3DSTATE_TO_STR(WINED3DRS_WRAP15);
2010 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE);
2011 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA);
2012 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA);
2013 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA);
2014 #undef D3DSTATE_TO_STR
2015 default:
2016 FIXME("Unrecognized %u render state!\n", state);
2017 return "unrecognized";
2021 const char *debug_d3dsamplerstate(DWORD state)
2023 switch (state)
2025 #define D3DSTATE_TO_STR(u) case u: return #u
2026 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR);
2027 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU);
2028 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV);
2029 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW);
2030 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER);
2031 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER);
2032 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER);
2033 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
2034 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL);
2035 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
2036 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE);
2037 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX);
2038 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET);
2039 #undef D3DSTATE_TO_STR
2040 default:
2041 FIXME("Unrecognized %u sampler state!\n", state);
2042 return "unrecognized";
2046 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2047 switch (filter_type) {
2048 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2049 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2050 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2051 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2052 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2053 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2054 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2055 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2056 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2057 #undef D3DTEXTUREFILTERTYPE_TO_STR
2058 default:
2059 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2060 return "unrecognized";
2064 const char *debug_d3dtexturestate(DWORD state)
2066 switch (state)
2068 #define D3DSTATE_TO_STR(u) case u: return #u
2069 D3DSTATE_TO_STR(WINED3DTSS_COLOROP);
2070 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1);
2071 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2);
2072 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP);
2073 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1);
2074 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2);
2075 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00);
2076 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01);
2077 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10);
2078 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11);
2079 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX);
2080 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE);
2081 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET);
2082 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS);
2083 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0);
2084 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0);
2085 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG);
2086 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT);
2087 #undef D3DSTATE_TO_STR
2088 default:
2089 FIXME("Unrecognized %u texture state!\n", state);
2090 return "unrecognized";
2094 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2095 switch (d3dtop) {
2096 #define D3DTOP_TO_STR(u) case u: return #u
2097 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2098 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2099 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2100 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2101 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2102 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2103 D3DTOP_TO_STR(WINED3DTOP_ADD);
2104 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2105 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2106 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2107 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2108 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2109 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2110 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2111 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2112 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2113 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2114 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2115 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2116 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2117 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2118 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2119 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2120 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2121 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2122 D3DTOP_TO_STR(WINED3DTOP_LERP);
2123 #undef D3DTOP_TO_STR
2124 default:
2125 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2126 return "unrecognized";
2130 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2131 switch (tstype) {
2132 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2133 TSTYPE_TO_STR(WINED3DTS_VIEW);
2134 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2135 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2136 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2137 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2138 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2139 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2140 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2141 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2142 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2143 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2144 #undef TSTYPE_TO_STR
2145 default:
2146 if (tstype > 256 && tstype < 512) {
2147 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2148 return ("WINED3DTS_WORLDMATRIX > 0");
2150 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2151 return "unrecognized";
2155 const char *debug_d3dstate(DWORD state)
2157 if (STATE_IS_RENDER(state))
2158 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2159 if (STATE_IS_TEXTURESTAGE(state))
2161 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2162 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2163 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2164 texture_stage, debug_d3dtexturestate(texture_state));
2166 if (STATE_IS_SAMPLER(state))
2167 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2168 if (STATE_IS_PIXELSHADER(state))
2169 return "STATE_PIXELSHADER";
2170 if (STATE_IS_TRANSFORM(state))
2171 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2172 if (STATE_IS_STREAMSRC(state))
2173 return "STATE_STREAMSRC";
2174 if (STATE_IS_INDEXBUFFER(state))
2175 return "STATE_INDEXBUFFER";
2176 if (STATE_IS_VDECL(state))
2177 return "STATE_VDECL";
2178 if (STATE_IS_VSHADER(state))
2179 return "STATE_VSHADER";
2180 if (STATE_IS_VIEWPORT(state))
2181 return "STATE_VIEWPORT";
2182 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2183 return "STATE_VERTEXSHADERCONSTANT";
2184 if (STATE_IS_PIXELSHADERCONSTANT(state))
2185 return "STATE_PIXELSHADERCONSTANT";
2186 if (STATE_IS_ACTIVELIGHT(state))
2187 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2188 if (STATE_IS_SCISSORRECT(state))
2189 return "STATE_SCISSORRECT";
2190 if (STATE_IS_CLIPPLANE(state))
2191 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2192 if (STATE_IS_MATERIAL(state))
2193 return "STATE_MATERIAL";
2194 if (STATE_IS_FRONTFACE(state))
2195 return "STATE_FRONTFACE";
2197 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2200 const char *debug_d3dpool(WINED3DPOOL pool)
2202 switch (pool)
2204 #define POOL_TO_STR(p) case p: return #p
2205 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2206 POOL_TO_STR(WINED3DPOOL_MANAGED);
2207 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2208 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2209 #undef POOL_TO_STR
2210 default:
2211 FIXME("Unrecognized %u WINED3DPOOL!\n", pool);
2212 return "unrecognized";
2216 const char *debug_fbostatus(GLenum status) {
2217 switch(status) {
2218 #define FBOSTATUS_TO_STR(u) case u: return #u
2219 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2220 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2221 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2222 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2223 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2224 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2225 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2226 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2227 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2228 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2229 #undef FBOSTATUS_TO_STR
2230 default:
2231 FIXME("Unrecognied FBO status 0x%08x\n", status);
2232 return "unrecognized";
2236 const char *debug_glerror(GLenum error) {
2237 switch(error) {
2238 #define GLERROR_TO_STR(u) case u: return #u
2239 GLERROR_TO_STR(GL_NO_ERROR);
2240 GLERROR_TO_STR(GL_INVALID_ENUM);
2241 GLERROR_TO_STR(GL_INVALID_VALUE);
2242 GLERROR_TO_STR(GL_INVALID_OPERATION);
2243 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2244 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2245 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2246 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2247 #undef GLERROR_TO_STR
2248 default:
2249 FIXME("Unrecognied GL error 0x%08x\n", error);
2250 return "unrecognized";
2254 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2255 switch(basis) {
2256 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2257 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2258 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2259 default: return "unrecognized";
2263 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2264 switch(degree) {
2265 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2266 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2267 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2268 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2269 default: return "unrecognized";
2273 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2275 switch(source)
2277 #define WINED3D_TO_STR(x) case x: return #x
2278 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2279 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2280 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2281 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2282 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2283 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2284 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2285 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2286 #undef WINED3D_TO_STR
2287 default:
2288 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2289 return "unrecognized";
2293 static const char *debug_complex_fixup(enum complex_fixup fixup)
2295 switch(fixup)
2297 #define WINED3D_TO_STR(x) case x: return #x
2298 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2299 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2300 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2301 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2302 #undef WINED3D_TO_STR
2303 default:
2304 FIXME("Unrecognized complex fixup %#x\n", fixup);
2305 return "unrecognized";
2309 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2311 if (is_complex_fixup(fixup))
2313 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2314 return;
2317 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2318 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2319 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2320 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2323 const char *debug_surflocation(DWORD flag) {
2324 char buf[128];
2326 buf[0] = 0;
2327 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2328 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2329 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2330 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2331 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2334 /*****************************************************************************
2335 * Useful functions mapping GL <-> D3D values
2337 GLenum StencilOp(DWORD op) {
2338 switch(op) {
2339 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2340 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2341 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2342 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2343 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2344 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2345 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2346 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2347 default:
2348 FIXME("Unrecognized stencil op %d\n", op);
2349 return GL_KEEP;
2353 GLenum CompareFunc(DWORD func) {
2354 switch ((WINED3DCMPFUNC)func) {
2355 case WINED3DCMP_NEVER : return GL_NEVER;
2356 case WINED3DCMP_LESS : return GL_LESS;
2357 case WINED3DCMP_EQUAL : return GL_EQUAL;
2358 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2359 case WINED3DCMP_GREATER : return GL_GREATER;
2360 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2361 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2362 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2363 default:
2364 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2365 return 0;
2369 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2370 WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
2372 if (op == WINED3DTOP_DISABLE) return FALSE;
2373 if (state->textures[stage]) return FALSE;
2375 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2376 && op != WINED3DTOP_SELECTARG2) return TRUE;
2377 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2378 && op != WINED3DTOP_SELECTARG1) return TRUE;
2379 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2380 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2382 return FALSE;
2385 /* Setup this textures matrix according to the texture flags*/
2386 /* GL locking is done by the caller (state handler) */
2387 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2388 enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2390 float mat[16];
2392 glMatrixMode(GL_TEXTURE);
2393 checkGLcall("glMatrixMode(GL_TEXTURE)");
2395 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2396 glLoadIdentity();
2397 checkGLcall("glLoadIdentity()");
2398 return;
2401 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2402 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2403 return;
2406 memcpy(mat, smat, 16 * sizeof(float));
2408 if (flags & WINED3DTTFF_PROJECTED) {
2409 if(!ffp_proj_control) {
2410 switch (flags & ~WINED3DTTFF_PROJECTED) {
2411 case WINED3DTTFF_COUNT2:
2412 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2413 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2414 break;
2415 case WINED3DTTFF_COUNT3:
2416 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2417 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2418 break;
2421 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2422 if(!calculatedCoords) {
2423 switch(vtx_fmt)
2425 case WINED3DFMT_R32_FLOAT:
2426 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2427 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2428 * the input value to the transformation will be 0, so the matrix value is irrelevant
2430 mat[12] = mat[4];
2431 mat[13] = mat[5];
2432 mat[14] = mat[6];
2433 mat[15] = mat[7];
2434 break;
2435 case WINED3DFMT_R32G32_FLOAT:
2436 /* See above, just 3rd and 4th coord
2438 mat[12] = mat[8];
2439 mat[13] = mat[9];
2440 mat[14] = mat[10];
2441 mat[15] = mat[11];
2442 break;
2443 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2444 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2446 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2447 * into a bad place. The division elimination below will apply to make sure the
2448 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2450 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2451 break;
2452 default:
2453 FIXME("Unexpected fixed function texture coord input\n");
2456 if(!ffp_proj_control) {
2457 switch (flags & ~WINED3DTTFF_PROJECTED) {
2458 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2459 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2460 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2461 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2462 * the 4th coord evaluates to 1.0 to eliminate that.
2464 * If the fixed function pipeline is used, the 4th value remains unused,
2465 * so there is no danger in doing this. With vertex shaders we have a
2466 * problem. Should an app hit that problem, the code here would have to
2467 * check for pixel shaders, and the shader has to undo the default gl divide.
2469 * A more serious problem occurs if the app passes 4 coordinates in, and the
2470 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2471 * or a replacement shader
2473 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2478 glLoadMatrixf(mat);
2479 checkGLcall("glLoadMatrixf(mat)");
2482 /* This small helper function is used to convert a bitmask into the number of masked bits */
2483 unsigned int count_bits(unsigned int mask)
2485 unsigned int count;
2486 for (count = 0; mask; ++count)
2488 mask &= mask - 1;
2490 return count;
2493 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2494 * The later function requires individual color components. */
2495 BOOL getColorBits(const struct wined3d_format *format,
2496 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2498 TRACE("format %s.\n", debug_d3dformat(format->id));
2500 switch (format->id)
2502 case WINED3DFMT_B8G8R8X8_UNORM:
2503 case WINED3DFMT_B8G8R8_UNORM:
2504 case WINED3DFMT_B8G8R8A8_UNORM:
2505 case WINED3DFMT_R8G8B8A8_UNORM:
2506 case WINED3DFMT_B10G10R10A2_UNORM:
2507 case WINED3DFMT_B5G5R5X1_UNORM:
2508 case WINED3DFMT_B5G5R5A1_UNORM:
2509 case WINED3DFMT_B5G6R5_UNORM:
2510 case WINED3DFMT_B4G4R4X4_UNORM:
2511 case WINED3DFMT_B4G4R4A4_UNORM:
2512 case WINED3DFMT_B2G3R3_UNORM:
2513 case WINED3DFMT_P8_UINT_A8_UNORM:
2514 case WINED3DFMT_P8_UINT:
2515 break;
2516 default:
2517 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2518 return FALSE;
2521 *redSize = count_bits(format->red_mask);
2522 *greenSize = count_bits(format->green_mask);
2523 *blueSize = count_bits(format->blue_mask);
2524 *alphaSize = count_bits(format->alpha_mask);
2525 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2527 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2528 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2529 return TRUE;
2532 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2533 BOOL getDepthStencilBits(const struct wined3d_format *format, short *depthSize, short *stencilSize)
2535 TRACE("format %s.\n", debug_d3dformat(format->id));
2537 switch (format->id)
2539 case WINED3DFMT_D16_LOCKABLE:
2540 case WINED3DFMT_D16_UNORM:
2541 case WINED3DFMT_S1_UINT_D15_UNORM:
2542 case WINED3DFMT_X8D24_UNORM:
2543 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2544 case WINED3DFMT_D24_UNORM_S8_UINT:
2545 case WINED3DFMT_S8_UINT_D24_FLOAT:
2546 case WINED3DFMT_D32_UNORM:
2547 case WINED3DFMT_D32_FLOAT:
2548 break;
2549 default:
2550 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2551 return FALSE;
2554 *depthSize = format->depth_size;
2555 *stencilSize = format->stencil_size;
2557 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2558 *depthSize, *stencilSize, debug_d3dformat(format->id));
2559 return TRUE;
2562 /* Note: It's the caller's responsibility to ensure values can be expressed
2563 * in the requested format. UNORM formats for example can only express values
2564 * in the range 0.0f -> 1.0f. */
2565 DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, const WINED3DCOLORVALUE *color)
2567 static const struct
2569 enum wined3d_format_id format_id;
2570 float r_mul;
2571 float g_mul;
2572 float b_mul;
2573 float a_mul;
2574 BYTE r_shift;
2575 BYTE g_shift;
2576 BYTE b_shift;
2577 BYTE a_shift;
2579 conv[] =
2581 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2582 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2583 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2584 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2585 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2586 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2587 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2588 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2589 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2590 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2591 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2592 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2593 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2594 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2596 unsigned int i;
2598 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2599 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2601 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2603 DWORD ret;
2605 if (format->id != conv[i].format_id) continue;
2607 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2608 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2609 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2610 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2612 TRACE("Returning 0x%08x.\n", ret);
2614 return ret;
2617 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2619 return 0;
2622 /* DirectDraw stuff */
2623 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2625 switch (depth)
2627 case 8: return WINED3DFMT_P8_UINT;
2628 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2629 case 16: return WINED3DFMT_B5G6R5_UNORM;
2630 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2631 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2632 default: return WINED3DFMT_UNKNOWN;
2636 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2637 WINED3DMATRIX temp;
2639 /* Now do the multiplication 'by hand'.
2640 I know that all this could be optimised, but this will be done later :-) */
2641 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);
2642 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);
2643 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);
2644 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);
2646 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);
2647 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);
2648 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);
2649 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);
2651 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);
2652 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);
2653 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);
2654 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);
2656 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);
2657 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);
2658 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);
2659 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);
2661 /* And copy the new matrix in the good storage.. */
2662 memcpy(dest, &temp, 16 * sizeof(float));
2665 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2666 DWORD size = 0;
2667 int i;
2668 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2670 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2671 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2672 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2673 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2674 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2675 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2676 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2677 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2678 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2679 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2680 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2681 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2682 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2683 default: ERR("Unexpected position mask\n");
2685 for (i = 0; i < numTextures; i++) {
2686 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2689 return size;
2692 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2693 #define ARG1 0x01
2694 #define ARG2 0x02
2695 #define ARG0 0x04
2696 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2697 /* undefined */ 0,
2698 /* D3DTOP_DISABLE */ 0,
2699 /* D3DTOP_SELECTARG1 */ ARG1,
2700 /* D3DTOP_SELECTARG2 */ ARG2,
2701 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2702 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2703 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2704 /* D3DTOP_ADD */ ARG1 | ARG2,
2705 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2706 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2707 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2708 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2709 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2710 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2711 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2712 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2713 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2714 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2715 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2716 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2717 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2718 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2719 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2720 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2721 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2722 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2723 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2725 unsigned int i;
2726 DWORD ttff;
2727 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2728 IWineD3DDeviceImpl *device = stateblock->device;
2729 IWineD3DSurfaceImpl *rt = device->render_targets[0];
2730 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2732 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2734 IWineD3DBaseTextureImpl *texture;
2735 settings->op[i].padding = 0;
2736 if (stateblock->state.texture_states[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE)
2738 settings->op[i].cop = WINED3DTOP_DISABLE;
2739 settings->op[i].aop = WINED3DTOP_DISABLE;
2740 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2741 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2742 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2743 settings->op[i].dst = resultreg;
2744 settings->op[i].tex_type = tex_1d;
2745 settings->op[i].projected = proj_none;
2746 i++;
2747 break;
2750 if ((texture = stateblock->state.textures[i]))
2752 settings->op[i].color_fixup = texture->resource.format->color_fixup;
2753 if (ignore_textype)
2755 settings->op[i].tex_type = tex_1d;
2757 else
2759 switch (texture->baseTexture.target)
2761 case GL_TEXTURE_1D:
2762 settings->op[i].tex_type = tex_1d;
2763 break;
2764 case GL_TEXTURE_2D:
2765 settings->op[i].tex_type = tex_2d;
2766 break;
2767 case GL_TEXTURE_3D:
2768 settings->op[i].tex_type = tex_3d;
2769 break;
2770 case GL_TEXTURE_CUBE_MAP_ARB:
2771 settings->op[i].tex_type = tex_cube;
2772 break;
2773 case GL_TEXTURE_RECTANGLE_ARB:
2774 settings->op[i].tex_type = tex_rect;
2775 break;
2778 } else {
2779 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2780 settings->op[i].tex_type = tex_1d;
2783 cop = stateblock->state.texture_states[i][WINED3DTSS_COLOROP];
2784 aop = stateblock->state.texture_states[i][WINED3DTSS_ALPHAOP];
2786 carg1 = (args[cop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2787 carg2 = (args[cop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2788 carg0 = (args[cop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2790 if (is_invalid_op(&stateblock->state, i, cop, carg1, carg2, carg0))
2792 carg0 = ARG_UNUSED;
2793 carg2 = ARG_UNUSED;
2794 carg1 = WINED3DTA_CURRENT;
2795 cop = WINED3DTOP_SELECTARG1;
2798 if(cop == WINED3DTOP_DOTPRODUCT3) {
2799 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2800 * the color result to the alpha component of the destination
2802 aop = cop;
2803 aarg1 = carg1;
2804 aarg2 = carg2;
2805 aarg0 = carg0;
2807 else
2809 aarg1 = (args[aop] & ARG1) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2810 aarg2 = (args[aop] & ARG2) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2811 aarg0 = (args[aop] & ARG0) ? stateblock->state.texture_states[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2814 if (!i && stateblock->state.textures[0] && stateblock->state.render_states[WINED3DRS_COLORKEYENABLE])
2816 IWineD3DBaseTextureImpl *texture = stateblock->state.textures[0];
2817 GLenum texture_dimensions = texture->baseTexture.target;
2819 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2821 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
2823 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
2825 if (aop == WINED3DTOP_DISABLE)
2827 aarg1 = WINED3DTA_TEXTURE;
2828 aop = WINED3DTOP_SELECTARG1;
2830 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2832 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2834 aarg2 = WINED3DTA_TEXTURE;
2835 aop = WINED3DTOP_MODULATE;
2837 else aarg1 = WINED3DTA_TEXTURE;
2839 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2841 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
2843 aarg1 = WINED3DTA_TEXTURE;
2844 aop = WINED3DTOP_MODULATE;
2846 else aarg2 = WINED3DTA_TEXTURE;
2852 if (is_invalid_op(&stateblock->state, i, aop, aarg1, aarg2, aarg0))
2854 aarg0 = ARG_UNUSED;
2855 aarg2 = ARG_UNUSED;
2856 aarg1 = WINED3DTA_CURRENT;
2857 aop = WINED3DTOP_SELECTARG1;
2860 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
2861 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
2863 ttff = stateblock->state.texture_states[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2864 if (ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3))
2866 settings->op[i].projected = proj_count3;
2867 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2868 settings->op[i].projected = proj_count4;
2869 } else {
2870 settings->op[i].projected = proj_none;
2872 } else {
2873 settings->op[i].projected = proj_none;
2876 settings->op[i].cop = cop;
2877 settings->op[i].aop = aop;
2878 settings->op[i].carg0 = carg0;
2879 settings->op[i].carg1 = carg1;
2880 settings->op[i].carg2 = carg2;
2881 settings->op[i].aarg0 = aarg0;
2882 settings->op[i].aarg1 = aarg1;
2883 settings->op[i].aarg2 = aarg2;
2885 if (stateblock->state.texture_states[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP)
2887 settings->op[i].dst = tempreg;
2888 } else {
2889 settings->op[i].dst = resultreg;
2893 /* Clear unsupported stages */
2894 for(; i < MAX_TEXTURES; i++) {
2895 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2898 if (!stateblock->state.render_states[WINED3DRS_FOGENABLE])
2900 settings->fog = FOG_OFF;
2902 else if (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
2904 if (use_vs(&stateblock->state) || stateblock->state.vertex_declaration->position_transformed)
2906 settings->fog = FOG_LINEAR;
2908 else
2910 switch (stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE])
2912 case WINED3DFOG_NONE:
2913 case WINED3DFOG_LINEAR:
2914 settings->fog = FOG_LINEAR;
2915 break;
2916 case WINED3DFOG_EXP:
2917 settings->fog = FOG_EXP;
2918 break;
2919 case WINED3DFOG_EXP2:
2920 settings->fog = FOG_EXP2;
2921 break;
2925 else
2927 switch (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE])
2929 case WINED3DFOG_LINEAR:
2930 settings->fog = FOG_LINEAR;
2931 break;
2932 case WINED3DFOG_EXP:
2933 settings->fog = FOG_EXP;
2934 break;
2935 case WINED3DFOG_EXP2:
2936 settings->fog = FOG_EXP2;
2937 break;
2940 if (stateblock->state.render_states[WINED3DRS_SRGBWRITEENABLE]
2941 && rt->resource.format->Flags & WINED3DFMT_FLAG_SRGB_WRITE)
2943 settings->sRGB_write = 1;
2944 } else {
2945 settings->sRGB_write = 0;
2947 if (device->vs_clipping || !use_vs(&stateblock->state) || !stateblock->state.render_states[WINED3DRS_CLIPPING]
2948 || !stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE])
2950 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2951 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2952 * if no clipplane is enabled
2954 settings->emul_clipplanes = 0;
2955 } else {
2956 settings->emul_clipplanes = 1;
2960 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2961 const struct ffp_frag_settings *settings)
2963 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2964 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2967 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2969 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2970 * whereas desc points to an extended structure with implementation specific parts. */
2971 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2973 ERR("Failed to insert ffp frag shader.\n");
2977 /* Activates the texture dimension according to the bound D3D texture.
2978 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2979 * Requires the caller to activate the correct unit before
2981 /* GL locking is done by the caller (state handler) */
2982 void texture_activate_dimensions(IWineD3DBaseTextureImpl *texture, const struct wined3d_gl_info *gl_info)
2984 if (texture)
2986 switch (texture->baseTexture.target)
2988 case GL_TEXTURE_2D:
2989 glDisable(GL_TEXTURE_3D);
2990 checkGLcall("glDisable(GL_TEXTURE_3D)");
2991 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2993 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2994 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2996 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2998 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2999 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3001 glEnable(GL_TEXTURE_2D);
3002 checkGLcall("glEnable(GL_TEXTURE_2D)");
3003 break;
3004 case GL_TEXTURE_RECTANGLE_ARB:
3005 glDisable(GL_TEXTURE_2D);
3006 checkGLcall("glDisable(GL_TEXTURE_2D)");
3007 glDisable(GL_TEXTURE_3D);
3008 checkGLcall("glDisable(GL_TEXTURE_3D)");
3009 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3011 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3012 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3014 glEnable(GL_TEXTURE_RECTANGLE_ARB);
3015 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3016 break;
3017 case GL_TEXTURE_3D:
3018 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3020 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3021 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3023 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3025 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3026 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3028 glDisable(GL_TEXTURE_2D);
3029 checkGLcall("glDisable(GL_TEXTURE_2D)");
3030 glEnable(GL_TEXTURE_3D);
3031 checkGLcall("glEnable(GL_TEXTURE_3D)");
3032 break;
3033 case GL_TEXTURE_CUBE_MAP_ARB:
3034 glDisable(GL_TEXTURE_2D);
3035 checkGLcall("glDisable(GL_TEXTURE_2D)");
3036 glDisable(GL_TEXTURE_3D);
3037 checkGLcall("glDisable(GL_TEXTURE_3D)");
3038 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3040 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3041 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3043 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3044 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3045 break;
3047 } else {
3048 glEnable(GL_TEXTURE_2D);
3049 checkGLcall("glEnable(GL_TEXTURE_2D)");
3050 glDisable(GL_TEXTURE_3D);
3051 checkGLcall("glDisable(GL_TEXTURE_3D)");
3052 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3054 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3055 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3057 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3059 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3060 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3062 /* Binding textures is done by samplers. A dummy texture will be bound */
3066 /* GL locking is done by the caller (state handler) */
3067 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3069 DWORD sampler = state - STATE_SAMPLER(0);
3070 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3072 /* No need to enable / disable anything here for unused samplers. The tex_colorop
3073 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3074 * will take care of this business
3076 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3077 if (sampler >= stateblock->state.lowest_disabled_stage) return;
3078 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3080 texture_activate_dimensions(stateblock->state.textures[sampler], context->gl_info);
3083 void *wined3d_rb_alloc(size_t size)
3085 return HeapAlloc(GetProcessHeap(), 0, size);
3088 void *wined3d_rb_realloc(void *ptr, size_t size)
3090 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3093 void wined3d_rb_free(void *ptr)
3095 HeapFree(GetProcessHeap(), 0, ptr);
3098 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3100 const struct ffp_frag_settings *ka = key;
3101 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3103 return memcmp(ka, kb, sizeof(*ka));
3106 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3108 wined3d_rb_alloc,
3109 wined3d_rb_realloc,
3110 wined3d_rb_free,
3111 ffp_frag_program_key_compare,
3114 UINT wined3d_log2i(UINT32 x)
3116 static const UINT l[] =
3118 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3119 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3120 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3121 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3122 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3123 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3124 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3125 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3126 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3127 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3128 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3129 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3130 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3131 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3132 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3133 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3135 UINT32 i;
3137 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3140 /* Set the shader type for this device, depending on the given capabilities
3141 * and the user preferences in wined3d_settings. */
3142 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3144 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3146 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3147 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3149 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3150 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3151 * shaders only on this card. */
3152 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3153 else *vs_selected = SHADER_GLSL;
3155 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3156 else *vs_selected = SHADER_NONE;
3158 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3159 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3160 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3161 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3162 else *ps_selected = SHADER_NONE;
3165 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
3166 const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format *src_format,
3167 const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format *dst_format)
3169 static const struct blit_shader * const blitters[] =
3171 &arbfp_blit,
3172 &ffp_blit,
3173 &cpu_blit,
3175 unsigned int i;
3177 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3179 if (blitters[i]->blit_supported(gl_info, blit_op,
3180 src_rect, src_usage, src_pool, src_format,
3181 dst_rect, dst_usage, dst_pool, dst_format))
3182 return blitters[i];
3185 return NULL;