VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/utils.c@ 37608

最後變更 在這個檔案從37608是 33656,由 vboxsync 提交於 14 年 前

*: rebrand Sun (L)GPL disclaimers

  • 屬性 svn:eol-style 設為 native
檔案大小: 137.7 KB
 
1/*
2 * Utility functions for the WineD3D Library
3 *
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2008 Henri Verbeet
9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
10 * Copyright 2009 Henri Verbeet for CodeWeavers
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27/*
28 * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
29 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
30 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
31 * a choice of LGPL license versions is made available with the language indicating
32 * that LGPLv2 or any later version may be used, or where a choice of which version
33 * of the LGPL is applied is otherwise unspecified.
34 */
35
36#include "config.h"
37#include "wined3d_private.h"
38
39WINE_DEFAULT_DEBUG_CHANNEL(d3d);
40
41struct StaticPixelFormatDesc
42{
43 WINED3DFORMAT format;
44 DWORD alphaMask, redMask, greenMask, blueMask;
45 UINT bpp;
46 short depthSize, stencilSize;
47};
48
49/*****************************************************************************
50 * Pixel format array
51 *
52 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
53 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
54 * high masks do not fit into the 32 bit values needed for ddraw. It is only
55 * used for ddraw mostly, and to figure out if the format has alpha at all, so
56 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
57 * formats are not usable in 2D rendering because ddraw doesn't support them.
58 */
59static const struct StaticPixelFormatDesc formats[] =
60{
61 /* WINED3DFORMAT alphamask redmask greenmask bluemask bpp depth stencil */
62 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
63 /* FourCC formats */
64 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
65 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
66 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
67 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
68 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
69 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
70 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
71 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
72 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
73 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
74 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
75 /* IEEE formats */
76 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
77 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
78 {WINED3DFMT_R32G32B32_FLOAT, 0x0, 0x0, 0x0, 0x0, 12, 0, 0},
79 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0},
80 /* Hmm? */
81 {WINED3DFMT_R8G8_SNORM_Cx, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
82 /* Float */
83 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
84 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
85 {WINED3DFMT_R16G16_SINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
86 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
87 {WINED3DFMT_R16G16B16A16_SINT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
88 /* Palettized formats */
89 {WINED3DFMT_P8_UINT_A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
90 {WINED3DFMT_P8_UINT, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
91 /* Standard ARGB formats. */
92 {WINED3DFMT_B8G8R8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0},
93 {WINED3DFMT_B8G8R8A8_UNORM, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
94 {WINED3DFMT_B8G8R8X8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
95 {WINED3DFMT_B5G6R5_UNORM, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0},
96 {WINED3DFMT_B5G5R5X1_UNORM, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
97 {WINED3DFMT_B5G5R5A1_UNORM, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
98 {WINED3DFMT_B4G4R4A4_UNORM, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
99 {WINED3DFMT_B2G3R3_UNORM, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0},
100 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0},
101 {WINED3DFMT_B2G3R3A8_UNORM, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0},
102 {WINED3DFMT_B4G4R4X4_UNORM, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
103 {WINED3DFMT_R10G10B10A2_UNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
104 {WINED3DFMT_R10G10B10A2_UINT, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
105 {WINED3DFMT_R10G10B10A2_SNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
106 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
107 {WINED3DFMT_R8G8B8A8_UINT, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
108 {WINED3DFMT_R8G8B8X8_UNORM, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
109 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0},
110 {WINED3DFMT_B10G10R10A2_UNORM, 0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0},
111 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0},
112 /* Luminance */
113 {WINED3DFMT_L8_UNORM, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
114 {WINED3DFMT_L8A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
115 {WINED3DFMT_L4A4_UNORM, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0},
116 {WINED3DFMT_L16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
117 /* Bump mapping stuff */
118 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
119 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
120 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
121 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
122 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
123 {WINED3DFMT_R10G11B11_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
124 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0},
125 /* Depth stencil formats */
126 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
127 {WINED3DFMT_D32_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
128 {WINED3DFMT_S1_UINT_D15_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 15, 1},
129 {WINED3DFMT_D24_UNORM_S8_UINT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
130 {WINED3DFMT_X8D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 0},
131 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 4},
132 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
133 {WINED3DFMT_D32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
134 {WINED3DFMT_S8_UINT_D24_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
135 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
136 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
137 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
138 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
139 /* Vendor-specific formats */
140 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
141 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
142 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
143};
144
145struct wined3d_format_base_flags
146{
147 WINED3DFORMAT format;
148 DWORD flags;
149};
150
151static const struct wined3d_format_base_flags format_base_flags[] =
152{
153 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
156 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
157 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
158 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
159 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
160 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
161 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
162 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
163 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
164 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
165 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
166 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
171 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
172 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
173 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
174 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
175 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC},
176 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
177 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
178 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
179 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
181 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
182 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
184 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
185 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
186 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
187};
188
189struct wined3d_format_compression_info
190{
191 WINED3DFORMAT format;
192 UINT block_width;
193 UINT block_height;
194 UINT block_byte_count;
195};
196
197static const struct wined3d_format_compression_info format_compression_info[] =
198{
199 {WINED3DFMT_DXT1, 4, 4, 8},
200 {WINED3DFMT_DXT2, 4, 4, 16},
201 {WINED3DFMT_DXT3, 4, 4, 16},
202 {WINED3DFMT_DXT4, 4, 4, 16},
203 {WINED3DFMT_DXT5, 4, 4, 16},
204 {WINED3DFMT_ATI2N, 1, 1, 1},
205};
206
207struct wined3d_format_vertex_info
208{
209 WINED3DFORMAT format;
210 enum wined3d_ffp_emit_idx emit_idx;
211 GLint component_count;
212 GLenum gl_vtx_type;
213 GLint gl_vtx_format;
214 GLboolean gl_normalized;
215 unsigned int component_size;
216};
217
218static const struct wined3d_format_vertex_info format_vertex_info[] =
219{
220 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
221 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
222 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
223 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
224 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
225 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
226 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
227 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
228 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
229 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
230 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
231 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
232 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
233 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
234 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
235 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
236 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
237};
238
239struct wined3d_format_texture_info
240{
241 WINED3DFORMAT format;
242 GLint gl_internal;
243 GLint gl_srgb_internal;
244 GLint gl_rt_internal;
245 GLint gl_format;
246 GLint gl_type;
247 unsigned int conv_byte_count;
248 unsigned int flags;
249 GL_SupportedExt extension;
250 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
251};
252
253static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
254{
255 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
256 * format+type combination to load it. Thus convert it to A8L8, then load it
257 * with A4L4 internal, but A8L8 format+type
258 */
259 unsigned int x, y;
260 const unsigned char *Source;
261 unsigned char *Dest;
262 UINT outpitch = pitch * 2;
263
264 for(y = 0; y < height; y++) {
265 Source = src + y * pitch;
266 Dest = dst + y * outpitch;
267 for (x = 0; x < width; x++ ) {
268 unsigned char color = (*Source++);
269 /* A */ Dest[1] = (color & 0xf0) << 0;
270 /* L */ Dest[0] = (color & 0x0f) << 4;
271 Dest += 2;
272 }
273 }
274}
275
276static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
277{
278 unsigned int x, y;
279 const WORD *Source;
280
281 for(y = 0; y < height; y++)
282 {
283 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
284 Source = (const WORD *)(src + y * pitch);
285 for (x = 0; x < width; x++ )
286 {
287 short color = (*Source++);
288 unsigned char l = ((color >> 10) & 0xfc);
289 short v = ((color >> 5) & 0x3e);
290 short u = ((color ) & 0x1f);
291 short v_conv = v + 16;
292 short u_conv = u + 16;
293
294 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
295 Dest_s += 1;
296 }
297 }
298}
299
300static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
301{
302 unsigned int x, y;
303 const WORD *Source;
304 unsigned char *Dest;
305 UINT outpitch = (pitch * 3)/2;
306
307 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
308 * fixed function and shaders without further conversion once the surface is
309 * loaded
310 */
311 for(y = 0; y < height; y++) {
312 Source = (const WORD *)(src + y * pitch);
313 Dest = dst + y * outpitch;
314 for (x = 0; x < width; x++ ) {
315 short color = (*Source++);
316 unsigned char l = ((color >> 10) & 0xfc);
317 char v = ((color >> 5) & 0x3e);
318 char u = ((color ) & 0x1f);
319
320 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
321 * and doubles the positive range. Thus shift left only once, gl does the 2nd
322 * shift. GL reads a signed value and converts it into an unsigned value.
323 */
324 /* M */ Dest[2] = l << 1;
325
326 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
327 * from 5 bit values to 8 bit values.
328 */
329 /* V */ Dest[1] = v << 3;
330 /* U */ Dest[0] = u << 3;
331 Dest += 3;
332 }
333 }
334}
335
336static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
337{
338 unsigned int x, y;
339 const short *Source;
340 unsigned char *Dest;
341 UINT outpitch = (pitch * 3)/2;
342
343 for(y = 0; y < height; y++)
344 {
345 Source = (const short *)(src + y * pitch);
346 Dest = dst + y * outpitch;
347 for (x = 0; x < width; x++ )
348 {
349 long color = (*Source++);
350 /* B */ Dest[0] = 0xff;
351 /* G */ Dest[1] = (color >> 8) + 128; /* V */
352 /* R */ Dest[2] = (color) + 128; /* U */
353 Dest += 3;
354 }
355 }
356}
357
358static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
359{
360 unsigned int x, y;
361 const DWORD *Source;
362 unsigned char *Dest;
363
364 /* Doesn't work correctly with the fixed function pipeline, but can work in
365 * shaders if the shader is adjusted. (There's no use for this format in gl's
366 * standard fixed function pipeline anyway).
367 */
368 for(y = 0; y < height; y++)
369 {
370 Source = (const DWORD *)(src + y * pitch);
371 Dest = dst + y * pitch;
372 for (x = 0; x < width; x++ )
373 {
374 long color = (*Source++);
375 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
376 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
377 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
378 Dest += 4;
379 }
380 }
381}
382
383static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
384{
385 unsigned int x, y;
386 const DWORD *Source;
387 unsigned char *Dest;
388
389 /* This implementation works with the fixed function pipeline and shaders
390 * without further modification after converting the surface.
391 */
392 for(y = 0; y < height; y++)
393 {
394 Source = (const DWORD *)(src + y * pitch);
395 Dest = dst + y * pitch;
396 for (x = 0; x < width; x++ )
397 {
398 long color = (*Source++);
399 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
400 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
401 /* U */ Dest[0] = (color & 0xff); /* U */
402 /* I */ Dest[3] = 255; /* X */
403 Dest += 4;
404 }
405 }
406}
407
408static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
409{
410 unsigned int x, y;
411 const DWORD *Source;
412 unsigned char *Dest;
413
414 for(y = 0; y < height; y++)
415 {
416 Source = (const DWORD *)(src + y * pitch);
417 Dest = dst + y * pitch;
418 for (x = 0; x < width; x++ )
419 {
420 long color = (*Source++);
421 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
422 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
423 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
424 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
425 Dest += 4;
426 }
427 }
428}
429
430static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
431{
432 unsigned int x, y;
433 const DWORD *Source;
434 unsigned short *Dest;
435 UINT outpitch = (pitch * 3)/2;
436
437 for(y = 0; y < height; y++)
438 {
439 Source = (const DWORD *)(src + y * pitch);
440 Dest = (unsigned short *) (dst + y * outpitch);
441 for (x = 0; x < width; x++ )
442 {
443 DWORD color = (*Source++);
444 /* B */ Dest[0] = 0xffff;
445 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
446 /* R */ Dest[2] = (color ) + 32768; /* U */
447 Dest += 3;
448 }
449 }
450}
451
452static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
453{
454 unsigned int x, y;
455 const WORD *Source;
456 WORD *Dest;
457 UINT outpitch = (pitch * 3)/2;
458
459 for(y = 0; y < height; y++)
460 {
461 Source = (const WORD *)(src + y * pitch);
462 Dest = (WORD *) (dst + y * outpitch);
463 for (x = 0; x < width; x++ )
464 {
465 WORD green = (*Source++);
466 WORD red = (*Source++);
467 Dest[0] = green;
468 Dest[1] = red;
469 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
470 * shader overwrites it anyway
471 */
472 Dest[2] = 0xffff;
473 Dest += 3;
474 }
475 }
476}
477
478static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
479{
480 unsigned int x, y;
481 const float *Source;
482 float *Dest;
483 UINT outpitch = (pitch * 3)/2;
484
485 for(y = 0; y < height; y++)
486 {
487 Source = (const float *)(src + y * pitch);
488 Dest = (float *) (dst + y * outpitch);
489 for (x = 0; x < width; x++ )
490 {
491 float green = (*Source++);
492 float red = (*Source++);
493 Dest[0] = green;
494 Dest[1] = red;
495 Dest[2] = 1.0f;
496 Dest += 3;
497 }
498 }
499}
500
501static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
502{
503 unsigned int x, y;
504 UINT outpitch = pitch * 2;
505
506 for (y = 0; y < height; ++y)
507 {
508 const WORD *source = (const WORD *)(src + y * pitch);
509 DWORD *dest = (DWORD *)(dst + y * outpitch);
510
511 for (x = 0; x < width; ++x)
512 {
513 /* The depth data is normalized, so needs to be scaled,
514 * the stencil data isn't. Scale depth data by
515 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
516 WORD d15 = source[x] >> 1;
517 DWORD d24 = (d15 << 9) + (d15 >> 6);
518 dest[x] = (d24 << 8) | (source[x] & 0x1);
519 }
520 }
521}
522
523static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
524{
525 unsigned int x, y;
526
527 for (y = 0; y < height; ++y)
528 {
529 const DWORD *source = (const DWORD *)(src + y * pitch);
530 DWORD *dest = (DWORD *)(dst + y * pitch);
531
532 for (x = 0; x < width; ++x)
533 {
534 /* Just need to clear out the X4 part. */
535 dest[x] = source[x] & ~0xf0;
536 }
537 }
538}
539
540static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
541{
542 unsigned int x, y;
543 UINT outpitch = pitch * 2;
544
545 for (y = 0; y < height; ++y)
546 {
547 const DWORD *source = (const DWORD *)(src + y * pitch);
548 float *dest_f = (float *)(dst + y * outpitch);
549 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
550
551 for (x = 0; x < width; ++x)
552 {
553 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
554 dest_s[x * 2 + 1] = source[x] & 0xff;
555 }
556 }
557}
558
559static const struct wined3d_format_texture_info format_texture_info[] =
560{
561 /* WINED3DFORMAT internal srgbInternal rtInternal
562 format type
563 flags
564 extension */
565 /* FourCC formats */
566 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
567 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
568 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
569 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
570 * endian machine
571 */
572 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
573 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
574 WINED3DFMT_FLAG_FILTERING,
575 WINED3D_GL_EXT_NONE, NULL},
576 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
577 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
578 WINED3DFMT_FLAG_FILTERING,
579 APPLE_YCBCR_422, NULL},
580 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
581 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
582 WINED3DFMT_FLAG_FILTERING,
583 WINED3D_GL_EXT_NONE, NULL},
584 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
585 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
586 WINED3DFMT_FLAG_FILTERING,
587 APPLE_YCBCR_422, NULL},
588 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
589 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
590 WINED3DFMT_FLAG_FILTERING,
591 WINED3D_GL_EXT_NONE, NULL},
592 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
593 GL_RGBA, GL_UNSIGNED_BYTE, 0,
594 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
595 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
596 {WINED3DFMT_DXT2, 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,
599 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
600 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
601 GL_RGBA, GL_UNSIGNED_BYTE, 0,
602 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
603 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
604 {WINED3DFMT_DXT4, 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,
607 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
608 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
609 GL_RGBA, GL_UNSIGNED_BYTE, 0,
610 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
611 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
612 /* IEEE formats */
613 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
614 GL_RED, GL_FLOAT, 0,
615 WINED3DFMT_FLAG_RENDERTARGET,
616 ARB_TEXTURE_FLOAT, NULL},
617 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
618 GL_RED, GL_FLOAT, 0,
619 WINED3DFMT_FLAG_RENDERTARGET,
620 ARB_TEXTURE_RG, NULL},
621 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
622 GL_RGB, GL_FLOAT, 12,
623 WINED3DFMT_FLAG_RENDERTARGET,
624 ARB_TEXTURE_FLOAT, &convert_r32g32_float},
625 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
626 GL_RG, GL_FLOAT, 0,
627 WINED3DFMT_FLAG_RENDERTARGET,
628 ARB_TEXTURE_RG, NULL},
629 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
630 GL_RGBA, GL_FLOAT, 0,
631 WINED3DFMT_FLAG_RENDERTARGET,
632 ARB_TEXTURE_FLOAT, NULL},
633 /* Float */
634 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
635 GL_RED, GL_HALF_FLOAT_ARB, 0,
636 WINED3DFMT_FLAG_RENDERTARGET,
637 ARB_TEXTURE_FLOAT, NULL},
638 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
639 GL_RED, GL_HALF_FLOAT_ARB, 0,
640 WINED3DFMT_FLAG_RENDERTARGET,
641 ARB_TEXTURE_RG, NULL},
642 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
643 GL_RGB, GL_HALF_FLOAT_ARB, 6,
644 WINED3DFMT_FLAG_RENDERTARGET,
645 ARB_TEXTURE_FLOAT, &convert_r16g16},
646 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
647 GL_RG, GL_HALF_FLOAT_ARB, 0,
648 WINED3DFMT_FLAG_RENDERTARGET,
649 ARB_TEXTURE_RG, NULL},
650 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
651 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
652 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
653 ARB_TEXTURE_FLOAT, NULL},
654 /* Palettized formats */
655 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
656 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
657 0,
658 ARB_FRAGMENT_PROGRAM, NULL},
659 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
660 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
661 0,
662 EXT_PALETTED_TEXTURE, NULL},
663 /* Standard ARGB formats */
664 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
665 GL_BGR, GL_UNSIGNED_BYTE, 0,
666 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
667 WINED3D_GL_EXT_NONE, NULL},
668 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
669 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
670 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
671 WINED3D_GL_EXT_NONE, NULL},
672 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
673 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
674 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
675 WINED3D_GL_EXT_NONE, NULL},
676 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
677 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
678 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
679 WINED3D_GL_EXT_NONE, NULL},
680 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
681 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
682 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
683 WINED3D_GL_EXT_NONE, NULL},
684 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
685 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
686 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
687 WINED3D_GL_EXT_NONE, NULL},
688 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
689 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
690 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
691 WINED3D_GL_EXT_NONE, NULL},
692 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
693 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
694 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
695 WINED3D_GL_EXT_NONE, NULL},
696 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
697 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
698 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
699 WINED3D_GL_EXT_NONE, NULL},
700 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
701 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
702 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
703 WINED3D_GL_EXT_NONE, NULL},
704 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
705 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
706 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
707 WINED3D_GL_EXT_NONE, NULL},
708 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
709 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
710 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
711 WINED3D_GL_EXT_NONE, NULL},
712 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
713 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
714 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
715 WINED3D_GL_EXT_NONE, NULL},
716 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
717 GL_RGB, GL_UNSIGNED_SHORT, 6,
718 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
719 WINED3D_GL_EXT_NONE, &convert_r16g16},
720 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
721 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
722 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
723 WINED3D_GL_EXT_NONE, NULL},
724 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
725 GL_RGBA, GL_UNSIGNED_SHORT, 0,
726 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
727 WINED3D_GL_EXT_NONE, NULL},
728 /* Luminance */
729 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
730 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
731 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
732 WINED3D_GL_EXT_NONE, NULL},
733 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
734 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
735 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
736 WINED3D_GL_EXT_NONE, NULL},
737 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
738 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
739 0,
740 WINED3D_GL_EXT_NONE, &convert_l4a4_unorm},
741 /* Bump mapping stuff */
742 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
743 GL_BGR, GL_UNSIGNED_BYTE, 3,
744 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
745 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm},
746 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
747 GL_DSDT_NV, GL_BYTE, 0,
748 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
749 NV_TEXTURE_SHADER, NULL},
750 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
751 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
752 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
753 WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm},
754 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
755 GL_DSDT_MAG_NV, GL_BYTE, 3,
756 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
757 NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv},
758 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
759 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
760 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
761 WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm},
762 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
763 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
764 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
765 NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv},
766 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
767 GL_BGRA, GL_UNSIGNED_BYTE, 4,
768 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
769 WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm},
770 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
771 GL_RGBA, GL_BYTE, 0,
772 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
773 NV_TEXTURE_SHADER, NULL},
774 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
775 GL_BGR, GL_UNSIGNED_SHORT, 6,
776 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
777 WINED3D_GL_EXT_NONE, &convert_r16g16_snorm},
778 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
779 GL_HILO_NV, GL_SHORT, 0,
780 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
781 NV_TEXTURE_SHADER, NULL},
782 /* Depth stencil formats */
783 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
784 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
785 WINED3DFMT_FLAG_DEPTH,
786 ARB_DEPTH_TEXTURE, NULL},
787 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
788 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
789 WINED3DFMT_FLAG_DEPTH,
790 ARB_DEPTH_TEXTURE, NULL},
791 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
792 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
793 WINED3DFMT_FLAG_DEPTH,
794 ARB_DEPTH_TEXTURE, NULL},
795 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
796 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
797 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
798 EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm},
799 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
800 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
801 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
802 ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm},
803 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
804 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
805 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
806 ARB_DEPTH_TEXTURE, NULL},
807 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
808 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
809 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
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 | WINED3DFMT_FLAG_STENCIL,
814 ARB_FRAMEBUFFER_OBJECT, NULL},
815 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
816 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
817 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
818 ARB_DEPTH_TEXTURE, NULL},
819 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
820 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
821 WINED3DFMT_FLAG_DEPTH,
822 ARB_DEPTH_TEXTURE, NULL},
823 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
824 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
825 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
826 EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm},
827 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
828 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
829 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
830 ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm},
831 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
832 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
833 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
834 ARB_DEPTH_TEXTURE, NULL},
835 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
836 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
837 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
838 WINED3D_GL_EXT_NONE, NULL},
839 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
840 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
841 WINED3DFMT_FLAG_DEPTH,
842 ARB_DEPTH_BUFFER_FLOAT, NULL},
843 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
844 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
845 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
846 ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float},
847 /* Vendor-specific formats */
848 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
849 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
850 0,
851 ATI_TEXTURE_COMPRESSION_3DC, NULL},
852 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, 0,
853 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
854 0,
855 EXT_TEXTURE_COMPRESSION_RGTC, NULL},
856};
857
858static inline int getFmtIdx(WINED3DFORMAT fmt) {
859 /* First check if the format is at the position of its value.
860 * This will catch the argb formats before the loop is entered
861 */
862 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
863 return fmt;
864 } else {
865 unsigned int i;
866 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
867 if(formats[i].format == fmt) {
868 return i;
869 }
870 }
871 }
872 return -1;
873}
874
875static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
876{
877 UINT format_count = sizeof(formats) / sizeof(*formats);
878 UINT i;
879
880 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->gl_formats));
881 if (!gl_info->gl_formats)
882 {
883 ERR("Failed to allocate memory.\n");
884 return FALSE;
885 }
886
887 for (i = 0; i < format_count; ++i)
888 {
889 struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
890 desc->format = formats[i].format;
891 desc->red_mask = formats[i].redMask;
892 desc->green_mask = formats[i].greenMask;
893 desc->blue_mask = formats[i].blueMask;
894 desc->alpha_mask = formats[i].alphaMask;
895 desc->byte_count = formats[i].bpp;
896 desc->depth_size = formats[i].depthSize;
897 desc->stencil_size = formats[i].stencilSize;
898 }
899
900 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
901 {
902 int fmt_idx = getFmtIdx(format_base_flags[i].format);
903
904 if (fmt_idx == -1)
905 {
906 ERR("Format %s (%#x) not found.\n",
907 debug_d3dformat(format_base_flags[i].format), format_base_flags[i].format);
908 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
909 return FALSE;
910 }
911
912 gl_info->gl_formats[fmt_idx].Flags |= format_base_flags[i].flags;
913 }
914
915 return TRUE;
916}
917
918static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
919{
920 unsigned int i;
921
922 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
923 {
924 struct wined3d_format_desc *format_desc;
925 int fmt_idx = getFmtIdx(format_compression_info[i].format);
926
927 if (fmt_idx == -1)
928 {
929 ERR("Format %s (%#x) not found.\n",
930 debug_d3dformat(format_compression_info[i].format), format_compression_info[i].format);
931 return FALSE;
932 }
933
934 format_desc = &gl_info->gl_formats[fmt_idx];
935 format_desc->block_width = format_compression_info[i].block_width;
936 format_desc->block_height = format_compression_info[i].block_height;
937 format_desc->block_byte_count = format_compression_info[i].block_byte_count;
938 format_desc->Flags |= WINED3DFMT_FLAG_COMPRESSED;
939 }
940
941 return TRUE;
942}
943
944/* Context activation is done by the caller. */
945static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format_desc *format_desc)
946{
947 /* Check if the default internal format is supported as a frame buffer
948 * target, otherwise fall back to the render target internal.
949 *
950 * Try to stick to the standard format if possible, this limits precision differences. */
951 GLenum status;
952 GLuint tex;
953
954 ENTER_GL();
955
956 while(glGetError());
957 glDisable(GL_BLEND);
958
959 glGenTextures(1, &tex);
960 glBindTexture(GL_TEXTURE_2D, tex);
961
962 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glInternal, 16, 16, 0,
963 format_desc->glFormat, format_desc->glType, NULL);
964 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
965 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
966
967 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
968
969 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
970 checkGLcall("Framebuffer format check");
971
972 if (status == GL_FRAMEBUFFER_COMPLETE)
973 {
974 TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(format_desc->format));
975 format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
976 format_desc->rtInternal = format_desc->glInternal;
977 }
978 else
979 {
980 if (!format_desc->rtInternal)
981 {
982 if (format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)
983 {
984 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
985 " and no fallback specified.\n", debug_d3dformat(format_desc->format));
986 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
987 }
988 else
989 {
990 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format_desc->format));
991 }
992 format_desc->rtInternal = format_desc->glInternal;
993 }
994 else
995 {
996 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
997 debug_d3dformat(format_desc->format));
998
999 while(glGetError());
1000
1001 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1002
1003 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->rtInternal, 16, 16, 0,
1004 format_desc->glFormat, format_desc->glType, NULL);
1005 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1006 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1007
1008 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1009
1010 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1011 checkGLcall("Framebuffer format check");
1012
1013 if (status == GL_FRAMEBUFFER_COMPLETE)
1014 {
1015 TRACE("Format %s rtInternal format is supported as FBO color attachment\n",
1016 debug_d3dformat(format_desc->format));
1017 }
1018 else
1019 {
1020 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1021 debug_d3dformat(format_desc->format));
1022 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1023 }
1024 }
1025 }
1026
1027 if (status == GL_FRAMEBUFFER_COMPLETE && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1028 {
1029 GLuint rb;
1030
1031 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1032 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1033 {
1034 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1035 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1036 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1037 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1038 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1039 checkGLcall("RB attachment");
1040 }
1041
1042 glEnable(GL_BLEND);
1043 glClear(GL_COLOR_BUFFER_BIT);
1044 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1045 {
1046 while(glGetError());
1047 TRACE("Format doesn't support post-pixelshader blending.\n");
1048 format_desc->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1049 }
1050
1051 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1052 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1053 {
1054 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1055 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1056 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1057 checkGLcall("RB cleanup");
1058 }
1059 }
1060
1061 glDeleteTextures(1, &tex);
1062
1063 LEAVE_GL();
1064}
1065
1066/* Context activation is done by the caller. */
1067static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1068{
1069 unsigned int i;
1070 GLuint fbo;
1071
1072 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1073 {
1074 ENTER_GL();
1075
1076 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1077 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1078
1079 LEAVE_GL();
1080 }
1081
1082 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1083 {
1084 struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
1085
1086 if (!desc->glInternal) continue;
1087
1088 if (desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1089 {
1090 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1091 debug_d3dformat(desc->format));
1092 continue;
1093 }
1094
1095 if (desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
1096 {
1097 TRACE("Skipping format %s because it's a compressed format.\n",
1098 debug_d3dformat(desc->format));
1099 continue;
1100 }
1101
1102 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1103 {
1104 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc->format));
1105 check_fbo_compat(gl_info, desc);
1106 }
1107 else
1108 {
1109 desc->rtInternal = desc->glInternal;
1110 }
1111 }
1112
1113 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1114 {
1115 ENTER_GL();
1116
1117 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1118
1119 LEAVE_GL();
1120 }
1121}
1122
1123static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1124{
1125 unsigned int i;
1126
1127 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1128 {
1129 int fmt_idx = getFmtIdx(format_texture_info[i].format);
1130 struct wined3d_format_desc *desc;
1131
1132 if (fmt_idx == -1)
1133 {
1134 ERR("Format %s (%#x) not found.\n",
1135 debug_d3dformat(format_texture_info[i].format), format_texture_info[i].format);
1136 return FALSE;
1137 }
1138
1139 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1140
1141 desc = &gl_info->gl_formats[fmt_idx];
1142 desc->glInternal = format_texture_info[i].gl_internal;
1143 desc->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1144 desc->rtInternal = format_texture_info[i].gl_rt_internal;
1145 desc->glFormat = format_texture_info[i].gl_format;
1146 desc->glType = format_texture_info[i].gl_type;
1147 desc->color_fixup = COLOR_FIXUP_IDENTITY;
1148 desc->Flags |= format_texture_info[i].flags;
1149 desc->heightscale = 1.0f;
1150
1151 /* Texture conversion stuff */
1152 desc->convert = format_texture_info[i].convert;
1153 desc->conv_byte_count = format_texture_info[i].conv_byte_count;
1154 }
1155
1156 return TRUE;
1157}
1158
1159static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1160{
1161 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1162 c1 >>= 8; c2 >>= 8;
1163 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1164 c1 >>= 8; c2 >>= 8;
1165 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1166 c1 >>= 8; c2 >>= 8;
1167 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1168 return TRUE;
1169}
1170
1171/* A context is provided by the caller */
1172static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1173{
1174 GLuint tex, fbo, buffer;
1175 const DWORD data[] = {0x00000000, 0xffffffff};
1176 DWORD readback[16 * 1];
1177 BOOL ret = FALSE;
1178
1179 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1180 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1181 * falling back to software. If this changes in the future this code will get fooled and
1182 * apps might hit the software path due to incorrectly advertised caps.
1183 *
1184 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1185 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1186 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1187 */
1188
1189 ENTER_GL();
1190 while(glGetError());
1191
1192 glGenTextures(1, &buffer);
1193 glBindTexture(GL_TEXTURE_2D, buffer);
1194 memset(readback, 0x7e, sizeof(readback));
1195 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1196 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1197 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1198 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1199 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1200 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1201
1202 glGenTextures(1, &tex);
1203 glBindTexture(GL_TEXTURE_2D, tex);
1204 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1205 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1206 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1207 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1208 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1209 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1210 glEnable(GL_TEXTURE_2D);
1211
1212 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1213 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1214 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1215 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1216
1217 glViewport(0, 0, 16, 1);
1218 glDisable(GL_LIGHTING);
1219 glMatrixMode(GL_MODELVIEW);
1220 glLoadIdentity();
1221 glMatrixMode(GL_PROJECTION);
1222 glLoadIdentity();
1223
1224 glClearColor(0, 1, 0, 0);
1225 glClear(GL_COLOR_BUFFER_BIT);
1226
1227 glBegin(GL_TRIANGLE_STRIP);
1228 glTexCoord2f(0.0, 0.0);
1229 glVertex2f(-1.0f, -1.0f);
1230 glTexCoord2f(1.0, 0.0);
1231 glVertex2f(1.0f, -1.0f);
1232 glTexCoord2f(0.0, 1.0);
1233 glVertex2f(-1.0f, 1.0f);
1234 glTexCoord2f(1.0, 1.0);
1235 glVertex2f(1.0f, 1.0f);
1236 glEnd();
1237
1238 glBindTexture(GL_TEXTURE_2D, buffer);
1239 memset(readback, 0x7f, sizeof(readback));
1240 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1241 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1242 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1243 {
1244 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1245 readback[6], readback[9]);
1246 ret = FALSE;
1247 }
1248 else
1249 {
1250 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1251 readback[6], readback[9]);
1252 ret = TRUE;
1253 }
1254
1255 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1256 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1257 glDeleteTextures(1, &tex);
1258 glDeleteTextures(1, &buffer);
1259
1260 if(glGetError())
1261 {
1262 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1263 ret = FALSE;
1264 }
1265 LEAVE_GL();
1266 return ret;
1267}
1268
1269static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1270{
1271 struct wined3d_format_desc *desc;
1272 unsigned int fmt_idx, i;
1273 WINED3DFORMAT fmts16[] = {
1274 WINED3DFMT_R16_FLOAT,
1275 WINED3DFMT_R16G16_FLOAT,
1276 WINED3DFMT_R16G16B16A16_FLOAT,
1277 };
1278 BOOL filtered;
1279
1280 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1281 {
1282 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1283 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1284 {
1285 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1286 filtered = TRUE;
1287 }
1288 else if (gl_info->limits.glsl_varyings > 44)
1289 {
1290 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1291 filtered = TRUE;
1292 }
1293 else
1294 {
1295 TRACE("Assuming no float16 blending\n");
1296 filtered = FALSE;
1297 }
1298
1299 if(filtered)
1300 {
1301 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1302 {
1303 fmt_idx = getFmtIdx(fmts16[i]);
1304 gl_info->gl_formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
1305 }
1306 }
1307 return;
1308 }
1309
1310 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1311 {
1312 fmt_idx = getFmtIdx(fmts16[i]);
1313 desc = &gl_info->gl_formats[fmt_idx];
1314 if(!desc->glInternal) continue; /* Not supported by GL */
1315
1316 filtered = check_filter(gl_info, gl_info->gl_formats[fmt_idx].glInternal);
1317 if(filtered)
1318 {
1319 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1320 desc->Flags |= WINED3DFMT_FLAG_FILTERING;
1321 }
1322 else
1323 {
1324 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1325 }
1326 }
1327}
1328
1329static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1330{
1331 int idx;
1332
1333 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1334 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1335 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1336
1337 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1338 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1339 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1340
1341 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1342 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1343 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1344
1345 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1346 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1347 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1348
1349 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1350 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1351 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1352
1353 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1354 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1355 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1356 * the only driver that implements it(fglrx) has a buggy implementation.
1357 *
1358 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1359 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1360 * conversion for this format.
1361 */
1362 if (!gl_info->supported[NV_TEXTURE_SHADER])
1363 {
1364 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1365 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1366 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1367 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1368 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1369 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1370 }
1371 else
1372 {
1373 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1374 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1375 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1376
1377 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1378 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1379 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1380 }
1381
1382 if (!gl_info->supported[NV_TEXTURE_SHADER])
1383 {
1384 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1385 * with each other
1386 */
1387 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1388 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1389 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1390 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1391 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1392 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1393 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1394 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1395 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1396 }
1397 else
1398 {
1399 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1400 * are converted at surface loading time, but they do not need any modification in
1401 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1402 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1403 */
1404 }
1405
1406 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1407 {
1408 idx = getFmtIdx(WINED3DFMT_ATI2N);
1409 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1410 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1411 }
1412 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1413 {
1414 idx = getFmtIdx(WINED3DFMT_ATI2N);
1415 gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
1416 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1417 }
1418
1419 if (!gl_info->supported[APPLE_YCBCR_422])
1420 {
1421 idx = getFmtIdx(WINED3DFMT_YUY2);
1422 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1423
1424 idx = getFmtIdx(WINED3DFMT_UYVY);
1425 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1426 }
1427
1428 idx = getFmtIdx(WINED3DFMT_YV12);
1429 gl_info->gl_formats[idx].heightscale = 1.5f;
1430 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1431
1432 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1433 {
1434 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1435 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1436 }
1437
1438 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1439 {
1440 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1441 gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
1442 }
1443
1444 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1445 {
1446 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1447 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1448 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1449 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1450
1451 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1452 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1453 }
1454}
1455
1456static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1457{
1458 unsigned int i;
1459
1460 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1461 {
1462 struct wined3d_format_desc *format_desc;
1463 int fmt_idx = getFmtIdx(format_vertex_info[i].format);
1464
1465 if (fmt_idx == -1)
1466 {
1467 ERR("Format %s (%#x) not found.\n",
1468 debug_d3dformat(format_vertex_info[i].format), format_vertex_info[i].format);
1469 return FALSE;
1470 }
1471
1472 format_desc = &gl_info->gl_formats[fmt_idx];
1473 format_desc->emit_idx = format_vertex_info[i].emit_idx;
1474 format_desc->component_count = format_vertex_info[i].component_count;
1475 format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1476 format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1477 format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
1478 format_desc->component_size = format_vertex_info[i].component_size;
1479 }
1480
1481 return TRUE;
1482}
1483
1484BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1485{
1486 if (!init_format_base_info(gl_info)) return FALSE;
1487
1488 if (!init_format_compression_info(gl_info))
1489 {
1490 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1491 gl_info->gl_formats = NULL;
1492 return FALSE;
1493 }
1494
1495 return TRUE;
1496}
1497
1498/* Context activation is done by the caller. */
1499BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1500{
1501 if (!init_format_base_info(gl_info)) return FALSE;
1502
1503 if (!init_format_compression_info(gl_info)) goto fail;
1504 if (!init_format_texture_info(gl_info)) goto fail;
1505 if (!init_format_vertex_info(gl_info)) goto fail;
1506
1507 apply_format_fixups(gl_info);
1508 init_format_fbo_compat_info(gl_info);
1509 init_format_filter_info(gl_info, vendor);
1510
1511 return TRUE;
1512
1513fail:
1514 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1515 gl_info->gl_formats = NULL;
1516 return FALSE;
1517}
1518
1519const struct wined3d_format_desc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info)
1520{
1521 int idx = getFmtIdx(fmt);
1522
1523 if(idx == -1) {
1524 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
1525 /* Get the caller a valid pointer */
1526 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1527 }
1528
1529 return &gl_info->gl_formats[idx];
1530}
1531
1532/*****************************************************************************
1533 * Trace formatting of useful values
1534 */
1535const char* debug_d3dformat(WINED3DFORMAT fmt) {
1536 switch (fmt) {
1537#define FMT_TO_STR(fmt) case fmt: return #fmt
1538 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1539 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1540 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1541 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1542 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1543 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1544 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1545 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1546 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1547 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1548 FMT_TO_STR(WINED3DFMT_P8_UINT);
1549 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1550 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1551 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1552 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1553 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1554 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1555 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1556 FMT_TO_STR(WINED3DFMT_UYVY);
1557 FMT_TO_STR(WINED3DFMT_YUY2);
1558 FMT_TO_STR(WINED3DFMT_YV12);
1559 FMT_TO_STR(WINED3DFMT_DXT1);
1560 FMT_TO_STR(WINED3DFMT_DXT2);
1561 FMT_TO_STR(WINED3DFMT_DXT3);
1562 FMT_TO_STR(WINED3DFMT_DXT4);
1563 FMT_TO_STR(WINED3DFMT_DXT5);
1564 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1565 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1566 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1567 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1568 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1569 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1570 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1571 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1572 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1573 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1574 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1575 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1576 FMT_TO_STR(WINED3DFMT_ATI2N);
1577 FMT_TO_STR(WINED3DFMT_NVHU);
1578 FMT_TO_STR(WINED3DFMT_NVHS);
1579 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1580 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1581 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1582 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1583 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1584 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1585 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1586 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1587 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1588 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1589 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1590 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1591 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1592 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1593 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1594 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1595 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1596 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1597 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1598 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1599 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1600 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1601 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1602 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1603 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1604 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1605 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1606 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1607 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1608 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1609 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1610 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1611 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1612 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1613 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1614 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1615 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1616 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1617 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1618 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1619 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1620 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1621 FMT_TO_STR(WINED3DFMT_R32_UINT);
1622 FMT_TO_STR(WINED3DFMT_R32_SINT);
1623 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1624 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1625 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1626 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1627 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1628 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1629 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1630 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1631 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1632 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1633 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1634 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1635 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1636 FMT_TO_STR(WINED3DFMT_R16_UINT);
1637 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1638 FMT_TO_STR(WINED3DFMT_R16_SINT);
1639 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1640 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1641 FMT_TO_STR(WINED3DFMT_R8_UINT);
1642 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1643 FMT_TO_STR(WINED3DFMT_R8_SINT);
1644 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1645 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1646 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1647 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1648 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1649 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1650 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1651 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1652 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1653 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1654 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1655 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1656 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1657 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1658 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1659 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1660 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1661 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1662 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1663 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1664 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1665 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1666 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1667 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1668#undef FMT_TO_STR
1669 default:
1670 {
1671 char fourcc[5];
1672 fourcc[0] = (char)(fmt);
1673 fourcc[1] = (char)(fmt >> 8);
1674 fourcc[2] = (char)(fmt >> 16);
1675 fourcc[3] = (char)(fmt >> 24);
1676 fourcc[4] = 0;
1677 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
1678 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
1679 else
1680 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
1681 }
1682 return "unrecognized";
1683 }
1684}
1685
1686const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
1687 switch (devtype) {
1688#define DEVTYPE_TO_STR(dev) case dev: return #dev
1689 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1690 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1691 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1692#undef DEVTYPE_TO_STR
1693 default:
1694 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1695 return "unrecognized";
1696 }
1697}
1698
1699const char *debug_d3dusage(DWORD usage)
1700{
1701 char buf[284];
1702
1703 buf[0] = '\0';
1704#define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1705 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1706 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1707 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1708 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1709 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1710 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1711 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1712 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1713 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1714 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1715 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1716#undef WINED3DUSAGE_TO_STR
1717 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1718
1719 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1720}
1721
1722const char *debug_d3dusagequery(DWORD usagequery)
1723{
1724 char buf[238];
1725
1726 buf[0] = '\0';
1727#define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1728 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1729 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1730 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1731 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1732 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1733 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1734 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1735#undef WINED3DUSAGEQUERY_TO_STR
1736 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1737
1738 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1739}
1740
1741const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1742 switch (method) {
1743#define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1744 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1745 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1746 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1747 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1748 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1749 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1750 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1751#undef WINED3DDECLMETHOD_TO_STR
1752 default:
1753 FIXME("Unrecognized %u declaration method!\n", method);
1754 return "unrecognized";
1755 }
1756}
1757
1758const char* debug_d3ddeclusage(BYTE usage) {
1759 switch (usage) {
1760#define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1761 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1762 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1763 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1764 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1765 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1766 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1767 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1768 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1769 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1770 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1771 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1772 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1773 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1774 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1775#undef WINED3DDECLUSAGE_TO_STR
1776 default:
1777 FIXME("Unrecognized %u declaration usage!\n", usage);
1778 return "unrecognized";
1779 }
1780}
1781
1782const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1783 switch (res) {
1784#define RES_TO_STR(res) case res: return #res
1785 RES_TO_STR(WINED3DRTYPE_SURFACE);
1786 RES_TO_STR(WINED3DRTYPE_VOLUME);
1787 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1788 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1789 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1790 RES_TO_STR(WINED3DRTYPE_BUFFER);
1791#undef RES_TO_STR
1792 default:
1793 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1794 return "unrecognized";
1795 }
1796}
1797
1798const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1799 switch (PrimitiveType) {
1800#define PRIM_TO_STR(prim) case prim: return #prim
1801 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1802 PRIM_TO_STR(WINED3DPT_POINTLIST);
1803 PRIM_TO_STR(WINED3DPT_LINELIST);
1804 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1805 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1806 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1807 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1808 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1809 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1810 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1811 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1812#undef PRIM_TO_STR
1813 default:
1814 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1815 return "unrecognized";
1816 }
1817}
1818
1819const char* debug_d3drenderstate(DWORD state) {
1820 switch (state) {
1821#define D3DSTATE_TO_STR(u) case u: return #u
1822 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1823 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1824 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1825 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1826 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1827 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1828 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1829 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1830 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1831 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1832 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1833 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1834 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1835 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1836 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1837 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1838 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1839 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1840 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1841 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1842 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1843 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1844 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1845 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1846 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1847 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1848 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1849 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1850 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1851 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1852 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1853 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1854 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1855 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1856 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1857 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1858 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1859 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1860 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1861 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1862 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1863 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1864 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1865 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1866 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1867 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1868 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1869 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1870 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1871 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1872 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1873 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1874 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1875 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1876 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1877 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1878 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1879 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1880 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1881 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1882 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1883 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1884 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1885 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1886 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1887 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1888 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1889 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1890 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1891 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1892 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1893 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1894 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1895 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1896 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1897 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1898 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1899 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1900 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1901 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1902 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1903 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1904 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1905 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1906 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1907 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1908 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1909 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1910 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1911 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1912 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1913 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1914 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1915 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1916 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1917 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1918 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1919 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1920 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1921 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1922 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1923 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1924 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1925 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1926 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1927 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1928 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1929 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1930 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1931 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1932 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1933 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1934 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1935 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1936 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1937 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1938 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1939 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1940 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1941 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1942 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1943 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1944 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1945 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1946 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1947 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1948 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1949#undef D3DSTATE_TO_STR
1950 default:
1951 FIXME("Unrecognized %u render state!\n", state);
1952 return "unrecognized";
1953 }
1954}
1955
1956const char* debug_d3dsamplerstate(DWORD state) {
1957 switch (state) {
1958#define D3DSTATE_TO_STR(u) case u: return #u
1959 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1960 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1961 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1962 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1963 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1964 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1965 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1966 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1967 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1968 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1969 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1970 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1971 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1972#undef D3DSTATE_TO_STR
1973 default:
1974 FIXME("Unrecognized %u sampler state!\n", state);
1975 return "unrecognized";
1976 }
1977}
1978
1979const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1980 switch (filter_type) {
1981#define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1982 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1983 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1984 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1985 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1986 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1987 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1988 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1989 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1990#undef D3DTEXTUREFILTERTYPE_TO_STR
1991 default:
1992 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1993 return "unrecognized";
1994 }
1995}
1996
1997const char* debug_d3dtexturestate(DWORD state) {
1998 switch (state) {
1999#define D3DSTATE_TO_STR(u) case u: return #u
2000 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
2001 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
2002 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
2003 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
2004 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
2005 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
2006 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
2007 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
2008 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
2009 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
2010 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
2011 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
2012 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
2013 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
2014 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
2015 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
2016 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
2017 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
2018#undef D3DSTATE_TO_STR
2019 default:
2020 FIXME("Unrecognized %u texture state!\n", state);
2021 return "unrecognized";
2022 }
2023}
2024
2025const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2026 switch (d3dtop) {
2027#define D3DTOP_TO_STR(u) case u: return #u
2028 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2029 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2030 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2031 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2032 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2033 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2034 D3DTOP_TO_STR(WINED3DTOP_ADD);
2035 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2036 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2037 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2038 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2039 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2040 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2041 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2042 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2043 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2044 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2045 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2046 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2047 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2048 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2049 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2050 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2051 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2052 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2053 D3DTOP_TO_STR(WINED3DTOP_LERP);
2054#undef D3DTOP_TO_STR
2055 default:
2056 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2057 return "unrecognized";
2058 }
2059}
2060
2061const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2062 switch (tstype) {
2063#define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2064 TSTYPE_TO_STR(WINED3DTS_VIEW);
2065 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2066 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2067 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2068 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2069 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2070 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2071 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2072 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2073 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2074 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2075#undef TSTYPE_TO_STR
2076 default:
2077 if (tstype > 256 && tstype < 512) {
2078 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2079 return ("WINED3DTS_WORLDMATRIX > 0");
2080 }
2081 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2082 return "unrecognized";
2083 }
2084}
2085
2086const char *debug_d3dstate(DWORD state)
2087{
2088 if (STATE_IS_RENDER(state))
2089 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2090 if (STATE_IS_TEXTURESTAGE(state))
2091 {
2092 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2093 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2094 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2095 texture_stage, debug_d3dtexturestate(texture_state));
2096 }
2097 if (STATE_IS_SAMPLER(state))
2098 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2099 if (STATE_IS_PIXELSHADER(state))
2100 return "STATE_PIXELSHADER";
2101 if (STATE_IS_TRANSFORM(state))
2102 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2103 if (STATE_IS_STREAMSRC(state))
2104 return "STATE_STREAMSRC";
2105 if (STATE_IS_INDEXBUFFER(state))
2106 return "STATE_INDEXBUFFER";
2107 if (STATE_IS_VDECL(state))
2108 return "STATE_VDECL";
2109 if (STATE_IS_VSHADER(state))
2110 return "STATE_VSHADER";
2111 if (STATE_IS_VIEWPORT(state))
2112 return "STATE_VIEWPORT";
2113 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2114 return "STATE_VERTEXSHADERCONSTANT";
2115 if (STATE_IS_PIXELSHADERCONSTANT(state))
2116 return "STATE_PIXELSHADERCONSTANT";
2117 if (STATE_IS_ACTIVELIGHT(state))
2118 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2119 if (STATE_IS_SCISSORRECT(state))
2120 return "STATE_SCISSORRECT";
2121 if (STATE_IS_CLIPPLANE(state))
2122 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2123 if (STATE_IS_MATERIAL(state))
2124 return "STATE_MATERIAL";
2125 if (STATE_IS_FRONTFACE(state))
2126 return "STATE_FRONTFACE";
2127
2128 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2129}
2130
2131const char* debug_d3dpool(WINED3DPOOL Pool) {
2132 switch (Pool) {
2133#define POOL_TO_STR(p) case p: return #p
2134 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2135 POOL_TO_STR(WINED3DPOOL_MANAGED);
2136 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2137 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2138#undef POOL_TO_STR
2139 default:
2140 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
2141 return "unrecognized";
2142 }
2143}
2144
2145const char *debug_fbostatus(GLenum status) {
2146 switch(status) {
2147#define FBOSTATUS_TO_STR(u) case u: return #u
2148 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2149 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2150 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2151 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2152 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2153 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2154 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2155 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2156 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2157 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2158#undef FBOSTATUS_TO_STR
2159 default:
2160 FIXME("Unrecognied FBO status 0x%08x\n", status);
2161 return "unrecognized";
2162 }
2163}
2164
2165const char *debug_glerror(GLenum error) {
2166 switch(error) {
2167#define GLERROR_TO_STR(u) case u: return #u
2168 GLERROR_TO_STR(GL_NO_ERROR);
2169 GLERROR_TO_STR(GL_INVALID_ENUM);
2170 GLERROR_TO_STR(GL_INVALID_VALUE);
2171 GLERROR_TO_STR(GL_INVALID_OPERATION);
2172 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2173 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2174 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2175 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2176#undef GLERROR_TO_STR
2177 default:
2178 FIXME("Unrecognied GL error 0x%08x\n", error);
2179 return "unrecognized";
2180 }
2181}
2182
2183const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2184 switch(basis) {
2185 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2186 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2187 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2188 default: return "unrecognized";
2189 }
2190}
2191
2192const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2193 switch(degree) {
2194 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2195 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2196 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2197 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2198 default: return "unrecognized";
2199 }
2200}
2201
2202static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2203{
2204 switch(source)
2205 {
2206#define WINED3D_TO_STR(x) case x: return #x
2207 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2208 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2209 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2210 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2211 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2212 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2213 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2214 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2215#undef WINED3D_TO_STR
2216 default:
2217 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2218 return "unrecognized";
2219 }
2220}
2221
2222static const char *debug_complex_fixup(enum complex_fixup fixup)
2223{
2224 switch(fixup)
2225 {
2226#define WINED3D_TO_STR(x) case x: return #x
2227 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2228 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2229 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2230 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2231#undef WINED3D_TO_STR
2232 default:
2233 FIXME("Unrecognized complex fixup %#x\n", fixup);
2234 return "unrecognized";
2235 }
2236}
2237
2238void dump_color_fixup_desc(struct color_fixup_desc fixup)
2239{
2240 if (is_complex_fixup(fixup))
2241 {
2242 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2243 return;
2244 }
2245
2246 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2247 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2248 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2249 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2250}
2251
2252const char *debug_surflocation(DWORD flag) {
2253 char buf[128];
2254
2255 buf[0] = 0;
2256 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
2257 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
2258 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
2259 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
2260 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2261}
2262
2263/*****************************************************************************
2264 * Useful functions mapping GL <-> D3D values
2265 */
2266GLenum StencilOp(DWORD op) {
2267 switch(op) {
2268 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2269 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2270 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2271 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2272 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2273 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2274 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2275 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2276 default:
2277 FIXME("Unrecognized stencil op %d\n", op);
2278 return GL_KEEP;
2279 }
2280}
2281
2282GLenum CompareFunc(DWORD func) {
2283 switch ((WINED3DCMPFUNC)func) {
2284 case WINED3DCMP_NEVER : return GL_NEVER;
2285 case WINED3DCMP_LESS : return GL_LESS;
2286 case WINED3DCMP_EQUAL : return GL_EQUAL;
2287 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2288 case WINED3DCMP_GREATER : return GL_GREATER;
2289 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2290 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2291 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2292 default:
2293 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2294 return 0;
2295 }
2296}
2297
2298BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
2299 if (op == WINED3DTOP_DISABLE) return FALSE;
2300 if (This->stateBlock->textures[stage]) return FALSE;
2301
2302 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2303 && op != WINED3DTOP_SELECTARG2) return TRUE;
2304 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2305 && op != WINED3DTOP_SELECTARG1) return TRUE;
2306 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2307 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2308
2309 return FALSE;
2310}
2311
2312/* Setup this textures matrix according to the texture flags*/
2313/* GL locking is done by the caller (state handler) */
2314void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2315 WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
2316{
2317 float mat[16];
2318
2319 glMatrixMode(GL_TEXTURE);
2320 checkGLcall("glMatrixMode(GL_TEXTURE)");
2321
2322 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2323 glLoadIdentity();
2324 checkGLcall("glLoadIdentity()");
2325 return;
2326 }
2327
2328 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2329 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2330 return;
2331 }
2332
2333 memcpy(mat, smat, 16 * sizeof(float));
2334
2335 if (flags & WINED3DTTFF_PROJECTED) {
2336 if(!ffp_proj_control) {
2337 switch (flags & ~WINED3DTTFF_PROJECTED) {
2338 case WINED3DTTFF_COUNT2:
2339 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2340 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2341 break;
2342 case WINED3DTTFF_COUNT3:
2343 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2344 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2345 break;
2346 }
2347 }
2348 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2349 if(!calculatedCoords) {
2350 switch(vtx_fmt)
2351 {
2352 case WINED3DFMT_R32_FLOAT:
2353 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2354 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2355 * the input value to the transformation will be 0, so the matrix value is irrelevant
2356 */
2357 mat[12] = mat[4];
2358 mat[13] = mat[5];
2359 mat[14] = mat[6];
2360 mat[15] = mat[7];
2361 break;
2362 case WINED3DFMT_R32G32_FLOAT:
2363 /* See above, just 3rd and 4th coord
2364 */
2365 mat[12] = mat[8];
2366 mat[13] = mat[9];
2367 mat[14] = mat[10];
2368 mat[15] = mat[11];
2369 break;
2370 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2371 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2372
2373 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2374 * into a bad place. The division elimination below will apply to make sure the
2375 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2376 */
2377 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2378 break;
2379 default:
2380 FIXME("Unexpected fixed function texture coord input\n");
2381 }
2382 }
2383 if(!ffp_proj_control) {
2384 switch (flags & ~WINED3DTTFF_PROJECTED) {
2385 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2386 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2387 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2388 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2389 * the 4th coord evaluates to 1.0 to eliminate that.
2390 *
2391 * If the fixed function pipeline is used, the 4th value remains unused,
2392 * so there is no danger in doing this. With vertex shaders we have a
2393 * problem. Should an app hit that problem, the code here would have to
2394 * check for pixel shaders, and the shader has to undo the default gl divide.
2395 *
2396 * A more serious problem occurs if the app passes 4 coordinates in, and the
2397 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2398 * or a replacement shader
2399 */
2400 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2401 }
2402 }
2403 }
2404
2405 glLoadMatrixf(mat);
2406 checkGLcall("glLoadMatrixf(mat)");
2407}
2408
2409/* This small helper function is used to convert a bitmask into the number of masked bits */
2410unsigned int count_bits(unsigned int mask)
2411{
2412 unsigned int count;
2413 for (count = 0; mask; ++count)
2414 {
2415 mask &= mask - 1;
2416 }
2417 return count;
2418}
2419
2420/* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2421 * The later function requires individual color components. */
2422BOOL getColorBits(const struct wined3d_format_desc *format_desc,
2423 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2424{
2425 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2426 switch(format_desc->format)
2427 {
2428 case WINED3DFMT_B8G8R8X8_UNORM:
2429 case WINED3DFMT_B8G8R8_UNORM:
2430 case WINED3DFMT_B8G8R8A8_UNORM:
2431 case WINED3DFMT_R8G8B8A8_UNORM:
2432 case WINED3DFMT_B10G10R10A2_UNORM:
2433 case WINED3DFMT_B5G5R5X1_UNORM:
2434 case WINED3DFMT_B5G5R5A1_UNORM:
2435 case WINED3DFMT_B5G6R5_UNORM:
2436 case WINED3DFMT_B4G4R4X4_UNORM:
2437 case WINED3DFMT_B4G4R4A4_UNORM:
2438 case WINED3DFMT_B2G3R3_UNORM:
2439 case WINED3DFMT_P8_UINT_A8_UNORM:
2440 case WINED3DFMT_P8_UINT:
2441 break;
2442 default:
2443 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
2444 return FALSE;
2445 }
2446
2447 *redSize = count_bits(format_desc->red_mask);
2448 *greenSize = count_bits(format_desc->green_mask);
2449 *blueSize = count_bits(format_desc->blue_mask);
2450 *alphaSize = count_bits(format_desc->alpha_mask);
2451 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2452
2453 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
2454 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
2455 return TRUE;
2456}
2457
2458/* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2459BOOL getDepthStencilBits(const struct wined3d_format_desc *format_desc, short *depthSize, short *stencilSize)
2460{
2461 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2462 switch(format_desc->format)
2463 {
2464 case WINED3DFMT_D16_LOCKABLE:
2465 case WINED3DFMT_D16_UNORM:
2466 case WINED3DFMT_S1_UINT_D15_UNORM:
2467 case WINED3DFMT_X8D24_UNORM:
2468 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2469 case WINED3DFMT_D24_UNORM_S8_UINT:
2470 case WINED3DFMT_S8_UINT_D24_FLOAT:
2471 case WINED3DFMT_D32_UNORM:
2472 case WINED3DFMT_D32_FLOAT:
2473 break;
2474 default:
2475 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
2476 return FALSE;
2477 }
2478
2479 *depthSize = format_desc->depth_size;
2480 *stencilSize = format_desc->stencil_size;
2481
2482 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
2483 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
2484 return TRUE;
2485}
2486
2487DWORD color_convert_argb_to_fmt(DWORD color, WINED3DFORMAT destfmt)
2488{
2489 unsigned int r, g, b, a;
2490 DWORD ret;
2491
2492 if (destfmt == WINED3DFMT_B8G8R8A8_UNORM
2493 || destfmt == WINED3DFMT_B8G8R8X8_UNORM
2494 || destfmt == WINED3DFMT_B8G8R8_UNORM)
2495 return color;
2496
2497 TRACE("Converting color %08x to format %s\n", color, debug_d3dformat(destfmt));
2498
2499 a = (color & 0xff000000) >> 24;
2500 r = (color & 0x00ff0000) >> 16;
2501 g = (color & 0x0000ff00) >> 8;
2502 b = (color & 0x000000ff) >> 0;
2503
2504 switch(destfmt)
2505 {
2506 case WINED3DFMT_B5G6R5_UNORM:
2507 if(r == 0xff && g == 0xff && b == 0xff) return 0xffff;
2508 r = (r * 32) / 256;
2509 g = (g * 64) / 256;
2510 b = (b * 32) / 256;
2511 ret = r << 11;
2512 ret |= g << 5;
2513 ret |= b;
2514 TRACE("Returning %08x\n", ret);
2515 return ret;
2516
2517 case WINED3DFMT_B5G5R5X1_UNORM:
2518 case WINED3DFMT_B5G5R5A1_UNORM:
2519 a = (a * 2) / 256;
2520 r = (r * 32) / 256;
2521 g = (g * 32) / 256;
2522 b = (b * 32) / 256;
2523 ret = a << 15;
2524 ret |= r << 10;
2525 ret |= g << 5;
2526 ret |= b << 0;
2527 TRACE("Returning %08x\n", ret);
2528 return ret;
2529
2530 case WINED3DFMT_A8_UNORM:
2531 TRACE("Returning %08x\n", a);
2532 return a;
2533
2534 case WINED3DFMT_B4G4R4X4_UNORM:
2535 case WINED3DFMT_B4G4R4A4_UNORM:
2536 a = (a * 16) / 256;
2537 r = (r * 16) / 256;
2538 g = (g * 16) / 256;
2539 b = (b * 16) / 256;
2540 ret = a << 12;
2541 ret |= r << 8;
2542 ret |= g << 4;
2543 ret |= b << 0;
2544 TRACE("Returning %08x\n", ret);
2545 return ret;
2546
2547 case WINED3DFMT_B2G3R3_UNORM:
2548 r = (r * 8) / 256;
2549 g = (g * 8) / 256;
2550 b = (b * 4) / 256;
2551 ret = r << 5;
2552 ret |= g << 2;
2553 ret |= b << 0;
2554 TRACE("Returning %08x\n", ret);
2555 return ret;
2556
2557 case WINED3DFMT_R8G8B8X8_UNORM:
2558 case WINED3DFMT_R8G8B8A8_UNORM:
2559 ret = a << 24;
2560 ret |= b << 16;
2561 ret |= g << 8;
2562 ret |= r << 0;
2563 TRACE("Returning %08x\n", ret);
2564 return ret;
2565
2566 case WINED3DFMT_B10G10R10A2_UNORM:
2567 a = (a * 4) / 256;
2568 r = (r * 1024) / 256;
2569 g = (g * 1024) / 256;
2570 b = (b * 1024) / 256;
2571 ret = a << 30;
2572 ret |= r << 20;
2573 ret |= g << 10;
2574 ret |= b << 0;
2575 TRACE("Returning %08x\n", ret);
2576 return ret;
2577
2578 case WINED3DFMT_R10G10B10A2_UNORM:
2579 a = (a * 4) / 256;
2580 r = (r * 1024) / 256;
2581 g = (g * 1024) / 256;
2582 b = (b * 1024) / 256;
2583 ret = a << 30;
2584 ret |= b << 20;
2585 ret |= g << 10;
2586 ret |= r << 0;
2587 TRACE("Returning %08x\n", ret);
2588 return ret;
2589
2590 default:
2591 FIXME("Add a COLORFILL conversion for format %s\n", debug_d3dformat(destfmt));
2592 return 0;
2593 }
2594}
2595
2596/* DirectDraw stuff */
2597WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2598 switch(depth) {
2599 case 8: return WINED3DFMT_P8_UINT;
2600 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2601 case 16: return WINED3DFMT_B5G6R5_UNORM;
2602 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2603 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2604 default: return WINED3DFMT_UNKNOWN;
2605 }
2606}
2607
2608void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2609 WINED3DMATRIX temp;
2610
2611 /* Now do the multiplication 'by hand'.
2612 I know that all this could be optimised, but this will be done later :-) */
2613 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);
2614 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);
2615 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);
2616 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);
2617
2618 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);
2619 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);
2620 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);
2621 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);
2622
2623 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);
2624 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);
2625 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);
2626 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);
2627
2628 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);
2629 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);
2630 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);
2631 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);
2632
2633 /* And copy the new matrix in the good storage.. */
2634 memcpy(dest, &temp, 16 * sizeof(float));
2635}
2636
2637DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2638 DWORD size = 0;
2639 int i;
2640 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2641
2642 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2643 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2644 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2645 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2646 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2647 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2648 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2649 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2650 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2651 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2652 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2653 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2654 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2655 default: ERR("Unexpected position mask\n");
2656 }
2657 for (i = 0; i < numTextures; i++) {
2658 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2659 }
2660
2661 return size;
2662}
2663
2664void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2665#define ARG1 0x01
2666#define ARG2 0x02
2667#define ARG0 0x04
2668 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2669 /* undefined */ 0,
2670 /* D3DTOP_DISABLE */ 0,
2671 /* D3DTOP_SELECTARG1 */ ARG1,
2672 /* D3DTOP_SELECTARG2 */ ARG2,
2673 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2674 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2675 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2676 /* D3DTOP_ADD */ ARG1 | ARG2,
2677 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2678 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2679 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2680 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2681 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2682 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2683 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2684 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2685 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2686 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2687 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2688 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2689 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2690 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2691 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2692 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2693 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2694 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2695 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2696 };
2697 unsigned int i;
2698 DWORD ttff;
2699 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2700 IWineD3DDeviceImpl *device = stateblock->device;
2701 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2702
2703 memset(settings, 0, sizeof(*settings));
2704
2705 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2706 {
2707 IWineD3DBaseTextureImpl *texture;
2708 settings->op[i].padding = 0;
2709 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2710 settings->op[i].cop = WINED3DTOP_DISABLE;
2711 settings->op[i].aop = WINED3DTOP_DISABLE;
2712 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2713 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2714 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2715 settings->op[i].dst = resultreg;
2716 settings->op[i].tex_type = tex_1d;
2717 settings->op[i].projected = proj_none;
2718 i++;
2719 break;
2720 }
2721
2722 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2723 if(texture) {
2724 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2725 if(ignore_textype) {
2726 settings->op[i].tex_type = tex_1d;
2727 } else {
2728 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2729 case GL_TEXTURE_1D:
2730 settings->op[i].tex_type = tex_1d;
2731 break;
2732 case GL_TEXTURE_2D:
2733 settings->op[i].tex_type = tex_2d;
2734 break;
2735 case GL_TEXTURE_3D:
2736 settings->op[i].tex_type = tex_3d;
2737 break;
2738 case GL_TEXTURE_CUBE_MAP_ARB:
2739 settings->op[i].tex_type = tex_cube;
2740 break;
2741 case GL_TEXTURE_RECTANGLE_ARB:
2742 settings->op[i].tex_type = tex_rect;
2743 break;
2744 }
2745 }
2746 } else {
2747 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2748 settings->op[i].tex_type = tex_1d;
2749 }
2750
2751 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2752 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2753
2754 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2755 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2756 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2757
2758 if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2759 carg0 = ARG_UNUSED;
2760 carg2 = ARG_UNUSED;
2761 carg1 = WINED3DTA_CURRENT;
2762 cop = WINED3DTOP_SELECTARG1;
2763 }
2764
2765 if(cop == WINED3DTOP_DOTPRODUCT3) {
2766 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2767 * the color result to the alpha component of the destination
2768 */
2769 aop = cop;
2770 aarg1 = carg1;
2771 aarg2 = carg2;
2772 aarg0 = carg0;
2773 } else {
2774 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2775 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2776 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2777 }
2778
2779 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2780 {
2781 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2782
2783 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2784 {
2785 IWineD3DSurfaceImpl *surf;
2786 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2787
2788 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2789 {
2790 if (aop == WINED3DTOP_DISABLE)
2791 {
2792 aarg1 = WINED3DTA_TEXTURE;
2793 aop = WINED3DTOP_SELECTARG1;
2794 }
2795 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2796 {
2797 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2798 {
2799 aarg2 = WINED3DTA_TEXTURE;
2800 aop = WINED3DTOP_MODULATE;
2801 }
2802 else aarg1 = WINED3DTA_TEXTURE;
2803 }
2804 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2805 {
2806 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2807 {
2808 aarg1 = WINED3DTA_TEXTURE;
2809 aop = WINED3DTOP_MODULATE;
2810 }
2811 else aarg2 = WINED3DTA_TEXTURE;
2812 }
2813 }
2814 }
2815 }
2816
2817 if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2818 aarg0 = ARG_UNUSED;
2819 aarg2 = ARG_UNUSED;
2820 aarg1 = WINED3DTA_CURRENT;
2821 aop = WINED3DTOP_SELECTARG1;
2822 }
2823
2824 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2825 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2826 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2827 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2828 settings->op[i].projected = proj_count3;
2829 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2830 settings->op[i].projected = proj_count4;
2831 } else {
2832 settings->op[i].projected = proj_none;
2833 }
2834 } else {
2835 settings->op[i].projected = proj_none;
2836 }
2837
2838 settings->op[i].cop = cop;
2839 settings->op[i].aop = aop;
2840 settings->op[i].carg0 = carg0;
2841 settings->op[i].carg1 = carg1;
2842 settings->op[i].carg2 = carg2;
2843 settings->op[i].aarg0 = aarg0;
2844 settings->op[i].aarg1 = aarg1;
2845 settings->op[i].aarg2 = aarg2;
2846
2847 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2848 settings->op[i].dst = tempreg;
2849 } else {
2850 settings->op[i].dst = resultreg;
2851 }
2852 }
2853
2854 /* Clear unsupported stages */
2855 for(; i < MAX_TEXTURES; i++) {
2856 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2857 }
2858
2859 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2860 settings->fog = FOG_OFF;
2861 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2862 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2863 settings->fog = FOG_LINEAR;
2864 } else {
2865 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2866 case WINED3DFOG_NONE:
2867 case WINED3DFOG_LINEAR:
2868 settings->fog = FOG_LINEAR;
2869 break;
2870 case WINED3DFOG_EXP:
2871 settings->fog = FOG_EXP;
2872 break;
2873 case WINED3DFOG_EXP2:
2874 settings->fog = FOG_EXP2;
2875 break;
2876 }
2877 }
2878 } else {
2879 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2880 case WINED3DFOG_LINEAR:
2881 settings->fog = FOG_LINEAR;
2882 break;
2883 case WINED3DFOG_EXP:
2884 settings->fog = FOG_EXP;
2885 break;
2886 case WINED3DFOG_EXP2:
2887 settings->fog = FOG_EXP2;
2888 break;
2889 }
2890 }
2891 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2892 settings->sRGB_write = 1;
2893 } else {
2894 settings->sRGB_write = 0;
2895 }
2896 if(device->vs_clipping || !use_vs(stateblock) || !stateblock->renderState[WINED3DRS_CLIPPING] ||
2897 !stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
2898 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2899 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2900 * if no clipplane is enabled
2901 */
2902 settings->emul_clipplanes = 0;
2903 } else {
2904 settings->emul_clipplanes = 1;
2905 }
2906}
2907
2908const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2909 const struct ffp_frag_settings *settings)
2910{
2911 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2912 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2913}
2914
2915void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2916{
2917 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2918 * whereas desc points to an extended structure with implementation specific parts. */
2919 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2920 {
2921 ERR("Failed to insert ffp frag shader.\n");
2922 }
2923}
2924
2925/* Activates the texture dimension according to the bound D3D texture.
2926 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2927 * Requires the caller to activate the correct unit before
2928 */
2929/* GL locking is done by the caller (state handler) */
2930void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2931{
2932 const struct wined3d_gl_info *gl_info = context->gl_info;
2933
2934 if (stateblock->textures[stage])
2935 {
2936 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2937 case GL_TEXTURE_2D:
2938 glDisable(GL_TEXTURE_3D);
2939 checkGLcall("glDisable(GL_TEXTURE_3D)");
2940 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2941 {
2942 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2943 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2944 }
2945 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2946 {
2947 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2948 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2949 }
2950 glEnable(GL_TEXTURE_2D);
2951 checkGLcall("glEnable(GL_TEXTURE_2D)");
2952 break;
2953 case GL_TEXTURE_RECTANGLE_ARB:
2954 glDisable(GL_TEXTURE_2D);
2955 checkGLcall("glDisable(GL_TEXTURE_2D)");
2956 glDisable(GL_TEXTURE_3D);
2957 checkGLcall("glDisable(GL_TEXTURE_3D)");
2958 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2959 {
2960 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2961 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2962 }
2963 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2964 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2965 break;
2966 case GL_TEXTURE_3D:
2967 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2968 {
2969 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2970 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2971 }
2972 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2973 {
2974 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2975 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2976 }
2977 glDisable(GL_TEXTURE_2D);
2978 checkGLcall("glDisable(GL_TEXTURE_2D)");
2979 glEnable(GL_TEXTURE_3D);
2980 checkGLcall("glEnable(GL_TEXTURE_3D)");
2981 break;
2982 case GL_TEXTURE_CUBE_MAP_ARB:
2983 glDisable(GL_TEXTURE_2D);
2984 checkGLcall("glDisable(GL_TEXTURE_2D)");
2985 glDisable(GL_TEXTURE_3D);
2986 checkGLcall("glDisable(GL_TEXTURE_3D)");
2987 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2988 {
2989 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2990 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2991 }
2992 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2993 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2994 break;
2995 }
2996 } else {
2997 glEnable(GL_TEXTURE_2D);
2998 checkGLcall("glEnable(GL_TEXTURE_2D)");
2999 glDisable(GL_TEXTURE_3D);
3000 checkGLcall("glDisable(GL_TEXTURE_3D)");
3001 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3002 {
3003 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3004 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3005 }
3006 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3007 {
3008 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3009 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3010 }
3011 /* Binding textures is done by samplers. A dummy texture will be bound */
3012 }
3013}
3014
3015/* GL locking is done by the caller (state handler) */
3016void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3017{
3018 DWORD sampler = state - STATE_SAMPLER(0);
3019 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3020
3021 /* No need to enable / disable anything here for unused samplers. The tex_colorop
3022 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3023 * will take care of this business
3024 */
3025 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
3026 if(sampler >= stateblock->lowest_disabled_stage) return;
3027 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3028
3029 texture_activate_dimensions(sampler, stateblock, context);
3030}
3031
3032void *wined3d_rb_alloc(size_t size)
3033{
3034 return HeapAlloc(GetProcessHeap(), 0, size);
3035}
3036
3037void *wined3d_rb_realloc(void *ptr, size_t size)
3038{
3039 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3040}
3041
3042void wined3d_rb_free(void *ptr)
3043{
3044 HeapFree(GetProcessHeap(), 0, ptr);
3045}
3046
3047static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3048{
3049 const struct ffp_frag_settings *ka = key;
3050 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3051
3052 return memcmp(ka, kb, sizeof(*ka));
3053}
3054
3055const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3056{
3057 wined3d_rb_alloc,
3058 wined3d_rb_realloc,
3059 wined3d_rb_free,
3060 ffp_frag_program_key_compare,
3061};
3062
3063UINT wined3d_log2i(UINT32 x)
3064{
3065 static const UINT l[] =
3066 {
3067 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3068 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3069 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3070 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3071 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3072 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3073 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3074 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3075 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3076 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3077 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3078 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3079 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3080 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3081 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3082 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3083 };
3084 UINT32 i;
3085
3086 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3087}
3088
3089/* Set the shader type for this device, depending on the given capabilities
3090 * and the user preferences in wined3d_settings. */
3091void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3092{
3093 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3094
3095 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3096 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3097 {
3098 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3099 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3100 * shaders only on this card. */
3101 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3102 else *vs_selected = SHADER_GLSL;
3103 }
3104 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3105 else *vs_selected = SHADER_NONE;
3106
3107 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3108 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3109 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3110 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3111 else *ps_selected = SHADER_NONE;
3112}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette