push 6e61d6ca5bcaf95ac09a664b4ba4f88238c927be
[wine/hacks.git] / dlls / wined3d / utils.c
blob2ff16752c33509f19e94d23bf660edc014b9c272
1 /*
2 * Utility functions for the WineD3D Library
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2008 Henri Verbeet
9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
10 * Copyright 2009 Henri Verbeet for CodeWeavers
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "config.h"
28 #include "wined3d_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
32 struct StaticPixelFormatDesc
34 WINED3DFORMAT format;
35 DWORD alphaMask, redMask, greenMask, blueMask;
36 UINT bpp;
37 short depthSize, stencilSize;
40 /*****************************************************************************
41 * Pixel format array
43 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
44 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
45 * high masks do not fit into the 32 bit values needed for ddraw. It is only
46 * used for ddraw mostly, and to figure out if the format has alpha at all, so
47 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
48 * formats are not usable in 2D rendering because ddraw doesn't support them.
50 static const struct StaticPixelFormatDesc formats[] =
52 /* WINED3DFORMAT alphamask redmask greenmask bluemask bpp depth stencil */
53 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
54 /* FourCC formats */
55 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
56 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
57 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
58 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
59 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
60 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
61 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
62 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
63 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
64 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
65 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
66 /* IEEE formats */
67 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
68 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
69 {WINED3DFMT_R32G32B32_FLOAT, 0x0, 0x0, 0x0, 0x0, 12, 0, 0},
70 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0},
71 /* Hmm? */
72 {WINED3DFMT_R8G8_SNORM_Cx, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
73 /* Float */
74 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
75 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
76 {WINED3DFMT_R16G16_SINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
77 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
78 {WINED3DFMT_R16G16B16A16_SINT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
79 /* Palettized formats */
80 {WINED3DFMT_P8_UINT_A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
81 {WINED3DFMT_P8_UINT, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
82 /* Standard ARGB formats. */
83 {WINED3DFMT_B8G8R8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0},
84 {WINED3DFMT_B8G8R8A8_UNORM, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
85 {WINED3DFMT_B8G8R8X8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
86 {WINED3DFMT_B5G6R5_UNORM, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0},
87 {WINED3DFMT_B5G5R5X1_UNORM, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
88 {WINED3DFMT_B5G5R5A1_UNORM, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
89 {WINED3DFMT_B4G4R4A4_UNORM, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
90 {WINED3DFMT_B2G3R3_UNORM, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0},
91 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0},
92 {WINED3DFMT_B2G3R3A8_UNORM, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0},
93 {WINED3DFMT_B4G4R4X4_UNORM, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
94 {WINED3DFMT_R10G10B10A2_UNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
95 {WINED3DFMT_R10G10B10A2_UINT, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
96 {WINED3DFMT_R10G10B10A2_SNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
97 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
98 {WINED3DFMT_R8G8B8A8_UINT, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
99 {WINED3DFMT_R8G8B8X8_UNORM, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
100 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0},
101 {WINED3DFMT_B10G10R10A2_UNORM, 0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0},
102 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0},
103 /* Luminance */
104 {WINED3DFMT_L8_UNORM, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
105 {WINED3DFMT_L8A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
106 {WINED3DFMT_L4A4_UNORM, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0},
107 {WINED3DFMT_L16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
108 /* Bump mapping stuff */
109 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
110 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
111 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
112 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
113 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
114 {WINED3DFMT_R10G11B11_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
115 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0},
116 /* Depth stencil formats */
117 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
118 {WINED3DFMT_D32_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
119 {WINED3DFMT_S1_UINT_D15_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 15, 1},
120 {WINED3DFMT_D24_UNORM_S8_UINT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
121 {WINED3DFMT_X8D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 0},
122 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 4},
123 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
124 {WINED3DFMT_D32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
125 {WINED3DFMT_S8_UINT_D24_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
126 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
127 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
128 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
129 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
130 /* Vendor-specific formats */
131 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
132 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
133 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
136 struct wined3d_format_base_flags
138 WINED3DFORMAT format;
139 DWORD flags;
142 static const struct wined3d_format_base_flags format_base_flags[] =
144 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
145 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
146 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
147 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
148 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
149 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
150 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
151 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
152 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
153 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
156 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
157 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
158 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
159 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
160 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
161 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
162 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
163 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
164 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
165 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
166 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC},
167 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
168 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
171 struct wined3d_format_compression_info
173 WINED3DFORMAT format;
174 UINT block_width;
175 UINT block_height;
176 UINT block_byte_count;
179 static const struct wined3d_format_compression_info format_compression_info[] =
181 {WINED3DFMT_DXT1, 4, 4, 8},
182 {WINED3DFMT_DXT2, 4, 4, 16},
183 {WINED3DFMT_DXT3, 4, 4, 16},
184 {WINED3DFMT_DXT4, 4, 4, 16},
185 {WINED3DFMT_DXT5, 4, 4, 16},
186 {WINED3DFMT_ATI2N, 4, 4, 16},
189 struct wined3d_format_vertex_info
191 WINED3DFORMAT format;
192 enum wined3d_ffp_emit_idx emit_idx;
193 GLint component_count;
194 GLenum gl_vtx_type;
195 GLint gl_vtx_format;
196 GLboolean gl_normalized;
197 unsigned int component_size;
200 static const struct wined3d_format_vertex_info format_vertex_info[] =
202 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
203 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
204 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
205 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
206 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
207 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
208 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
209 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
210 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
211 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
212 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
213 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
214 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
215 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
216 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
217 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
218 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
221 typedef struct {
222 WINED3DFORMAT fmt;
223 GLint glInternal, glGammaInternal, rtInternal, glFormat, glType;
224 unsigned int Flags;
225 GL_SupportedExt extension;
226 } GlPixelFormatDescTemplate;
228 /*****************************************************************************
229 * OpenGL format template. Contains unexciting formats which do not need
230 * extension checks. The order in this table is independent of the order in
231 * the table StaticPixelFormatDesc above. Not all formats have to be in this
232 * table.
234 static const GlPixelFormatDescTemplate gl_formats_template[] = {
235 /* WINED3DFORMAT internal srgbInternal rtInternal
236 format type
237 flags
238 extension */
239 /* FourCC formats */
240 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
241 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
242 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
243 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
244 * endian machine
246 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
247 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
248 WINED3DFMT_FLAG_FILTERING,
249 WINED3D_GL_EXT_NONE},
250 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
251 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE,
252 WINED3DFMT_FLAG_FILTERING,
253 APPLE_YCBCR_422},
254 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
255 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
256 WINED3DFMT_FLAG_FILTERING,
257 WINED3D_GL_EXT_NONE},
258 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
259 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE,
260 WINED3DFMT_FLAG_FILTERING,
261 APPLE_YCBCR_422},
262 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
263 GL_ALPHA, GL_UNSIGNED_BYTE,
264 WINED3DFMT_FLAG_FILTERING,
265 WINED3D_GL_EXT_NONE},
266 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
267 GL_RGBA, GL_UNSIGNED_BYTE,
268 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
269 EXT_TEXTURE_COMPRESSION_S3TC},
270 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
271 GL_RGBA, GL_UNSIGNED_BYTE,
272 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
273 EXT_TEXTURE_COMPRESSION_S3TC},
274 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
275 GL_RGBA, GL_UNSIGNED_BYTE,
276 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
277 EXT_TEXTURE_COMPRESSION_S3TC},
278 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
279 GL_RGBA, GL_UNSIGNED_BYTE,
280 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
281 EXT_TEXTURE_COMPRESSION_S3TC},
282 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
283 GL_RGBA, GL_UNSIGNED_BYTE,
284 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
285 EXT_TEXTURE_COMPRESSION_S3TC},
286 /* IEEE formats */
287 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
288 GL_RED, GL_FLOAT,
289 WINED3DFMT_FLAG_RENDERTARGET,
290 ARB_TEXTURE_FLOAT},
291 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
292 GL_RED, GL_FLOAT,
293 WINED3DFMT_FLAG_RENDERTARGET,
294 ARB_TEXTURE_RG},
295 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
296 GL_RGB, GL_FLOAT,
297 WINED3DFMT_FLAG_RENDERTARGET,
298 ARB_TEXTURE_FLOAT},
299 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
300 GL_RG, GL_FLOAT,
301 WINED3DFMT_FLAG_RENDERTARGET,
302 ARB_TEXTURE_RG},
303 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
304 GL_RGBA, GL_FLOAT,
305 WINED3DFMT_FLAG_RENDERTARGET,
306 ARB_TEXTURE_FLOAT},
307 /* Float */
308 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
309 GL_RED, GL_HALF_FLOAT_ARB,
310 WINED3DFMT_FLAG_RENDERTARGET,
311 ARB_TEXTURE_FLOAT},
312 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
313 GL_RED, GL_HALF_FLOAT_ARB,
314 WINED3DFMT_FLAG_RENDERTARGET,
315 ARB_TEXTURE_RG},
316 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
317 GL_RGB, GL_HALF_FLOAT_ARB,
318 WINED3DFMT_FLAG_RENDERTARGET,
319 ARB_TEXTURE_FLOAT},
320 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
321 GL_RG, GL_HALF_FLOAT_ARB,
322 WINED3DFMT_FLAG_RENDERTARGET,
323 ARB_TEXTURE_RG},
324 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
325 GL_RGBA, GL_HALF_FLOAT_ARB,
326 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
327 ARB_TEXTURE_FLOAT},
328 /* Palettized formats */
329 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
330 GL_RGBA, GL_UNSIGNED_BYTE,
332 ARB_FRAGMENT_PROGRAM},
333 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
334 GL_COLOR_INDEX, GL_UNSIGNED_BYTE,
336 EXT_PALETTED_TEXTURE},
337 /* Standard ARGB formats */
338 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
339 GL_BGR, GL_UNSIGNED_BYTE,
340 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
341 WINED3D_GL_EXT_NONE},
342 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
343 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
344 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
345 WINED3D_GL_EXT_NONE},
346 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
347 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
348 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
349 WINED3D_GL_EXT_NONE},
350 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
351 GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
352 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
353 WINED3D_GL_EXT_NONE},
354 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
355 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
356 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
357 WINED3D_GL_EXT_NONE},
358 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
359 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
360 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
361 WINED3D_GL_EXT_NONE},
362 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
363 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
364 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
365 WINED3D_GL_EXT_NONE},
366 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
367 GL_RGB, GL_UNSIGNED_BYTE_3_3_2,
368 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
369 WINED3D_GL_EXT_NONE},
370 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
371 GL_ALPHA, GL_UNSIGNED_BYTE,
372 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
373 WINED3D_GL_EXT_NONE},
374 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
375 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
376 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
377 WINED3D_GL_EXT_NONE},
378 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
379 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV,
380 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
381 WINED3D_GL_EXT_NONE},
382 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
383 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
384 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
385 WINED3D_GL_EXT_NONE},
386 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
387 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
388 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
389 WINED3D_GL_EXT_NONE},
390 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
391 GL_RGB, GL_UNSIGNED_SHORT,
392 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
393 WINED3D_GL_EXT_NONE},
394 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
395 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV,
396 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
397 WINED3D_GL_EXT_NONE},
398 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
399 GL_RGBA, GL_UNSIGNED_SHORT,
400 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
401 WINED3D_GL_EXT_NONE},
402 /* Luminance */
403 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
404 GL_LUMINANCE, GL_UNSIGNED_BYTE,
405 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
406 WINED3D_GL_EXT_NONE},
407 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
408 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
409 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
410 WINED3D_GL_EXT_NONE},
411 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
412 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
414 WINED3D_GL_EXT_NONE},
415 /* Bump mapping stuff */
416 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
417 GL_BGR, GL_UNSIGNED_BYTE,
418 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
419 WINED3D_GL_EXT_NONE},
420 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
421 GL_DSDT_NV, GL_BYTE,
422 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
423 NV_TEXTURE_SHADER},
424 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
425 GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
426 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
427 WINED3D_GL_EXT_NONE},
428 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
429 GL_DSDT_MAG_NV, GL_BYTE,
430 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
431 NV_TEXTURE_SHADER},
432 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
433 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
434 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
435 WINED3D_GL_EXT_NONE},
436 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
437 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV,
438 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
439 NV_TEXTURE_SHADER},
440 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
441 GL_BGRA, GL_UNSIGNED_BYTE,
442 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
443 WINED3D_GL_EXT_NONE},
444 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
445 GL_RGBA, GL_BYTE,
446 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
447 NV_TEXTURE_SHADER},
448 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
449 GL_BGR, GL_UNSIGNED_SHORT,
450 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
451 WINED3D_GL_EXT_NONE},
452 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
453 GL_HILO_NV, GL_SHORT,
454 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
455 NV_TEXTURE_SHADER},
456 /* Depth stencil formats */
457 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
458 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
459 WINED3DFMT_FLAG_DEPTH,
460 ARB_DEPTH_TEXTURE},
461 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
462 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
463 WINED3DFMT_FLAG_DEPTH,
464 ARB_DEPTH_TEXTURE},
465 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
466 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
467 WINED3DFMT_FLAG_DEPTH,
468 ARB_DEPTH_TEXTURE},
469 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
470 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
471 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
472 EXT_PACKED_DEPTH_STENCIL},
473 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
474 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
475 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
476 ARB_FRAMEBUFFER_OBJECT},
477 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
478 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
479 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
480 ARB_DEPTH_TEXTURE},
481 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
482 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
483 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
484 EXT_PACKED_DEPTH_STENCIL},
485 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
486 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
487 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
488 ARB_FRAMEBUFFER_OBJECT},
489 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
490 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
491 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
492 ARB_DEPTH_TEXTURE},
493 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
494 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
495 WINED3DFMT_FLAG_DEPTH,
496 ARB_DEPTH_TEXTURE},
497 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
498 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
499 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
500 EXT_PACKED_DEPTH_STENCIL},
501 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
502 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
503 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
504 ARB_FRAMEBUFFER_OBJECT},
505 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
506 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
507 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
508 ARB_DEPTH_TEXTURE},
509 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
510 GL_LUMINANCE, GL_UNSIGNED_SHORT,
511 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
512 WINED3D_GL_EXT_NONE},
513 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
514 GL_DEPTH_COMPONENT, GL_FLOAT,
515 WINED3DFMT_FLAG_DEPTH,
516 ARB_DEPTH_BUFFER_FLOAT},
517 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
518 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
519 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
520 ARB_DEPTH_BUFFER_FLOAT},
521 /* Vendor-specific formats */
522 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
523 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
525 ATI_TEXTURE_COMPRESSION_3DC},
526 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, 0,
527 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
529 EXT_TEXTURE_COMPRESSION_RGTC},
532 static inline int getFmtIdx(WINED3DFORMAT fmt) {
533 /* First check if the format is at the position of its value.
534 * This will catch the argb formats before the loop is entered
536 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
537 return fmt;
538 } else {
539 unsigned int i;
540 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
541 if(formats[i].format == fmt) {
542 return i;
546 return -1;
549 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
551 UINT format_count = sizeof(formats) / sizeof(*formats);
552 UINT i;
554 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->gl_formats));
555 if (!gl_info->gl_formats)
557 ERR("Failed to allocate memory.\n");
558 return FALSE;
561 for (i = 0; i < format_count; ++i)
563 struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
564 desc->format = formats[i].format;
565 desc->red_mask = formats[i].redMask;
566 desc->green_mask = formats[i].greenMask;
567 desc->blue_mask = formats[i].blueMask;
568 desc->alpha_mask = formats[i].alphaMask;
569 desc->byte_count = formats[i].bpp;
570 desc->depth_size = formats[i].depthSize;
571 desc->stencil_size = formats[i].stencilSize;
574 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
576 int fmt_idx = getFmtIdx(format_base_flags[i].format);
578 if (fmt_idx == -1)
580 ERR("Format %s (%#x) not found.\n",
581 debug_d3dformat(format_base_flags[i].format), format_base_flags[i].format);
582 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
583 return FALSE;
586 gl_info->gl_formats[fmt_idx].Flags |= format_base_flags[i].flags;
589 return TRUE;
592 static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
594 unsigned int i;
596 for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
598 struct GlPixelFormatDesc *format_desc;
599 int fmt_idx = getFmtIdx(format_compression_info[i].format);
601 if (fmt_idx == -1)
603 ERR("Format %s (%#x) not found.\n",
604 debug_d3dformat(format_compression_info[i].format), format_compression_info[i].format);
605 return FALSE;
608 format_desc = &gl_info->gl_formats[fmt_idx];
609 format_desc->block_width = format_compression_info[i].block_width;
610 format_desc->block_height = format_compression_info[i].block_height;
611 format_desc->block_byte_count = format_compression_info[i].block_byte_count;
612 format_desc->Flags |= WINED3DFMT_FLAG_COMPRESSED;
615 return TRUE;
618 /* Context activation is done by the caller. */
619 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPixelFormatDesc *format_desc)
621 /* Check if the default internal format is supported as a frame buffer
622 * target, otherwise fall back to the render target internal.
624 * Try to stick to the standard format if possible, this limits precision differences. */
625 GLenum status;
626 GLuint tex;
628 ENTER_GL();
630 while(glGetError());
631 glDisable(GL_BLEND);
633 glGenTextures(1, &tex);
634 glBindTexture(GL_TEXTURE_2D, tex);
636 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glInternal, 16, 16, 0,
637 format_desc->glFormat, format_desc->glType, NULL);
638 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
639 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
641 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
643 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
644 checkGLcall("Framebuffer format check");
646 if (status == GL_FRAMEBUFFER_COMPLETE)
648 TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(format_desc->format));
649 format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
650 format_desc->rtInternal = format_desc->glInternal;
652 else
654 if (!format_desc->rtInternal)
656 if (format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)
658 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
659 " and no fallback specified.\n", debug_d3dformat(format_desc->format));
660 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
662 else
664 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format_desc->format));
666 format_desc->rtInternal = format_desc->glInternal;
668 else
670 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
671 debug_d3dformat(format_desc->format));
673 while(glGetError());
675 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
677 glTexImage2D(GL_TEXTURE_2D, 0, format_desc->rtInternal, 16, 16, 0,
678 format_desc->glFormat, format_desc->glType, NULL);
679 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
680 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
682 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
684 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
685 checkGLcall("Framebuffer format check");
687 if (status == GL_FRAMEBUFFER_COMPLETE)
689 TRACE("Format %s rtInternal format is supported as FBO color attachment\n",
690 debug_d3dformat(format_desc->format));
692 else
694 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
695 debug_d3dformat(format_desc->format));
696 format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
701 if (status == GL_FRAMEBUFFER_COMPLETE && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
703 GLuint rb;
705 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
706 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
708 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
709 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
710 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
711 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
712 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
713 checkGLcall("RB attachment");
716 glEnable(GL_BLEND);
717 glClear(GL_COLOR_BUFFER_BIT);
718 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
720 while(glGetError());
721 TRACE("Format doesn't support post-pixelshader blending.\n");
722 format_desc->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
725 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
726 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
728 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
729 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
730 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
731 checkGLcall("RB cleanup");
735 glDeleteTextures(1, &tex);
737 LEAVE_GL();
740 /* Context activation is done by the caller. */
741 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
743 unsigned int i;
744 GLuint fbo;
746 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
748 ENTER_GL();
750 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
751 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
753 LEAVE_GL();
756 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
758 struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
760 if (!desc->glInternal) continue;
762 if (desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
764 TRACE("Skipping format %s because it's a depth/stencil format.\n",
765 debug_d3dformat(desc->format));
766 continue;
769 if (desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
771 TRACE("Skipping format %s because it's a compressed format.\n",
772 debug_d3dformat(desc->format));
773 continue;
776 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
778 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc->format));
779 check_fbo_compat(gl_info, desc);
781 else
783 desc->rtInternal = desc->glInternal;
787 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
789 ENTER_GL();
791 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
793 LEAVE_GL();
797 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
799 unsigned int i;
801 for (i = 0; i < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); ++i)
803 int fmt_idx = getFmtIdx(gl_formats_template[i].fmt);
804 struct GlPixelFormatDesc *desc;
806 if (fmt_idx == -1)
808 ERR("Format %s (%#x) not found.\n",
809 debug_d3dformat(gl_formats_template[i].fmt), gl_formats_template[i].fmt);
810 return FALSE;
813 if (!gl_info->supported[gl_formats_template[i].extension]) continue;
815 desc = &gl_info->gl_formats[fmt_idx];
816 desc->glInternal = gl_formats_template[i].glInternal;
817 desc->glGammaInternal = gl_formats_template[i].glGammaInternal;
818 desc->rtInternal = gl_formats_template[i].rtInternal;
819 desc->glFormat = gl_formats_template[i].glFormat;
820 desc->glType = gl_formats_template[i].glType;
821 desc->color_fixup = COLOR_FIXUP_IDENTITY;
822 desc->Flags |= gl_formats_template[i].Flags;
823 desc->heightscale = 1.0f;
826 return TRUE;
829 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
831 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
832 c1 >>= 8; c2 >>= 8;
833 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
834 c1 >>= 8; c2 >>= 8;
835 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
836 c1 >>= 8; c2 >>= 8;
837 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
838 return TRUE;
841 /* A context is provided by the caller */
842 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
844 GLuint tex, fbo, buffer;
845 const DWORD data[] = {0x00000000, 0xffffffff};
846 DWORD readback[16 * 1];
847 BOOL ret = FALSE;
849 /* Render a filtered texture and see what happens. This is intended to detect the lack of
850 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
851 * falling back to software. If this changes in the future this code will get fooled and
852 * apps might hit the software path due to incorrectly advertised caps.
854 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
855 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
856 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
859 ENTER_GL();
860 while(glGetError());
862 glGenTextures(1, &buffer);
863 glBindTexture(GL_TEXTURE_2D, buffer);
864 memset(readback, 0x7e, sizeof(readback));
865 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
866 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
867 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
868 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
869 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
870 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
872 glGenTextures(1, &tex);
873 glBindTexture(GL_TEXTURE_2D, tex);
874 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
875 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
876 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
877 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
878 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
879 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
880 glEnable(GL_TEXTURE_2D);
882 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
883 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
884 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
885 glDrawBuffer(GL_COLOR_ATTACHMENT0);
887 glViewport(0, 0, 16, 1);
888 glDisable(GL_LIGHTING);
889 glMatrixMode(GL_MODELVIEW);
890 glLoadIdentity();
891 glMatrixMode(GL_PROJECTION);
892 glLoadIdentity();
894 glClearColor(0, 1, 0, 0);
895 glClear(GL_COLOR_BUFFER_BIT);
897 glBegin(GL_TRIANGLE_STRIP);
898 glTexCoord2f(0.0, 0.0);
899 glVertex2f(-1.0f, -1.0f);
900 glTexCoord2f(1.0, 0.0);
901 glVertex2f(1.0f, -1.0f);
902 glTexCoord2f(0.0, 1.0);
903 glVertex2f(-1.0f, 1.0f);
904 glTexCoord2f(1.0, 1.0);
905 glVertex2f(1.0f, 1.0f);
906 glEnd();
908 glBindTexture(GL_TEXTURE_2D, buffer);
909 memset(readback, 0x7f, sizeof(readback));
910 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
911 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
912 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
914 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
915 readback[6], readback[9]);
916 ret = FALSE;
918 else
920 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
921 readback[6], readback[9]);
922 ret = TRUE;
925 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
926 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
927 glDeleteTextures(1, &tex);
928 glDeleteTextures(1, &buffer);
930 if(glGetError())
932 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
933 ret = FALSE;
935 LEAVE_GL();
936 return ret;
939 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
941 unsigned int fmt_idx, i;
942 WINED3DFORMAT fmts16[] = {
943 WINED3DFMT_R16_FLOAT,
944 WINED3DFMT_R16G16_FLOAT,
945 WINED3DFMT_R16G16B16A16_FLOAT,
947 BOOL filtered;
948 struct GlPixelFormatDesc *desc;
950 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
952 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
953 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
955 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
956 filtered = TRUE;
958 else if (gl_info->limits.glsl_varyings > 44)
960 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
961 filtered = TRUE;
963 else
965 TRACE("Assuming no float16 blending\n");
966 filtered = FALSE;
969 if(filtered)
971 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
973 fmt_idx = getFmtIdx(fmts16[i]);
974 gl_info->gl_formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
977 return;
980 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
982 fmt_idx = getFmtIdx(fmts16[i]);
983 desc = &gl_info->gl_formats[fmt_idx];
984 if(!desc->glInternal) continue; /* Not supported by GL */
986 filtered = check_filter(gl_info, gl_info->gl_formats[fmt_idx].glInternal);
987 if(filtered)
989 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
990 desc->Flags |= WINED3DFMT_FLAG_FILTERING;
992 else
994 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
999 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1001 int idx;
1003 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1004 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1005 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1007 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1008 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1009 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1011 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1012 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1013 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1015 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1016 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1017 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1019 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1020 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1021 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1023 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1024 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1025 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1026 * the only driver that implements it(fglrx) has a buggy implementation.
1028 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1029 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1030 * conversion for this format.
1032 if (!gl_info->supported[NV_TEXTURE_SHADER])
1034 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1035 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1036 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1037 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1038 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1039 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1041 else
1043 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1044 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1045 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1046 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1047 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1048 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1051 if (!gl_info->supported[NV_TEXTURE_SHADER])
1053 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1054 * with each other
1056 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1057 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1058 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1059 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1060 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1061 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1062 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1063 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1064 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1066 else
1068 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1069 * are converted at surface loading time, but they do not need any modification in
1070 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1071 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1075 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1077 idx = getFmtIdx(WINED3DFMT_ATI2N);
1078 gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
1079 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1081 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1083 idx = getFmtIdx(WINED3DFMT_ATI2N);
1084 gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
1085 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1088 if (!gl_info->supported[APPLE_YCBCR_422])
1090 idx = getFmtIdx(WINED3DFMT_YUY2);
1091 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1093 idx = getFmtIdx(WINED3DFMT_UYVY);
1094 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1097 idx = getFmtIdx(WINED3DFMT_YV12);
1098 gl_info->gl_formats[idx].heightscale = 1.5f;
1099 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1101 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1102 gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1104 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1106 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1107 gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
1110 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1112 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1113 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1114 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1115 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1117 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1118 gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1122 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1124 unsigned int i;
1126 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1128 struct GlPixelFormatDesc *format_desc;
1129 int fmt_idx = getFmtIdx(format_vertex_info[i].format);
1131 if (fmt_idx == -1)
1133 ERR("Format %s (%#x) not found.\n",
1134 debug_d3dformat(format_vertex_info[i].format), format_vertex_info[i].format);
1135 return FALSE;
1138 format_desc = &gl_info->gl_formats[fmt_idx];
1139 format_desc->emit_idx = format_vertex_info[i].emit_idx;
1140 format_desc->component_count = format_vertex_info[i].component_count;
1141 format_desc->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1142 format_desc->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1143 format_desc->gl_normalized = format_vertex_info[i].gl_normalized;
1144 format_desc->component_size = format_vertex_info[i].component_size;
1147 return TRUE;
1150 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1152 if (!init_format_base_info(gl_info)) return FALSE;
1154 if (!init_format_compression_info(gl_info))
1156 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1157 gl_info->gl_formats = NULL;
1158 return FALSE;
1161 return TRUE;
1164 /* Context activation is done by the caller. */
1165 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1167 if (!init_format_base_info(gl_info)) return FALSE;
1169 if (!init_format_compression_info(gl_info)) goto fail;
1170 if (!init_format_texture_info(gl_info)) goto fail;
1171 if (!init_format_vertex_info(gl_info)) goto fail;
1173 apply_format_fixups(gl_info);
1174 init_format_fbo_compat_info(gl_info);
1175 init_format_filter_info(gl_info, vendor);
1177 return TRUE;
1179 fail:
1180 HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
1181 gl_info->gl_formats = NULL;
1182 return FALSE;
1185 const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info)
1187 int idx = getFmtIdx(fmt);
1189 if(idx == -1) {
1190 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
1191 /* Get the caller a valid pointer */
1192 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1195 return &gl_info->gl_formats[idx];
1198 /*****************************************************************************
1199 * Trace formatting of useful values
1201 const char* debug_d3dformat(WINED3DFORMAT fmt) {
1202 switch (fmt) {
1203 #define FMT_TO_STR(fmt) case fmt: return #fmt
1204 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1205 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1206 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1207 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1208 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1209 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1210 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1211 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1212 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1213 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1214 FMT_TO_STR(WINED3DFMT_P8_UINT);
1215 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1216 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1217 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1218 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1219 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1220 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1221 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1222 FMT_TO_STR(WINED3DFMT_UYVY);
1223 FMT_TO_STR(WINED3DFMT_YUY2);
1224 FMT_TO_STR(WINED3DFMT_YV12);
1225 FMT_TO_STR(WINED3DFMT_DXT1);
1226 FMT_TO_STR(WINED3DFMT_DXT2);
1227 FMT_TO_STR(WINED3DFMT_DXT3);
1228 FMT_TO_STR(WINED3DFMT_DXT4);
1229 FMT_TO_STR(WINED3DFMT_DXT5);
1230 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1231 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1232 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1233 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1234 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1235 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1236 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1237 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1238 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1239 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1240 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1241 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1242 FMT_TO_STR(WINED3DFMT_ATI2N);
1243 FMT_TO_STR(WINED3DFMT_NVHU);
1244 FMT_TO_STR(WINED3DFMT_NVHS);
1245 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1246 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1247 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1248 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1249 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1250 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1251 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1252 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1253 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1254 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1255 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1256 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1257 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1258 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1259 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1260 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1261 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1262 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1263 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1264 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1265 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1266 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1267 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1268 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1269 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1270 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1271 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1272 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1273 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1274 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1275 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1276 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1277 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1278 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1279 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1280 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1281 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1282 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1283 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1284 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1285 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1286 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1287 FMT_TO_STR(WINED3DFMT_R32_UINT);
1288 FMT_TO_STR(WINED3DFMT_R32_SINT);
1289 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1290 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1291 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1292 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1293 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1294 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1295 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1296 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1297 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1298 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1299 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1300 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1301 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1302 FMT_TO_STR(WINED3DFMT_R16_UINT);
1303 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1304 FMT_TO_STR(WINED3DFMT_R16_SINT);
1305 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1306 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1307 FMT_TO_STR(WINED3DFMT_R8_UINT);
1308 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1309 FMT_TO_STR(WINED3DFMT_R8_SINT);
1310 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1311 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1312 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1313 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1314 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1315 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1316 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1317 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1318 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1319 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1320 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1321 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1322 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1323 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1324 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1325 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1326 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1327 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1328 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1329 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1330 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1331 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1332 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1333 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1334 #undef FMT_TO_STR
1335 default:
1337 char fourcc[5];
1338 fourcc[0] = (char)(fmt);
1339 fourcc[1] = (char)(fmt >> 8);
1340 fourcc[2] = (char)(fmt >> 16);
1341 fourcc[3] = (char)(fmt >> 24);
1342 fourcc[4] = 0;
1343 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
1344 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
1345 else
1346 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
1348 return "unrecognized";
1352 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
1353 switch (devtype) {
1354 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1355 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1356 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1357 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1358 #undef DEVTYPE_TO_STR
1359 default:
1360 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1361 return "unrecognized";
1365 const char *debug_d3dusage(DWORD usage)
1367 char buf[284];
1369 buf[0] = '\0';
1370 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1371 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1372 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1373 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1374 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1375 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1376 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1377 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1378 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1379 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1380 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1381 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1382 #undef WINED3DUSAGE_TO_STR
1383 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1385 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1388 const char *debug_d3dusagequery(DWORD usagequery)
1390 char buf[238];
1392 buf[0] = '\0';
1393 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1394 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1395 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1396 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1397 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1398 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1399 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1400 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1401 #undef WINED3DUSAGEQUERY_TO_STR
1402 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1404 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1407 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1408 switch (method) {
1409 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1410 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1411 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1412 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1413 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1414 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1415 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1416 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1417 #undef WINED3DDECLMETHOD_TO_STR
1418 default:
1419 FIXME("Unrecognized %u declaration method!\n", method);
1420 return "unrecognized";
1424 const char* debug_d3ddeclusage(BYTE usage) {
1425 switch (usage) {
1426 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1427 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1428 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1429 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1430 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1431 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1432 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1433 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1434 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1435 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1436 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1437 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1438 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1439 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1440 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1441 #undef WINED3DDECLUSAGE_TO_STR
1442 default:
1443 FIXME("Unrecognized %u declaration usage!\n", usage);
1444 return "unrecognized";
1448 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
1449 switch (res) {
1450 #define RES_TO_STR(res) case res: return #res
1451 RES_TO_STR(WINED3DRTYPE_SURFACE);
1452 RES_TO_STR(WINED3DRTYPE_VOLUME);
1453 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1454 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1455 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1456 RES_TO_STR(WINED3DRTYPE_BUFFER);
1457 #undef RES_TO_STR
1458 default:
1459 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1460 return "unrecognized";
1464 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
1465 switch (PrimitiveType) {
1466 #define PRIM_TO_STR(prim) case prim: return #prim
1467 PRIM_TO_STR(WINED3DPT_UNDEFINED);
1468 PRIM_TO_STR(WINED3DPT_POINTLIST);
1469 PRIM_TO_STR(WINED3DPT_LINELIST);
1470 PRIM_TO_STR(WINED3DPT_LINESTRIP);
1471 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
1472 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
1473 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
1474 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
1475 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
1476 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
1477 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
1478 #undef PRIM_TO_STR
1479 default:
1480 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
1481 return "unrecognized";
1485 const char* debug_d3drenderstate(DWORD state) {
1486 switch (state) {
1487 #define D3DSTATE_TO_STR(u) case u: return #u
1488 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
1489 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
1490 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
1491 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
1492 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
1493 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
1494 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
1495 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
1496 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
1497 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
1498 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
1499 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
1500 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
1501 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
1502 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
1503 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
1504 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
1505 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
1506 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
1507 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
1508 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
1509 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
1510 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
1511 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
1512 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
1513 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
1514 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
1515 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
1516 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
1517 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
1518 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
1519 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
1520 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
1521 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
1522 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
1523 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
1524 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
1525 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
1526 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
1527 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
1528 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
1529 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
1530 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
1531 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
1532 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
1533 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
1534 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
1535 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
1536 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
1537 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
1538 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
1539 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
1540 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
1541 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
1542 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
1543 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
1544 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
1545 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
1546 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
1547 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
1548 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
1549 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
1550 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
1551 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
1552 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
1553 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
1554 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
1555 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
1556 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
1557 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
1558 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
1559 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
1560 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
1561 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
1562 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
1563 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
1564 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
1565 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
1566 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
1567 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
1568 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
1569 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
1570 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
1571 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
1572 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
1573 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
1574 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
1575 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
1576 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
1577 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
1578 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
1579 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
1580 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
1581 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
1582 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
1583 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
1584 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
1585 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
1586 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
1587 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
1588 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
1589 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
1590 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
1591 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
1592 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
1593 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
1594 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
1595 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
1596 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
1597 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
1598 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
1599 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
1600 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
1601 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
1602 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
1603 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
1604 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
1605 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
1606 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
1607 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
1608 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
1609 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
1610 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
1611 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
1612 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
1613 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
1614 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
1615 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
1616 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
1617 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
1618 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
1619 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
1620 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
1621 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
1622 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
1623 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
1624 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
1625 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
1626 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
1627 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
1628 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
1629 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
1630 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
1631 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
1632 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
1633 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
1634 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
1635 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
1636 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
1637 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
1638 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
1639 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
1640 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
1641 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
1642 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
1643 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
1644 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
1645 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
1646 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
1647 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
1648 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
1649 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
1650 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
1651 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
1652 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
1653 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
1654 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
1655 #undef D3DSTATE_TO_STR
1656 default:
1657 FIXME("Unrecognized %u render state!\n", state);
1658 return "unrecognized";
1662 const char* debug_d3dsamplerstate(DWORD state) {
1663 switch (state) {
1664 #define D3DSTATE_TO_STR(u) case u: return #u
1665 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
1666 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
1667 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
1668 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
1669 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
1670 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
1671 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
1672 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
1673 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
1674 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
1675 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
1676 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
1677 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
1678 #undef D3DSTATE_TO_STR
1679 default:
1680 FIXME("Unrecognized %u sampler state!\n", state);
1681 return "unrecognized";
1685 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
1686 switch (filter_type) {
1687 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1688 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1689 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1690 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1691 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1692 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1693 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1694 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1695 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1696 #undef D3DTEXTUREFILTERTYPE_TO_STR
1697 default:
1698 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1699 return "unrecognized";
1703 const char* debug_d3dtexturestate(DWORD state) {
1704 switch (state) {
1705 #define D3DSTATE_TO_STR(u) case u: return #u
1706 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1707 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1708 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1709 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1710 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1711 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1712 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1713 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1714 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1715 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1716 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1717 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1718 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1719 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1720 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1721 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1722 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1723 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1724 #undef D3DSTATE_TO_STR
1725 default:
1726 FIXME("Unrecognized %u texture state!\n", state);
1727 return "unrecognized";
1731 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1732 switch (d3dtop) {
1733 #define D3DTOP_TO_STR(u) case u: return #u
1734 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1735 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1736 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1737 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1738 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1739 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1740 D3DTOP_TO_STR(WINED3DTOP_ADD);
1741 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1742 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1743 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1744 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1745 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1746 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1747 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1748 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1749 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1750 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1751 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1752 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1753 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1754 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1755 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1756 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1757 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1758 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1759 D3DTOP_TO_STR(WINED3DTOP_LERP);
1760 #undef D3DTOP_TO_STR
1761 default:
1762 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1763 return "unrecognized";
1767 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1768 switch (tstype) {
1769 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1770 TSTYPE_TO_STR(WINED3DTS_VIEW);
1771 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1772 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1773 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1774 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1775 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1776 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1777 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1778 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1779 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1780 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1781 #undef TSTYPE_TO_STR
1782 default:
1783 if (tstype > 256 && tstype < 512) {
1784 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1785 return ("WINED3DTS_WORLDMATRIX > 0");
1787 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1788 return "unrecognized";
1792 const char *debug_d3dstate(DWORD state)
1794 if (STATE_IS_RENDER(state))
1795 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
1796 if (STATE_IS_TEXTURESTAGE(state))
1798 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
1799 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
1800 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
1801 texture_stage, debug_d3dtexturestate(texture_state));
1803 if (STATE_IS_SAMPLER(state))
1804 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
1805 if (STATE_IS_PIXELSHADER(state))
1806 return "STATE_PIXELSHADER";
1807 if (STATE_IS_TRANSFORM(state))
1808 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
1809 if (STATE_IS_STREAMSRC(state))
1810 return "STATE_STREAMSRC";
1811 if (STATE_IS_INDEXBUFFER(state))
1812 return "STATE_INDEXBUFFER";
1813 if (STATE_IS_VDECL(state))
1814 return "STATE_VDECL";
1815 if (STATE_IS_VSHADER(state))
1816 return "STATE_VSHADER";
1817 if (STATE_IS_VIEWPORT(state))
1818 return "STATE_VIEWPORT";
1819 if (STATE_IS_VERTEXSHADERCONSTANT(state))
1820 return "STATE_VERTEXSHADERCONSTANT";
1821 if (STATE_IS_PIXELSHADERCONSTANT(state))
1822 return "STATE_PIXELSHADERCONSTANT";
1823 if (STATE_IS_ACTIVELIGHT(state))
1824 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
1825 if (STATE_IS_SCISSORRECT(state))
1826 return "STATE_SCISSORRECT";
1827 if (STATE_IS_CLIPPLANE(state))
1828 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
1829 if (STATE_IS_MATERIAL(state))
1830 return "STATE_MATERIAL";
1831 if (STATE_IS_FRONTFACE(state))
1832 return "STATE_FRONTFACE";
1834 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
1837 const char* debug_d3dpool(WINED3DPOOL Pool) {
1838 switch (Pool) {
1839 #define POOL_TO_STR(p) case p: return #p
1840 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1841 POOL_TO_STR(WINED3DPOOL_MANAGED);
1842 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1843 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1844 #undef POOL_TO_STR
1845 default:
1846 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1847 return "unrecognized";
1851 const char *debug_fbostatus(GLenum status) {
1852 switch(status) {
1853 #define FBOSTATUS_TO_STR(u) case u: return #u
1854 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
1855 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
1856 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
1857 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1858 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1859 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
1860 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
1861 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
1862 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
1863 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
1864 #undef FBOSTATUS_TO_STR
1865 default:
1866 FIXME("Unrecognied FBO status 0x%08x\n", status);
1867 return "unrecognized";
1871 const char *debug_glerror(GLenum error) {
1872 switch(error) {
1873 #define GLERROR_TO_STR(u) case u: return #u
1874 GLERROR_TO_STR(GL_NO_ERROR);
1875 GLERROR_TO_STR(GL_INVALID_ENUM);
1876 GLERROR_TO_STR(GL_INVALID_VALUE);
1877 GLERROR_TO_STR(GL_INVALID_OPERATION);
1878 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1879 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1880 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1881 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
1882 #undef GLERROR_TO_STR
1883 default:
1884 FIXME("Unrecognied GL error 0x%08x\n", error);
1885 return "unrecognized";
1889 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1890 switch(basis) {
1891 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1892 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1893 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1894 default: return "unrecognized";
1898 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1899 switch(degree) {
1900 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1901 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1902 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1903 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1904 default: return "unrecognized";
1908 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
1910 switch(source)
1912 #define WINED3D_TO_STR(x) case x: return #x
1913 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1914 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1915 WINED3D_TO_STR(CHANNEL_SOURCE_X);
1916 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1917 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1918 WINED3D_TO_STR(CHANNEL_SOURCE_W);
1919 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
1920 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
1921 #undef WINED3D_TO_STR
1922 default:
1923 FIXME("Unrecognized fixup_channel_source %#x\n", source);
1924 return "unrecognized";
1928 static const char *debug_complex_fixup(enum complex_fixup fixup)
1930 switch(fixup)
1932 #define WINED3D_TO_STR(x) case x: return #x
1933 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
1934 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
1935 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
1936 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
1937 #undef WINED3D_TO_STR
1938 default:
1939 FIXME("Unrecognized complex fixup %#x\n", fixup);
1940 return "unrecognized";
1944 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1946 if (is_complex_fixup(fixup))
1948 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
1949 return;
1952 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1953 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1954 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1955 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1958 const char *debug_surflocation(DWORD flag) {
1959 char buf[128];
1961 buf[0] = 0;
1962 if(flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");
1963 if(flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");
1964 if(flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");
1965 if(flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");
1966 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
1969 /*****************************************************************************
1970 * Useful functions mapping GL <-> D3D values
1972 GLenum StencilOp(DWORD op) {
1973 switch(op) {
1974 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1975 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1976 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1977 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1978 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1979 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1980 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1981 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1982 default:
1983 FIXME("Unrecognized stencil op %d\n", op);
1984 return GL_KEEP;
1988 GLenum CompareFunc(DWORD func) {
1989 switch ((WINED3DCMPFUNC)func) {
1990 case WINED3DCMP_NEVER : return GL_NEVER;
1991 case WINED3DCMP_LESS : return GL_LESS;
1992 case WINED3DCMP_EQUAL : return GL_EQUAL;
1993 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1994 case WINED3DCMP_GREATER : return GL_GREATER;
1995 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1996 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1997 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1998 default:
1999 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2000 return 0;
2004 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
2005 if (op == WINED3DTOP_DISABLE) return FALSE;
2006 if (This->stateBlock->textures[stage]) return FALSE;
2008 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2009 && op != WINED3DTOP_SELECTARG2) return TRUE;
2010 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2011 && op != WINED3DTOP_SELECTARG1) return TRUE;
2012 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2013 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2015 return FALSE;
2018 /* Setup this textures matrix according to the texture flags*/
2019 /* GL locking is done by the caller (state handler) */
2020 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2021 WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
2023 float mat[16];
2025 glMatrixMode(GL_TEXTURE);
2026 checkGLcall("glMatrixMode(GL_TEXTURE)");
2028 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2029 glLoadIdentity();
2030 checkGLcall("glLoadIdentity()");
2031 return;
2034 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2035 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2036 return;
2039 memcpy(mat, smat, 16 * sizeof(float));
2041 if (flags & WINED3DTTFF_PROJECTED) {
2042 if(!ffp_proj_control) {
2043 switch (flags & ~WINED3DTTFF_PROJECTED) {
2044 case WINED3DTTFF_COUNT2:
2045 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2046 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2047 break;
2048 case WINED3DTTFF_COUNT3:
2049 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2050 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2051 break;
2054 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2055 if(!calculatedCoords) {
2056 switch(vtx_fmt)
2058 case WINED3DFMT_R32_FLOAT:
2059 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2060 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2061 * the input value to the transformation will be 0, so the matrix value is irrelevant
2063 mat[12] = mat[4];
2064 mat[13] = mat[5];
2065 mat[14] = mat[6];
2066 mat[15] = mat[7];
2067 break;
2068 case WINED3DFMT_R32G32_FLOAT:
2069 /* See above, just 3rd and 4th coord
2071 mat[12] = mat[8];
2072 mat[13] = mat[9];
2073 mat[14] = mat[10];
2074 mat[15] = mat[11];
2075 break;
2076 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2077 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2079 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2080 * into a bad place. The division elimination below will apply to make sure the
2081 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2083 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2084 break;
2085 default:
2086 FIXME("Unexpected fixed function texture coord input\n");
2089 if(!ffp_proj_control) {
2090 switch (flags & ~WINED3DTTFF_PROJECTED) {
2091 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2092 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2093 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2094 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2095 * the 4th coord evaluates to 1.0 to eliminate that.
2097 * If the fixed function pipeline is used, the 4th value remains unused,
2098 * so there is no danger in doing this. With vertex shaders we have a
2099 * problem. Should an app hit that problem, the code here would have to
2100 * check for pixel shaders, and the shader has to undo the default gl divide.
2102 * A more serious problem occurs if the app passes 4 coordinates in, and the
2103 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2104 * or a replacement shader
2106 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2111 glLoadMatrixf(mat);
2112 checkGLcall("glLoadMatrixf(mat)");
2115 /* This small helper function is used to convert a bitmask into the number of masked bits */
2116 unsigned int count_bits(unsigned int mask)
2118 unsigned int count;
2119 for (count = 0; mask; ++count)
2121 mask &= mask - 1;
2123 return count;
2126 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2127 * The later function requires individual color components. */
2128 BOOL getColorBits(const struct GlPixelFormatDesc *format_desc,
2129 short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2131 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2132 switch(format_desc->format)
2134 case WINED3DFMT_B8G8R8X8_UNORM:
2135 case WINED3DFMT_B8G8R8_UNORM:
2136 case WINED3DFMT_B8G8R8A8_UNORM:
2137 case WINED3DFMT_R8G8B8A8_UNORM:
2138 case WINED3DFMT_B10G10R10A2_UNORM:
2139 case WINED3DFMT_B5G5R5X1_UNORM:
2140 case WINED3DFMT_B5G5R5A1_UNORM:
2141 case WINED3DFMT_B5G6R5_UNORM:
2142 case WINED3DFMT_B4G4R4X4_UNORM:
2143 case WINED3DFMT_B4G4R4A4_UNORM:
2144 case WINED3DFMT_B2G3R3_UNORM:
2145 case WINED3DFMT_P8_UINT_A8_UNORM:
2146 case WINED3DFMT_P8_UINT:
2147 break;
2148 default:
2149 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc->format));
2150 return FALSE;
2153 *redSize = count_bits(format_desc->red_mask);
2154 *greenSize = count_bits(format_desc->green_mask);
2155 *blueSize = count_bits(format_desc->blue_mask);
2156 *alphaSize = count_bits(format_desc->alpha_mask);
2157 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2159 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
2160 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format_desc->format));
2161 return TRUE;
2164 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2165 BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize)
2167 TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
2168 switch(format_desc->format)
2170 case WINED3DFMT_D16_LOCKABLE:
2171 case WINED3DFMT_D16_UNORM:
2172 case WINED3DFMT_S1_UINT_D15_UNORM:
2173 case WINED3DFMT_X8D24_UNORM:
2174 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2175 case WINED3DFMT_D24_UNORM_S8_UINT:
2176 case WINED3DFMT_S8_UINT_D24_FLOAT:
2177 case WINED3DFMT_D32_UNORM:
2178 case WINED3DFMT_D32_FLOAT:
2179 break;
2180 default:
2181 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc->format));
2182 return FALSE;
2185 *depthSize = format_desc->depth_size;
2186 *stencilSize = format_desc->stencil_size;
2188 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
2189 *depthSize, *stencilSize, debug_d3dformat(format_desc->format));
2190 return TRUE;
2193 /* DirectDraw stuff */
2194 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2195 switch(depth) {
2196 case 8: return WINED3DFMT_P8_UINT;
2197 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2198 case 16: return WINED3DFMT_B5G6R5_UNORM;
2199 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2200 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2201 default: return WINED3DFMT_UNKNOWN;
2205 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2206 WINED3DMATRIX temp;
2208 /* Now do the multiplication 'by hand'.
2209 I know that all this could be optimised, but this will be done later :-) */
2210 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);
2211 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);
2212 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);
2213 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);
2215 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);
2216 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);
2217 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);
2218 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);
2220 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);
2221 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);
2222 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);
2223 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);
2225 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);
2226 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);
2227 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);
2228 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);
2230 /* And copy the new matrix in the good storage.. */
2231 memcpy(dest, &temp, 16 * sizeof(float));
2234 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2235 DWORD size = 0;
2236 int i;
2237 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2239 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2240 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2241 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2242 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2243 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2244 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2245 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2246 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2247 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2248 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2249 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2250 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2251 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2252 default: ERR("Unexpected position mask\n");
2254 for (i = 0; i < numTextures; i++) {
2255 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2258 return size;
2261 /***********************************************************************
2262 * CalculateTexRect
2264 * Calculates the dimensions of the opengl texture used for blits.
2265 * Handled oversized opengl textures and updates the source rectangle
2266 * accordingly
2268 * Params:
2269 * This: Surface to operate on
2270 * Rect: Requested rectangle
2272 * Returns:
2273 * TRUE if the texture part can be loaded,
2274 * FALSE otherwise
2276 *********************************************************************/
2277 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4])
2279 const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info;
2280 int x1 = Rect->left, x2 = Rect->right;
2281 int y1 = Rect->top, y2 = Rect->bottom;
2282 GLint maxSize = gl_info->limits.texture_size;
2284 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2285 Rect->left, Rect->top, Rect->right, Rect->bottom);
2287 /* The sizes might be reversed */
2288 if(Rect->left > Rect->right) {
2289 x1 = Rect->right;
2290 x2 = Rect->left;
2292 if(Rect->top > Rect->bottom) {
2293 y1 = Rect->bottom;
2294 y2 = Rect->top;
2297 /* No oversized texture? This is easy */
2298 if(!(This->Flags & SFLAG_OVERSIZE)) {
2299 /* Which rect from the texture do I need? */
2300 if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
2302 glTexCoord[0] = (float) Rect->left;
2303 glTexCoord[2] = (float) Rect->top;
2304 glTexCoord[1] = (float) Rect->right;
2305 glTexCoord[3] = (float) Rect->bottom;
2306 } else {
2307 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2308 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2309 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2310 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2313 return TRUE;
2314 } else {
2315 /* Check if we can succeed at all */
2316 if( (x2 - x1) > maxSize ||
2317 (y2 - y1) > maxSize ) {
2318 TRACE("Requested rectangle is too large for gl\n");
2319 return FALSE;
2322 /* A part of the texture has to be picked. First, check if
2323 * some texture part is loaded already, if yes try to re-use it.
2324 * If the texture is dirty, or the part can't be used,
2325 * re-position the part to load
2327 if(This->Flags & SFLAG_INTEXTURE) {
2328 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2329 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2330 /* Ok, the rectangle is ok, re-use it */
2331 TRACE("Using existing gl Texture\n");
2332 } else {
2333 /* Rectangle is not ok, dirtify the texture to reload it */
2334 TRACE("Dirtifying texture to force reload\n");
2335 This->Flags &= ~SFLAG_INTEXTURE;
2339 /* Now if we are dirty(no else if!) */
2340 if(!(This->Flags & SFLAG_INTEXTURE)) {
2341 /* Set the new rectangle. Use the following strategy:
2342 * 1) Use as big textures as possible.
2343 * 2) Place the texture part in the way that the requested
2344 * part is in the middle of the texture(well, almost)
2345 * 3) If the texture is moved over the edges of the
2346 * surface, replace it nicely
2347 * 4) If the coord is not limiting the texture size,
2348 * use the whole size
2350 if((This->pow2Width) > maxSize) {
2351 This->glRect.left = x1 - maxSize / 2;
2352 if(This->glRect.left < 0) {
2353 This->glRect.left = 0;
2355 This->glRect.right = This->glRect.left + maxSize;
2356 if(This->glRect.right > This->currentDesc.Width) {
2357 This->glRect.right = This->currentDesc.Width;
2358 This->glRect.left = This->glRect.right - maxSize;
2360 } else {
2361 This->glRect.left = 0;
2362 This->glRect.right = This->pow2Width;
2365 if (This->pow2Height > maxSize)
2367 This->glRect.top = x1 - gl_info->limits.texture_size / 2;
2368 if(This->glRect.top < 0) This->glRect.top = 0;
2369 This->glRect.bottom = This->glRect.left + maxSize;
2370 if(This->glRect.bottom > This->currentDesc.Height) {
2371 This->glRect.bottom = This->currentDesc.Height;
2372 This->glRect.top = This->glRect.bottom - maxSize;
2374 } else {
2375 This->glRect.top = 0;
2376 This->glRect.bottom = This->pow2Height;
2378 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2379 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2382 /* Re-calculate the rect to draw */
2383 Rect->left -= This->glRect.left;
2384 Rect->right -= This->glRect.left;
2385 Rect->top -= This->glRect.top;
2386 Rect->bottom -= This->glRect.top;
2388 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2389 * or the pow2Width / pow2Height of the surface.
2391 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
2392 * as regular GL_TEXTURE_2D.
2394 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2395 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2396 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2397 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2399 return TRUE;
2402 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
2403 #define ARG1 0x01
2404 #define ARG2 0x02
2405 #define ARG0 0x04
2406 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2407 /* undefined */ 0,
2408 /* D3DTOP_DISABLE */ 0,
2409 /* D3DTOP_SELECTARG1 */ ARG1,
2410 /* D3DTOP_SELECTARG2 */ ARG2,
2411 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2412 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2413 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2414 /* D3DTOP_ADD */ ARG1 | ARG2,
2415 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2416 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2417 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2418 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2419 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2420 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2421 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2422 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2423 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2424 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2425 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2426 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2427 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2428 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2429 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2430 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2431 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2432 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2433 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2435 unsigned int i;
2436 DWORD ttff;
2437 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2438 IWineD3DDeviceImpl *device = stateblock->device;
2439 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2441 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2443 IWineD3DBaseTextureImpl *texture;
2444 settings->op[i].padding = 0;
2445 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
2446 settings->op[i].cop = WINED3DTOP_DISABLE;
2447 settings->op[i].aop = WINED3DTOP_DISABLE;
2448 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2449 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2450 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2451 settings->op[i].dst = resultreg;
2452 settings->op[i].tex_type = tex_1d;
2453 settings->op[i].projected = proj_none;
2454 i++;
2455 break;
2458 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
2459 if(texture) {
2460 settings->op[i].color_fixup = texture->resource.format_desc->color_fixup;
2461 if(ignore_textype) {
2462 settings->op[i].tex_type = tex_1d;
2463 } else {
2464 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
2465 case GL_TEXTURE_1D:
2466 settings->op[i].tex_type = tex_1d;
2467 break;
2468 case GL_TEXTURE_2D:
2469 settings->op[i].tex_type = tex_2d;
2470 break;
2471 case GL_TEXTURE_3D:
2472 settings->op[i].tex_type = tex_3d;
2473 break;
2474 case GL_TEXTURE_CUBE_MAP_ARB:
2475 settings->op[i].tex_type = tex_cube;
2476 break;
2477 case GL_TEXTURE_RECTANGLE_ARB:
2478 settings->op[i].tex_type = tex_rect;
2479 break;
2482 } else {
2483 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2484 settings->op[i].tex_type = tex_1d;
2487 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
2488 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
2490 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2491 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2492 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2494 if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
2495 carg0 = ARG_UNUSED;
2496 carg2 = ARG_UNUSED;
2497 carg1 = WINED3DTA_CURRENT;
2498 cop = WINED3DTOP_SELECTARG1;
2501 if(cop == WINED3DTOP_DOTPRODUCT3) {
2502 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2503 * the color result to the alpha component of the destination
2505 aop = cop;
2506 aarg1 = carg1;
2507 aarg2 = carg2;
2508 aarg0 = carg0;
2509 } else {
2510 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2511 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2512 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2515 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2517 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2519 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2521 IWineD3DSurfaceImpl *surf;
2522 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2524 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
2526 if (aop == WINED3DTOP_DISABLE)
2528 aarg1 = WINED3DTA_TEXTURE;
2529 aop = WINED3DTOP_SELECTARG1;
2531 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2533 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2535 aarg2 = WINED3DTA_TEXTURE;
2536 aop = WINED3DTOP_MODULATE;
2538 else aarg1 = WINED3DTA_TEXTURE;
2540 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2542 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2544 aarg1 = WINED3DTA_TEXTURE;
2545 aop = WINED3DTOP_MODULATE;
2547 else aarg2 = WINED3DTA_TEXTURE;
2553 if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
2554 aarg0 = ARG_UNUSED;
2555 aarg2 = ARG_UNUSED;
2556 aarg1 = WINED3DTA_CURRENT;
2557 aop = WINED3DTOP_SELECTARG1;
2560 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2561 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2562 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2563 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2564 settings->op[i].projected = proj_count3;
2565 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2566 settings->op[i].projected = proj_count4;
2567 } else {
2568 settings->op[i].projected = proj_none;
2570 } else {
2571 settings->op[i].projected = proj_none;
2574 settings->op[i].cop = cop;
2575 settings->op[i].aop = aop;
2576 settings->op[i].carg0 = carg0;
2577 settings->op[i].carg1 = carg1;
2578 settings->op[i].carg2 = carg2;
2579 settings->op[i].aarg0 = aarg0;
2580 settings->op[i].aarg1 = aarg1;
2581 settings->op[i].aarg2 = aarg2;
2583 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2584 settings->op[i].dst = tempreg;
2585 } else {
2586 settings->op[i].dst = resultreg;
2590 /* Clear unsupported stages */
2591 for(; i < MAX_TEXTURES; i++) {
2592 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2595 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2596 settings->fog = FOG_OFF;
2597 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2598 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2599 settings->fog = FOG_LINEAR;
2600 } else {
2601 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2602 case WINED3DFOG_NONE:
2603 case WINED3DFOG_LINEAR:
2604 settings->fog = FOG_LINEAR;
2605 break;
2606 case WINED3DFOG_EXP:
2607 settings->fog = FOG_EXP;
2608 break;
2609 case WINED3DFOG_EXP2:
2610 settings->fog = FOG_EXP2;
2611 break;
2614 } else {
2615 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2616 case WINED3DFOG_LINEAR:
2617 settings->fog = FOG_LINEAR;
2618 break;
2619 case WINED3DFOG_EXP:
2620 settings->fog = FOG_EXP;
2621 break;
2622 case WINED3DFOG_EXP2:
2623 settings->fog = FOG_EXP2;
2624 break;
2627 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2628 settings->sRGB_write = 1;
2629 } else {
2630 settings->sRGB_write = 0;
2632 if(device->vs_clipping || !use_vs(stateblock) || !stateblock->renderState[WINED3DRS_CLIPPING] ||
2633 !stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
2634 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2635 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2636 * if no clipplane is enabled
2638 settings->emul_clipplanes = 0;
2639 } else {
2640 settings->emul_clipplanes = 1;
2644 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
2645 const struct ffp_frag_settings *settings)
2647 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
2648 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
2651 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
2653 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2654 * whereas desc points to an extended structure with implementation specific parts. */
2655 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
2657 ERR("Failed to insert ffp frag shader.\n");
2661 /* Activates the texture dimension according to the bound D3D texture.
2662 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2663 * Requires the caller to activate the correct unit before
2665 /* GL locking is done by the caller (state handler) */
2666 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2668 const struct wined3d_gl_info *gl_info = context->gl_info;
2670 if (stateblock->textures[stage])
2672 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2673 case GL_TEXTURE_2D:
2674 glDisable(GL_TEXTURE_3D);
2675 checkGLcall("glDisable(GL_TEXTURE_3D)");
2676 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2678 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2679 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2681 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2683 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2684 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2686 glEnable(GL_TEXTURE_2D);
2687 checkGLcall("glEnable(GL_TEXTURE_2D)");
2688 break;
2689 case GL_TEXTURE_RECTANGLE_ARB:
2690 glDisable(GL_TEXTURE_2D);
2691 checkGLcall("glDisable(GL_TEXTURE_2D)");
2692 glDisable(GL_TEXTURE_3D);
2693 checkGLcall("glDisable(GL_TEXTURE_3D)");
2694 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2696 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2697 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2699 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2700 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2701 break;
2702 case GL_TEXTURE_3D:
2703 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2705 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2706 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2708 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2710 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2711 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2713 glDisable(GL_TEXTURE_2D);
2714 checkGLcall("glDisable(GL_TEXTURE_2D)");
2715 glEnable(GL_TEXTURE_3D);
2716 checkGLcall("glEnable(GL_TEXTURE_3D)");
2717 break;
2718 case GL_TEXTURE_CUBE_MAP_ARB:
2719 glDisable(GL_TEXTURE_2D);
2720 checkGLcall("glDisable(GL_TEXTURE_2D)");
2721 glDisable(GL_TEXTURE_3D);
2722 checkGLcall("glDisable(GL_TEXTURE_3D)");
2723 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2725 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2726 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2728 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2729 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2730 break;
2732 } else {
2733 glEnable(GL_TEXTURE_2D);
2734 checkGLcall("glEnable(GL_TEXTURE_2D)");
2735 glDisable(GL_TEXTURE_3D);
2736 checkGLcall("glDisable(GL_TEXTURE_3D)");
2737 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2739 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2740 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2742 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
2744 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2745 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2747 /* Binding textures is done by samplers. A dummy texture will be bound */
2751 /* GL locking is done by the caller (state handler) */
2752 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2754 DWORD sampler = state - STATE_SAMPLER(0);
2755 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
2757 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2758 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2759 * will take care of this business
2761 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
2762 if(sampler >= stateblock->lowest_disabled_stage) return;
2763 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2765 texture_activate_dimensions(sampler, stateblock, context);
2768 void *wined3d_rb_alloc(size_t size)
2770 return HeapAlloc(GetProcessHeap(), 0, size);
2773 void *wined3d_rb_realloc(void *ptr, size_t size)
2775 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
2778 void wined3d_rb_free(void *ptr)
2780 HeapFree(GetProcessHeap(), 0, ptr);
2783 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
2785 const struct ffp_frag_settings *ka = key;
2786 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
2788 return memcmp(ka, kb, sizeof(*ka));
2791 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
2793 wined3d_rb_alloc,
2794 wined3d_rb_realloc,
2795 wined3d_rb_free,
2796 ffp_frag_program_key_compare,
2799 UINT wined3d_log2i(UINT32 x)
2801 static const UINT l[] =
2803 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2804 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2805 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2806 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2807 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2808 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2809 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2810 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2811 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2812 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2813 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2814 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2815 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2816 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2817 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2818 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2820 UINT32 i;
2822 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
2825 /* Set the shader type for this device, depending on the given capabilities
2826 * and the user preferences in wined3d_settings. */
2827 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
2829 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
2830 else if (gl_info->supported[ARB_VERTEX_SHADER] && wined3d_settings.glslRequested)
2832 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
2833 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
2834 * shaders only on this card. */
2835 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
2836 else *vs_selected = SHADER_GLSL;
2838 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
2839 else *vs_selected = SHADER_NONE;
2841 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
2842 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && wined3d_settings.glslRequested) *ps_selected = SHADER_GLSL;
2843 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
2844 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
2845 else *ps_selected = SHADER_NONE;