wined3d: Pass the destination pitch to format conversion functions.
[wine.git] / dlls / wined3d / utils.c
blob3d50e29911e2e654474f2a4e8061bab7cad21852
1 /*
2 * Utility functions for the WineD3D Library
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2008 Henri Verbeet
9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
10 * Copyright 2009-2010 Henri Verbeet for CodeWeavers
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "config.h"
28 #include "wine/port.h"
30 #include <stdio.h>
32 #include "wined3d_private.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
36 struct wined3d_format_channels
38 enum wined3d_format_id id;
39 DWORD red_size, green_size, blue_size, alpha_size;
40 DWORD red_offset, green_offset, blue_offset, alpha_offset;
41 UINT bpp;
42 BYTE depth_size, stencil_size;
45 static const struct wined3d_format_channels formats[] =
47 /* size offset
48 * format id r g b a r g b a bpp depth stencil */
49 {WINED3DFMT_UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
50 /* FourCC formats */
51 {WINED3DFMT_UYVY, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
52 {WINED3DFMT_YUY2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
53 {WINED3DFMT_YV12, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
54 {WINED3DFMT_DXT1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
55 {WINED3DFMT_DXT2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
56 {WINED3DFMT_DXT3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
57 {WINED3DFMT_DXT4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
58 {WINED3DFMT_DXT5, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
59 {WINED3DFMT_MULTI2_ARGB8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
60 {WINED3DFMT_G8R8_G8B8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
61 {WINED3DFMT_R8G8_B8G8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
62 /* IEEE formats */
63 {WINED3DFMT_R32_FLOAT, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
64 {WINED3DFMT_R32G32_FLOAT, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0},
65 {WINED3DFMT_R32G32B32_FLOAT, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0},
66 {WINED3DFMT_R32G32B32A32_FLOAT, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0},
67 /* Hmm? */
68 {WINED3DFMT_R8G8_SNORM_Cx, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
69 /* Float */
70 {WINED3DFMT_R16_FLOAT, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
71 {WINED3DFMT_R16G16_FLOAT, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
72 {WINED3DFMT_R16G16_SINT, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
73 {WINED3DFMT_R16G16B16A16_FLOAT, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
74 {WINED3DFMT_R16G16B16A16_SINT, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
75 /* Palettized formats */
76 {WINED3DFMT_P8_UINT_A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 8, 2, 0, 0},
77 {WINED3DFMT_P8_UINT, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
78 /* Standard ARGB formats. */
79 {WINED3DFMT_B8G8R8_UNORM, 8, 8, 8, 0, 16, 8, 0, 0, 3, 0, 0},
80 {WINED3DFMT_B8G8R8A8_UNORM, 8, 8, 8, 8, 16, 8, 0, 24, 4, 0, 0},
81 {WINED3DFMT_B8G8R8X8_UNORM, 8, 8, 8, 0, 16, 8, 0, 0, 4, 0, 0},
82 {WINED3DFMT_B5G6R5_UNORM, 5, 6, 5, 0, 11, 5, 0, 0, 2, 0, 0},
83 {WINED3DFMT_B5G5R5X1_UNORM, 5, 5, 5, 0, 10, 5, 0, 0, 2, 0, 0},
84 {WINED3DFMT_B5G5R5A1_UNORM, 5, 5, 5, 1, 10, 5, 0, 15, 2, 0, 0},
85 {WINED3DFMT_B4G4R4A4_UNORM, 4, 4, 4, 4, 8, 4, 0, 12, 2, 0, 0},
86 {WINED3DFMT_B2G3R3_UNORM, 3, 3, 2, 0, 5, 2, 0, 0, 1, 0, 0},
87 {WINED3DFMT_A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 0, 1, 0, 0},
88 {WINED3DFMT_B2G3R3A8_UNORM, 3, 3, 2, 8, 5, 2, 0, 8, 2, 0, 0},
89 {WINED3DFMT_B4G4R4X4_UNORM, 4, 4, 4, 0, 8, 4, 0, 0, 2, 0, 0},
90 {WINED3DFMT_R10G10B10A2_UNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
91 {WINED3DFMT_R10G10B10A2_UINT, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
92 {WINED3DFMT_R10G10B10A2_SNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
93 {WINED3DFMT_R8G8B8A8_UNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
94 {WINED3DFMT_R8G8B8A8_UINT, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
95 {WINED3DFMT_R8G8B8X8_UNORM, 8, 8, 8, 0, 0, 8, 16, 0, 4, 0, 0},
96 {WINED3DFMT_R16G16_UNORM, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
97 {WINED3DFMT_B10G10R10A2_UNORM, 10, 10, 10, 2, 20, 10, 0, 30, 4, 0, 0},
98 {WINED3DFMT_R16G16B16A16_UNORM, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
99 /* Luminance */
100 {WINED3DFMT_L8_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
101 {WINED3DFMT_L8A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 8, 2, 0, 0},
102 {WINED3DFMT_L4A4_UNORM, 0, 0, 0, 4, 0, 0, 0, 4, 1, 0, 0},
103 {WINED3DFMT_L16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
104 /* Bump mapping stuff */
105 {WINED3DFMT_R8G8_SNORM, 8, 8, 0, 0, 0, 8, 0, 0, 2, 0, 0},
106 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 5, 5, 0, 0, 0, 5, 0, 0, 2, 0, 0},
107 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 8, 8, 0, 0, 0, 8, 0, 0, 4, 0, 0},
108 {WINED3DFMT_R8G8B8A8_SNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
109 {WINED3DFMT_R16G16_SNORM, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
110 {WINED3DFMT_R10G11B11_SNORM, 10, 11, 11, 0, 0, 10, 21, 0, 4, 0, 0},
111 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
112 /* Depth stencil formats */
113 {WINED3DFMT_D16_LOCKABLE, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0},
114 {WINED3DFMT_D32_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0},
115 {WINED3DFMT_S1_UINT_D15_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 15, 1},
116 {WINED3DFMT_D24_UNORM_S8_UINT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
117 {WINED3DFMT_X8D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 0},
118 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 4},
119 {WINED3DFMT_D16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0},
120 {WINED3DFMT_D32_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0},
121 {WINED3DFMT_S8_UINT_D24_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
122 {WINED3DFMT_VERTEXDATA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
123 {WINED3DFMT_R16_UINT, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
124 {WINED3DFMT_R32_UINT, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
125 {WINED3DFMT_R32G32_UINT, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0},
126 {WINED3DFMT_R32G32B32_UINT, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0},
127 {WINED3DFMT_R32G32B32A32_UINT, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0},
128 {WINED3DFMT_R16G16B16A16_SNORM, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
129 /* Vendor-specific formats */
130 {WINED3DFMT_ATI2N, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
131 {WINED3DFMT_NVDB, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
132 {WINED3DFMT_INST, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
133 {WINED3DFMT_INTZ, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
134 {WINED3DFMT_RESZ, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
135 {WINED3DFMT_NVHU, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
136 {WINED3DFMT_NVHS, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
137 {WINED3DFMT_NULL, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
138 /* Unsure about them, could not find a Windows driver that supports them */
139 {WINED3DFMT_R16, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
140 {WINED3DFMT_AL16, 0, 0, 0, 16, 0, 0, 0, 16, 4, 0, 0},
141 /* Typeless */
142 {WINED3DFMT_R8_TYPELESS, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
143 {WINED3DFMT_R8G8_TYPELESS, 8, 8, 0, 0, 0, 8, 0, 0, 2, 0, 0},
144 {WINED3DFMT_R8G8B8A8_TYPELESS, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
145 {WINED3DFMT_R16_TYPELESS, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
146 {WINED3DFMT_R16G16_TYPELESS, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
147 {WINED3DFMT_R16G16B16A16_TYPELESS, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
148 {WINED3DFMT_R32_TYPELESS, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
149 {WINED3DFMT_R32G32_TYPELESS, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0},
150 {WINED3DFMT_R32G32B32_TYPELESS, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0},
151 {WINED3DFMT_R32G32B32A32_TYPELESS, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0},
154 struct wined3d_format_base_flags
156 enum wined3d_format_id id;
157 DWORD flags;
160 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
161 * still needs to use the correct block based calculation for e.g. the
162 * resource size. */
163 static const struct wined3d_format_base_flags format_base_flags[] =
165 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
166 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
171 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
172 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
173 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
174 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
175 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
176 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_BROKEN_PITCH},
177 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
178 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
179 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
181 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
182 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
184 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
185 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
188 struct wined3d_format_block_info
190 enum wined3d_format_id id;
191 UINT block_width;
192 UINT block_height;
193 UINT block_byte_count;
194 BOOL verify;
197 static const struct wined3d_format_block_info format_block_info[] =
199 {WINED3DFMT_DXT1, 4, 4, 8, TRUE},
200 {WINED3DFMT_DXT2, 4, 4, 16, TRUE},
201 {WINED3DFMT_DXT3, 4, 4, 16, TRUE},
202 {WINED3DFMT_DXT4, 4, 4, 16, TRUE},
203 {WINED3DFMT_DXT5, 4, 4, 16, TRUE},
204 {WINED3DFMT_ATI2N, 4, 4, 16, FALSE},
205 {WINED3DFMT_YUY2, 2, 1, 4, FALSE},
206 {WINED3DFMT_UYVY, 2, 1, 4, FALSE},
209 struct wined3d_format_vertex_info
211 enum wined3d_format_id id;
212 enum wined3d_ffp_emit_idx emit_idx;
213 GLint component_count;
214 GLenum gl_vtx_type;
215 GLint gl_vtx_format;
216 GLboolean gl_normalized;
217 unsigned int component_size;
220 static const struct wined3d_format_vertex_info format_vertex_info[] =
222 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
223 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
224 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
225 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
226 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
227 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
228 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
229 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
230 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
231 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
232 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
233 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
234 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
235 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
236 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
237 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
238 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)},
239 {WINED3DFMT_R32_UINT, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_INT, 1, GL_FALSE, sizeof(UINT)},
240 {WINED3DFMT_R32G32_UINT, WINED3D_FFP_EMIT_INVALID, 2, GL_UNSIGNED_INT, 2, GL_FALSE, sizeof(UINT)},
241 {WINED3DFMT_R32G32B32_UINT, WINED3D_FFP_EMIT_INVALID, 3, GL_UNSIGNED_INT, 3, GL_FALSE, sizeof(UINT)},
242 {WINED3DFMT_R32G32B32A32_UINT, WINED3D_FFP_EMIT_INVALID, 4, GL_UNSIGNED_INT, 4, GL_FALSE, sizeof(UINT)},
245 struct wined3d_format_texture_info
247 enum wined3d_format_id id;
248 GLint gl_internal;
249 GLint gl_srgb_internal;
250 GLint gl_rt_internal;
251 GLint gl_format;
252 GLint gl_type;
253 unsigned int conv_byte_count;
254 unsigned int flags;
255 enum wined3d_gl_extension extension;
256 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT dst_pitch, UINT width, UINT height);
259 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch,
260 UINT dst_pitch, UINT width, UINT height)
262 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
263 * format+type combination to load it. Thus convert it to A8L8, then load it
264 * with A4L4 internal, but A8L8 format+type
266 unsigned int x, y;
267 const unsigned char *Source;
268 unsigned char *Dest;
270 for(y = 0; y < height; y++) {
271 Source = src + y * pitch;
272 Dest = dst + y * dst_pitch;
273 for (x = 0; x < width; x++ ) {
274 unsigned char color = (*Source++);
275 /* A */ Dest[1] = (color & 0xf0) << 0;
276 /* L */ Dest[0] = (color & 0x0f) << 4;
277 Dest += 2;
282 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch,
283 UINT dst_pitch, UINT width, UINT height)
285 unsigned int x, y;
286 const WORD *Source;
288 for(y = 0; y < height; y++)
290 unsigned short *Dest_s = (unsigned short *) (dst + y * dst_pitch);
291 Source = (const WORD *)(src + y * pitch);
292 for (x = 0; x < width; x++ )
294 short color = (*Source++);
295 unsigned char l = ((color >> 10) & 0xfc);
296 short v = ((color >> 5) & 0x3e);
297 short u = ((color ) & 0x1f);
298 short v_conv = v + 16;
299 short u_conv = u + 16;
301 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
302 Dest_s += 1;
307 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch,
308 UINT dst_pitch, UINT width, UINT height)
310 unsigned int x, y;
311 const WORD *Source;
312 unsigned char *Dest;
314 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
315 * fixed function and shaders without further conversion once the surface is
316 * loaded
318 for(y = 0; y < height; y++) {
319 Source = (const WORD *)(src + y * pitch);
320 Dest = dst + y * dst_pitch;
321 for (x = 0; x < width; x++ ) {
322 short color = (*Source++);
323 unsigned char l = ((color >> 10) & 0xfc);
324 char v = ((color >> 5) & 0x3e);
325 char u = ((color ) & 0x1f);
327 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
328 * and doubles the positive range. Thus shift left only once, gl does the 2nd
329 * shift. GL reads a signed value and converts it into an unsigned value.
331 /* M */ Dest[2] = l << 1;
333 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
334 * from 5 bit values to 8 bit values.
336 /* V */ Dest[1] = v << 3;
337 /* U */ Dest[0] = u << 3;
338 Dest += 3;
343 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch,
344 UINT dst_pitch, UINT width, UINT height)
346 unsigned int x, y;
347 const short *Source;
348 unsigned char *Dest;
350 for(y = 0; y < height; y++)
352 Source = (const short *)(src + y * pitch);
353 Dest = dst + y * dst_pitch;
354 for (x = 0; x < width; x++ )
356 const short color = (*Source++);
357 /* B */ Dest[0] = 0xff;
358 /* G */ Dest[1] = (color >> 8) + 128; /* V */
359 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
360 Dest += 3;
365 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch,
366 UINT dst_pitch, UINT width, UINT height)
368 unsigned int x, y;
369 const DWORD *Source;
370 unsigned char *Dest;
372 /* Doesn't work correctly with the fixed function pipeline, but can work in
373 * shaders if the shader is adjusted. (There's no use for this format in gl's
374 * standard fixed function pipeline anyway).
376 for(y = 0; y < height; y++)
378 Source = (const DWORD *)(src + y * pitch);
379 Dest = dst + y * dst_pitch;
380 for (x = 0; x < width; x++ )
382 LONG color = (*Source++);
383 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
384 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
385 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
386 Dest += 4;
391 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch,
392 UINT dst_pitch, UINT width, UINT height)
394 unsigned int x, y;
395 const DWORD *Source;
396 unsigned char *Dest;
398 /* This implementation works with the fixed function pipeline and shaders
399 * without further modification after converting the surface.
401 for(y = 0; y < height; y++)
403 Source = (const DWORD *)(src + y * pitch);
404 Dest = dst + y * dst_pitch;
405 for (x = 0; x < width; x++ )
407 LONG color = (*Source++);
408 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
409 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
410 /* U */ Dest[0] = (color & 0xff); /* U */
411 /* I */ Dest[3] = 255; /* X */
412 Dest += 4;
417 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch,
418 UINT dst_pitch, UINT width, UINT height)
420 unsigned int x, y;
421 const DWORD *Source;
422 unsigned char *Dest;
424 for(y = 0; y < height; y++)
426 Source = (const DWORD *)(src + y * pitch);
427 Dest = dst + y * dst_pitch;
428 for (x = 0; x < width; x++ )
430 LONG color = (*Source++);
431 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
432 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
433 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
434 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
435 Dest += 4;
440 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch,
441 UINT dst_pitch, UINT width, UINT height)
443 unsigned int x, y;
444 const DWORD *Source;
445 unsigned short *Dest;
447 for(y = 0; y < height; y++)
449 Source = (const DWORD *)(src + y * pitch);
450 Dest = (unsigned short *) (dst + y * dst_pitch);
451 for (x = 0; x < width; x++ )
453 const DWORD color = (*Source++);
454 /* B */ Dest[0] = 0xffff;
455 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
456 /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */
457 Dest += 3;
462 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch,
463 UINT dst_pitch, UINT width, UINT height)
465 unsigned int x, y;
466 const WORD *Source;
467 WORD *Dest;
469 for(y = 0; y < height; y++)
471 Source = (const WORD *)(src + y * pitch);
472 Dest = (WORD *) (dst + y * dst_pitch);
473 for (x = 0; x < width; x++ )
475 WORD green = (*Source++);
476 WORD red = (*Source++);
477 Dest[0] = green;
478 Dest[1] = red;
479 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
480 * shader overwrites it anyway
482 Dest[2] = 0xffff;
483 Dest += 3;
488 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch,
489 UINT dst_pitch, UINT width, UINT height)
491 unsigned int x, y;
492 const float *Source;
493 float *Dest;
495 for(y = 0; y < height; y++)
497 Source = (const float *)(src + y * pitch);
498 Dest = (float *) (dst + y * dst_pitch);
499 for (x = 0; x < width; x++ )
501 float green = (*Source++);
502 float red = (*Source++);
503 Dest[0] = green;
504 Dest[1] = red;
505 Dest[2] = 1.0f;
506 Dest += 3;
511 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch,
512 UINT dst_pitch, UINT width, UINT height)
514 unsigned int x, y;
516 for (y = 0; y < height; ++y)
518 const WORD *source = (const WORD *)(src + y * pitch);
519 DWORD *dest = (DWORD *)(dst + y * dst_pitch);
521 for (x = 0; x < width; ++x)
523 /* The depth data is normalized, so needs to be scaled,
524 * the stencil data isn't. Scale depth data by
525 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
526 WORD d15 = source[x] >> 1;
527 DWORD d24 = (d15 << 9) + (d15 >> 6);
528 dest[x] = (d24 << 8) | (source[x] & 0x1);
533 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch,
534 UINT dst_pitch, UINT width, UINT height)
536 unsigned int x, y;
538 for (y = 0; y < height; ++y)
540 const DWORD *source = (const DWORD *)(src + y * pitch);
541 DWORD *dest = (DWORD *)(dst + y * dst_pitch);
543 for (x = 0; x < width; ++x)
545 /* Just need to clear out the X4 part. */
546 dest[x] = source[x] & ~0xf0;
551 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch,
552 UINT dst_pitch, UINT width, UINT height)
554 unsigned int x, y;
556 for (y = 0; y < height; ++y)
558 const DWORD *source = (const DWORD *)(src + y * pitch);
559 float *dest_f = (float *)(dst + y * dst_pitch);
560 DWORD *dest_s = (DWORD *)(dst + y * dst_pitch);
562 for (x = 0; x < width; ++x)
564 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
565 dest_s[x * 2 + 1] = source[x] & 0xff;
570 /* The following formats explicitly don't have WINED3DFMT_FLAG_TEXTURE set:
572 * These are never supported on native.
573 * WINED3DFMT_B8G8R8_UNORM
574 * WINED3DFMT_B2G3R3_UNORM
575 * WINED3DFMT_L4A4_UNORM
576 * WINED3DFMT_S1_UINT_D15_UNORM
577 * WINED3DFMT_S4X4_UINT_D24_UNORM
579 * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of ddraw.
580 * Since it is not widely available, don't offer it. Further no Windows driver
581 * offers WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either.
582 * WINED3DFMT_P8_UINT
583 * WINED3DFMT_P8_UINT_A8_UNORM
585 * These formats seem to be similar to the HILO formats in
586 * GL_NV_texture_shader. NVHU is said to be GL_UNSIGNED_HILO16,
587 * NVHS GL_SIGNED_HILO16. Rumours say that D3D computes a 3rd channel
588 * similarly to D3DFMT_CxV8U8 (So NVHS could be called D3DFMT_CxV16U16). ATI
589 * refused to support formats which can easily be emulated with pixel shaders,
590 * so applications have to deal with not having NVHS and NVHU.
591 * WINED3DFMT_NVHU
592 * WINED3DFMT_NVHS */
593 static const struct wined3d_format_texture_info format_texture_info[] =
595 /* format id gl_internal gl_srgb_internal gl_rt_internal
596 gl_format gl_type conv_byte_count
597 flags
598 extension convert */
599 /* FourCC formats */
600 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
601 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
602 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
603 * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
604 * endian machine
606 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
607 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
608 WINED3DFMT_FLAG_FILTERING,
609 WINED3D_GL_EXT_NONE, NULL},
610 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
611 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 0,
612 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
613 APPLE_YCBCR_422, NULL},
614 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
615 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
616 WINED3DFMT_FLAG_FILTERING,
617 WINED3D_GL_EXT_NONE, NULL},
618 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
619 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, 0,
620 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
621 APPLE_YCBCR_422, NULL},
622 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
623 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
624 WINED3DFMT_FLAG_FILTERING,
625 WINED3D_GL_EXT_NONE, NULL},
626 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
627 GL_RGBA, GL_UNSIGNED_BYTE, 0,
628 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
629 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
630 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
631 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
632 GL_RGBA, GL_UNSIGNED_BYTE, 0,
633 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
634 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
635 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
636 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
637 GL_RGBA, GL_UNSIGNED_BYTE, 0,
638 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
639 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
640 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
641 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
642 GL_RGBA, GL_UNSIGNED_BYTE, 0,
643 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
644 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
645 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
646 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
647 GL_RGBA, GL_UNSIGNED_BYTE, 0,
648 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
649 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
650 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
651 /* IEEE formats */
652 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
653 GL_RED, GL_FLOAT, 0,
654 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
655 ARB_TEXTURE_FLOAT, NULL},
656 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
657 GL_RED, GL_FLOAT, 0,
658 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
659 ARB_TEXTURE_RG, NULL},
660 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
661 GL_RGB, GL_FLOAT, 12,
662 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
663 ARB_TEXTURE_FLOAT, convert_r32g32_float},
664 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
665 GL_RG, GL_FLOAT, 0,
666 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
667 ARB_TEXTURE_RG, NULL},
668 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
669 GL_RGBA, GL_FLOAT, 0,
670 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
671 ARB_TEXTURE_FLOAT, NULL},
672 /* Float */
673 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
674 GL_RED, GL_HALF_FLOAT_ARB, 0,
675 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
676 ARB_TEXTURE_FLOAT, NULL},
677 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
678 GL_RED, GL_HALF_FLOAT_ARB, 0,
679 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
680 ARB_TEXTURE_RG, NULL},
681 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
682 GL_RGB, GL_HALF_FLOAT_ARB, 6,
683 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
684 ARB_TEXTURE_FLOAT, convert_r16g16},
685 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
686 GL_RG, GL_HALF_FLOAT_ARB, 0,
687 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
688 ARB_TEXTURE_RG, NULL},
689 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
690 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
691 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET
692 | WINED3DFMT_FLAG_VTF,
693 ARB_TEXTURE_FLOAT, NULL},
694 /* Palettized formats */
695 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
696 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
698 ARB_FRAGMENT_PROGRAM, NULL},
699 /* Standard ARGB formats */
700 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
701 GL_BGR, GL_UNSIGNED_BYTE, 0,
702 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
703 WINED3D_GL_EXT_NONE, NULL},
704 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
705 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
706 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
707 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE
708 | WINED3DFMT_FLAG_VTF,
709 WINED3D_GL_EXT_NONE, NULL},
710 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
711 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
712 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
713 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
714 WINED3D_GL_EXT_NONE, NULL},
715 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
716 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
717 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
718 | WINED3DFMT_FLAG_RENDERTARGET,
719 WINED3D_GL_EXT_NONE, NULL},
720 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
721 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
722 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
723 WINED3D_GL_EXT_NONE, NULL},
724 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
725 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
726 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
727 WINED3D_GL_EXT_NONE, NULL},
728 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
729 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
730 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
731 | WINED3DFMT_FLAG_SRGB_READ,
732 WINED3D_GL_EXT_NONE, NULL},
733 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
734 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
735 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
736 WINED3D_GL_EXT_NONE, NULL},
737 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
738 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
739 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
740 WINED3D_GL_EXT_NONE, NULL},
741 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
742 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
743 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
744 WINED3D_GL_EXT_NONE, NULL},
745 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
746 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
747 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
748 | WINED3DFMT_FLAG_RENDERTARGET,
749 WINED3D_GL_EXT_NONE, NULL},
750 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
751 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
752 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
753 WINED3D_GL_EXT_NONE, NULL},
754 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
755 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
756 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
757 WINED3D_GL_EXT_NONE, NULL},
758 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
759 GL_RGB, GL_UNSIGNED_SHORT, 6,
760 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
761 WINED3D_GL_EXT_NONE, convert_r16g16},
762 {WINED3DFMT_R16G16_UNORM, GL_RG16, GL_RG16, 0,
763 GL_RG, GL_UNSIGNED_SHORT, 0,
764 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
765 | WINED3DFMT_FLAG_RENDERTARGET,
766 ARB_TEXTURE_RG, NULL},
767 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
768 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
769 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
770 | WINED3DFMT_FLAG_RENDERTARGET,
771 WINED3D_GL_EXT_NONE, NULL},
772 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
773 GL_RGBA, GL_UNSIGNED_SHORT, 0,
774 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
775 | WINED3DFMT_FLAG_RENDERTARGET,
776 WINED3D_GL_EXT_NONE, NULL},
777 /* Luminance */
778 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
779 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
780 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
781 | WINED3DFMT_FLAG_SRGB_READ,
782 WINED3D_GL_EXT_NONE, NULL},
783 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
784 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
785 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
786 | WINED3DFMT_FLAG_SRGB_READ,
787 WINED3D_GL_EXT_NONE, NULL},
788 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
789 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
790 WINED3DFMT_FLAG_FILTERING,
791 WINED3D_GL_EXT_NONE, convert_l4a4_unorm},
792 /* Bump mapping stuff */
793 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
794 GL_BGR, GL_UNSIGNED_BYTE, 3,
795 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
796 | WINED3DFMT_FLAG_BUMPMAP,
797 WINED3D_GL_EXT_NONE, convert_r8g8_snorm},
798 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
799 GL_DSDT_NV, GL_BYTE, 0,
800 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
801 | WINED3DFMT_FLAG_BUMPMAP,
802 NV_TEXTURE_SHADER, NULL},
803 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
804 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
805 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
806 | WINED3DFMT_FLAG_BUMPMAP,
807 WINED3D_GL_EXT_NONE, convert_r5g5_snorm_l6_unorm},
808 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
809 GL_DSDT_MAG_NV, GL_BYTE, 3,
810 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
811 | WINED3DFMT_FLAG_BUMPMAP,
812 NV_TEXTURE_SHADER, convert_r5g5_snorm_l6_unorm_nv},
813 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
814 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
815 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
816 | WINED3DFMT_FLAG_BUMPMAP,
817 WINED3D_GL_EXT_NONE, convert_r8g8_snorm_l8x8_unorm},
818 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
819 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
820 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
821 | WINED3DFMT_FLAG_BUMPMAP,
822 NV_TEXTURE_SHADER, convert_r8g8_snorm_l8x8_unorm_nv},
823 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
824 GL_BGRA, GL_UNSIGNED_BYTE, 4,
825 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
826 | WINED3DFMT_FLAG_BUMPMAP,
827 WINED3D_GL_EXT_NONE, convert_r8g8b8a8_snorm},
828 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
829 GL_RGBA, GL_BYTE, 0,
830 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
831 | WINED3DFMT_FLAG_BUMPMAP,
832 NV_TEXTURE_SHADER, NULL},
833 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
834 GL_BGR, GL_UNSIGNED_SHORT, 6,
835 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
836 | WINED3DFMT_FLAG_BUMPMAP,
837 WINED3D_GL_EXT_NONE, convert_r16g16_snorm},
838 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
839 GL_HILO_NV, GL_SHORT, 0,
840 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
841 | WINED3DFMT_FLAG_BUMPMAP,
842 NV_TEXTURE_SHADER, NULL},
843 /* Depth stencil formats */
844 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
845 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
846 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
847 ARB_DEPTH_TEXTURE, NULL},
848 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
849 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
850 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
851 ARB_DEPTH_TEXTURE, NULL},
852 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
853 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
854 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
855 ARB_DEPTH_TEXTURE, NULL},
856 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
857 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
858 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
859 EXT_PACKED_DEPTH_STENCIL, convert_s1_uint_d15_unorm},
860 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
861 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
862 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
863 ARB_FRAMEBUFFER_OBJECT, convert_s1_uint_d15_unorm},
864 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
865 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
866 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
867 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
868 ARB_DEPTH_TEXTURE, NULL},
869 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
870 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
871 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
872 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
873 EXT_PACKED_DEPTH_STENCIL, NULL},
874 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
875 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
876 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
877 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
878 ARB_FRAMEBUFFER_OBJECT, NULL},
879 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
880 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
881 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
882 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
883 ARB_DEPTH_TEXTURE, NULL},
884 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
885 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
886 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
887 ARB_DEPTH_TEXTURE, NULL},
888 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
889 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
890 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
891 EXT_PACKED_DEPTH_STENCIL, convert_s4x4_uint_d24_unorm},
892 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
893 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
894 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
895 ARB_FRAMEBUFFER_OBJECT, convert_s4x4_uint_d24_unorm},
896 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
897 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
898 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
899 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
900 ARB_DEPTH_TEXTURE, NULL},
901 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
902 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
903 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
904 WINED3D_GL_EXT_NONE, NULL},
905 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
906 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
907 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
908 ARB_DEPTH_BUFFER_FLOAT, NULL},
909 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
910 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
911 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
912 ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float},
913 /* Vendor-specific formats */
914 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
915 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
916 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
917 | WINED3DFMT_FLAG_COMPRESSED,
918 ATI_TEXTURE_COMPRESSION_3DC, NULL},
919 {WINED3DFMT_ATI2N, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0,
920 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
921 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
922 | WINED3DFMT_FLAG_COMPRESSED,
923 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
924 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
925 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
926 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
927 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
928 EXT_PACKED_DEPTH_STENCIL, NULL},
929 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
930 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
931 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
932 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
933 ARB_FRAMEBUFFER_OBJECT, NULL},
934 {WINED3DFMT_NULL, 0, 0, 0,
935 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
936 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET,
937 ARB_FRAMEBUFFER_OBJECT, NULL},
940 static inline int getFmtIdx(enum wined3d_format_id format_id)
942 /* First check if the format is at the position of its value.
943 * This will catch the argb formats before the loop is entered. */
944 if (format_id < (sizeof(formats) / sizeof(*formats))
945 && formats[format_id].id == format_id)
947 return format_id;
949 else
951 unsigned int i;
953 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
955 if (formats[i].id == format_id) return i;
958 return -1;
961 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
963 UINT format_count = sizeof(formats) / sizeof(*formats);
964 UINT i;
966 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
967 if (!gl_info->formats)
969 ERR("Failed to allocate memory.\n");
970 return FALSE;
973 for (i = 0; i < format_count; ++i)
975 struct wined3d_format *format = &gl_info->formats[i];
976 format->id = formats[i].id;
977 format->red_size = formats[i].red_size;
978 format->green_size = formats[i].green_size;
979 format->blue_size = formats[i].blue_size;
980 format->alpha_size = formats[i].alpha_size;
981 format->red_offset = formats[i].red_offset;
982 format->green_offset = formats[i].green_offset;
983 format->blue_offset = formats[i].blue_offset;
984 format->alpha_offset = formats[i].alpha_offset;
985 format->byte_count = formats[i].bpp;
986 format->depth_size = formats[i].depth_size;
987 format->stencil_size = formats[i].stencil_size;
988 format->block_width = 1;
989 format->block_height = 1;
990 format->block_byte_count = formats[i].bpp;
993 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
995 int fmt_idx = getFmtIdx(format_base_flags[i].id);
997 if (fmt_idx == -1)
999 ERR("Format %s (%#x) not found.\n",
1000 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
1001 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1002 return FALSE;
1005 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
1008 return TRUE;
1011 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
1013 unsigned int i;
1015 for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i)
1017 struct wined3d_format *format;
1018 int fmt_idx = getFmtIdx(format_block_info[i].id);
1020 if (fmt_idx == -1)
1022 ERR("Format %s (%#x) not found.\n",
1023 debug_d3dformat(format_block_info[i].id), format_block_info[i].id);
1024 return FALSE;
1027 format = &gl_info->formats[fmt_idx];
1028 format->block_width = format_block_info[i].block_width;
1029 format->block_height = format_block_info[i].block_height;
1030 format->block_byte_count = format_block_info[i].block_byte_count;
1031 format->flags |= WINED3DFMT_FLAG_BLOCKS;
1032 if (!format_block_info[i].verify)
1033 format->flags |= WINED3DFMT_FLAG_BLOCKS_NO_VERIFY;
1036 return TRUE;
1039 /* Context activation is done by the caller. */
1040 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
1042 /* Check if the default internal format is supported as a frame buffer
1043 * target, otherwise fall back to the render target internal.
1045 * Try to stick to the standard format if possible, this limits precision differences. */
1046 GLenum status;
1047 GLuint tex;
1049 while (gl_info->gl_ops.gl.p_glGetError());
1050 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1052 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1053 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1055 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0,
1056 format->glFormat, format->glType, NULL);
1057 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1058 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1060 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1062 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1063 checkGLcall("Framebuffer format check");
1065 if (status == GL_FRAMEBUFFER_COMPLETE)
1067 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1068 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1069 format->rtInternal = format->glInternal;
1071 else
1073 if (!format->rtInternal)
1075 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1077 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1078 " and no fallback specified.\n", debug_d3dformat(format->id));
1079 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1081 else
1083 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1085 format->rtInternal = format->glInternal;
1087 else
1089 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1090 debug_d3dformat(format->id));
1092 while (gl_info->gl_ops.gl.p_glGetError());
1094 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1096 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0,
1097 format->glFormat, format->glType, NULL);
1098 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1099 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1101 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1103 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1104 checkGLcall("Framebuffer format check");
1106 if (status == GL_FRAMEBUFFER_COMPLETE)
1108 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1109 debug_d3dformat(format->id));
1111 else
1113 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1114 debug_d3dformat(format->id));
1115 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1120 if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1121 || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1122 && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
1123 && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA
1124 && (format->red_size || format->alpha_size))
1126 DWORD readback[16 * 16], color, r_range, a_range;
1127 BYTE r, a;
1128 BOOL match = TRUE;
1129 GLuint rb;
1131 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1132 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1134 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1135 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1136 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1137 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1138 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1139 checkGLcall("RB attachment");
1142 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1143 gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1144 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1145 if (gl_info->gl_ops.gl.p_glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1147 while (gl_info->gl_ops.gl.p_glGetError());
1148 TRACE("Format doesn't support post-pixelshader blending.\n");
1149 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1151 else
1153 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1154 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16);
1155 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1156 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1157 gl_info->gl_ops.gl.p_glLoadIdentity();
1158 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1159 gl_info->gl_ops.gl.p_glLoadIdentity();
1161 gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1163 /* Draw a full-black quad */
1164 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1165 gl_info->gl_ops.gl.p_glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
1166 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1167 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1168 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1169 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1170 gl_info->gl_ops.gl.p_glEnd();
1172 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1173 /* Draw a half-transparent red quad */
1174 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1175 gl_info->gl_ops.gl.p_glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
1176 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1177 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1178 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1179 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1180 gl_info->gl_ops.gl.p_glEnd();
1182 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1184 /* Rebinding texture to workaround a fglrx bug. */
1185 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1186 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1187 checkGLcall("Post-pixelshader blending check");
1189 color = readback[7 * 16 + 7];
1190 a = color >> 24;
1191 r = (color & 0x00ff0000) >> 16;
1193 r_range = format->red_size < 8 ? 1 << (8 - format->red_size) : 1;
1194 a_range = format->alpha_size < 8 ? 1 << (8 - format->alpha_size) : 1;
1195 if (format->red_size && (r < 0x7f - r_range || r > 0x7f + r_range))
1196 match = FALSE;
1197 else if (format->alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range))
1198 match = FALSE;
1199 if (!match)
1201 TRACE("Format doesn't support post-pixelshader blending.\n");
1202 TRACE("Color output: %#x\n", color);
1203 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1205 else
1207 TRACE("Format supports post-pixelshader blending.\n");
1208 TRACE("Color output: %#x\n", color);
1209 format->flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1213 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1214 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1216 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1217 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1218 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1219 checkGLcall("RB cleanup");
1223 if (format->glInternal != format->glGammaInternal)
1225 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0,
1226 format->glFormat, format->glType, NULL);
1227 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1229 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1230 checkGLcall("Framebuffer format check");
1232 if (status == GL_FRAMEBUFFER_COMPLETE)
1234 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1235 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1237 else
1239 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1242 else if (status == GL_FRAMEBUFFER_COMPLETE)
1243 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1245 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1248 static void query_format_flag(struct wined3d_gl_info *gl_info, struct wined3d_format *format,
1249 GLint internal, GLenum pname, DWORD flag, const char *string)
1251 GLint value;
1253 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, internal, pname, 1, &value);
1254 if (value == GL_FULL_SUPPORT)
1256 TRACE("Format %s supports %s.\n", debug_d3dformat(format->id), string);
1257 format->flags |= flag;
1259 else
1261 TRACE("Format %s doesn't support %s.\n", debug_d3dformat(format->id), string);
1262 format->flags &= ~flag;
1266 /* Context activation is done by the caller. */
1267 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1269 unsigned int i;
1270 GLuint fbo;
1272 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
1274 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1276 GLint value;
1277 struct wined3d_format *format = &gl_info->formats[i];
1279 if (!format->glInternal)
1280 continue;
1281 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1282 continue;
1284 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->glInternal,
1285 GL_FRAMEBUFFER_RENDERABLE, 1, &value);
1286 if (value == GL_FULL_SUPPORT)
1288 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1289 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1290 format->rtInternal = format->glInternal;
1292 query_format_flag(gl_info, format, format->glInternal, GL_FRAMEBUFFER_BLEND,
1293 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING, "post-pixelshader blending");
1295 else
1297 if (!format->rtInternal)
1299 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1301 WARN("Format %s with rendertarget flag is not supported as FBO color attachment"
1302 " and no fallback specified.\n", debug_d3dformat(format->id));
1303 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1305 else
1306 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1307 format->rtInternal = format->glInternal;
1309 else
1311 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->rtInternal,
1312 GL_FRAMEBUFFER_RENDERABLE, 1, &value);
1313 if (value == GL_FULL_SUPPORT)
1315 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1316 debug_d3dformat(format->id));
1318 else
1320 WARN("Format %s rtInternal format is not supported as FBO color attachment.\n",
1321 debug_d3dformat(format->id));
1322 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1327 if (format->glInternal != format->glGammaInternal)
1329 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->glGammaInternal,
1330 GL_FRAMEBUFFER_RENDERABLE, 1, &value);
1331 if (value == GL_FULL_SUPPORT)
1333 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1334 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1336 else
1338 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1341 else if (format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)
1342 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1344 return;
1347 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1349 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1350 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1351 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1352 gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0);
1355 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1357 struct wined3d_format *format = &gl_info->formats[i];
1359 if (!format->glInternal) continue;
1361 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1363 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1364 debug_d3dformat(format->id));
1365 continue;
1368 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1370 TRACE("Skipping format %s because it's a compressed format.\n",
1371 debug_d3dformat(format->id));
1372 continue;
1375 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1377 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1378 check_fbo_compat(gl_info, format);
1380 else
1382 format->rtInternal = format->glInternal;
1386 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1387 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1390 static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1392 struct fragment_caps fragment_caps;
1393 struct shader_caps shader_caps;
1394 BOOL srgb_write;
1395 unsigned int i;
1397 adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
1398 adapter->shader_backend->shader_get_caps(gl_info, &shader_caps);
1399 srgb_write = (fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_SRGB_WRITE)
1400 && (shader_caps.wined3d_caps & WINED3D_SHADER_CAP_SRGB_WRITE);
1402 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1404 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1405 struct wined3d_format *format;
1407 if (fmt_idx == -1)
1409 ERR("Format %s (%#x) not found.\n",
1410 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1411 return FALSE;
1414 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1416 format = &gl_info->formats[fmt_idx];
1418 /* ARB_texture_rg defines floating point formats, but only if
1419 * ARB_texture_float is also supported. */
1420 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1421 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1422 continue;
1424 format->glInternal = format_texture_info[i].gl_internal;
1425 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1426 format->rtInternal = format_texture_info[i].gl_rt_internal;
1427 format->glFormat = format_texture_info[i].gl_format;
1428 format->glType = format_texture_info[i].gl_type;
1429 format->color_fixup = COLOR_FIXUP_IDENTITY;
1430 format->flags |= format_texture_info[i].flags;
1431 format->height_scale.numerator = 1;
1432 format->height_scale.denominator = 1;
1434 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
1436 query_format_flag(gl_info, format, format->glInternal, GL_VERTEX_TEXTURE,
1437 WINED3DFMT_FLAG_VTF, "vertex texture usage");
1438 query_format_flag(gl_info, format, format->glInternal, GL_FILTER,
1439 WINED3DFMT_FLAG_FILTERING, "filtering");
1441 if (format->glGammaInternal != format->glInternal)
1443 query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_READ,
1444 WINED3DFMT_FLAG_SRGB_READ, "sRGB read");
1446 if (srgb_write)
1447 query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_WRITE,
1448 WINED3DFMT_FLAG_SRGB_WRITE, "sRGB write");
1449 else
1450 format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
1452 if (!(format->flags & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE)))
1453 format->glGammaInternal = format->glInternal;
1454 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1455 format->glInternal = format->glGammaInternal;
1458 else
1460 if (!gl_info->limits.vertex_samplers)
1461 format->flags &= ~WINED3DFMT_FLAG_VTF;
1463 if (!(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1464 format->flags |= WINED3DFMT_FLAG_FILTERING;
1465 else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT)
1466 format->flags &= ~WINED3DFMT_FLAG_VTF;
1468 if (format->glGammaInternal != format->glInternal)
1470 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1471 if (!gl_info->supported[EXT_TEXTURE_SRGB])
1473 format->glGammaInternal = format->glInternal;
1474 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1476 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1478 format->glInternal = format->glGammaInternal;
1482 if ((format->flags & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write)
1483 format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
1486 /* Texture conversion stuff */
1487 format->convert = format_texture_info[i].convert;
1488 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1491 return TRUE;
1494 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1496 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1497 c1 >>= 8; c2 >>= 8;
1498 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1499 c1 >>= 8; c2 >>= 8;
1500 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1501 c1 >>= 8; c2 >>= 8;
1502 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1503 return TRUE;
1506 /* A context is provided by the caller */
1507 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1509 static const DWORD data[] = {0x00000000, 0xffffffff};
1510 GLuint tex, fbo, buffer;
1511 DWORD readback[16 * 1];
1512 BOOL ret = FALSE;
1514 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1515 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1516 * falling back to software. If this changes in the future this code will get fooled and
1517 * apps might hit the software path due to incorrectly advertised caps.
1519 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1520 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1521 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1524 while (gl_info->gl_ops.gl.p_glGetError());
1526 gl_info->gl_ops.gl.p_glGenTextures(1, &buffer);
1527 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1528 memset(readback, 0x7e, sizeof(readback));
1529 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0,
1530 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1531 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1532 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1533 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1534 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1535 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1537 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1538 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1539 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0,
1540 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1541 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1542 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1543 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1544 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1545 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1546 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
1548 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1549 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1550 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1551 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1553 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1);
1554 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1555 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1556 gl_info->gl_ops.gl.p_glLoadIdentity();
1557 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1558 gl_info->gl_ops.gl.p_glLoadIdentity();
1560 gl_info->gl_ops.gl.p_glClearColor(0, 1, 0, 0);
1561 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1563 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1564 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 0.0);
1565 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, -1.0f);
1566 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 0.0);
1567 gl_info->gl_ops.gl.p_glVertex2f(1.0f, -1.0f);
1568 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 1.0);
1569 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, 1.0f);
1570 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 1.0);
1571 gl_info->gl_ops.gl.p_glVertex2f(1.0f, 1.0f);
1572 gl_info->gl_ops.gl.p_glEnd();
1574 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1575 memset(readback, 0x7f, sizeof(readback));
1576 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1577 if (color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5)
1578 || color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1580 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, assuming no filtering\n",
1581 readback[6], readback[9]);
1582 ret = FALSE;
1584 else
1586 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1587 readback[6], readback[9]);
1588 ret = TRUE;
1591 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1592 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1593 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1594 gl_info->gl_ops.gl.p_glDeleteTextures(1, &buffer);
1596 if (gl_info->gl_ops.gl.p_glGetError())
1598 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1599 ret = FALSE;
1602 return ret;
1605 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1607 struct wined3d_format *format;
1608 unsigned int fmt_idx, i;
1609 static const enum wined3d_format_id fmts16[] =
1611 WINED3DFMT_R16_FLOAT,
1612 WINED3DFMT_R16G16_FLOAT,
1613 WINED3DFMT_R16G16B16A16_FLOAT,
1615 BOOL filtered;
1617 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
1618 /* This was already handled by init_format_texture_info(). */
1619 return;
1621 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1623 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1624 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1626 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1627 filtered = TRUE;
1629 else if (gl_info->limits.glsl_varyings > 44)
1631 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1632 filtered = TRUE;
1634 else
1636 TRACE("Assuming no float16 blending\n");
1637 filtered = FALSE;
1640 if(filtered)
1642 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1644 fmt_idx = getFmtIdx(fmts16[i]);
1645 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1648 return;
1651 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1653 fmt_idx = getFmtIdx(fmts16[i]);
1654 format = &gl_info->formats[fmt_idx];
1655 if (!format->glInternal) continue; /* Not supported by GL */
1657 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1658 if(filtered)
1660 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1661 format->flags |= WINED3DFMT_FLAG_FILTERING;
1663 else
1665 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1670 static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1672 unsigned int i;
1673 int idx;
1675 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1676 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1677 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1679 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1680 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1681 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1683 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1684 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1685 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1687 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1688 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1689 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1691 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1692 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1693 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1695 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1696 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1697 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1698 * the only driver that implements it(fglrx) has a buggy implementation.
1700 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1701 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1702 * conversion for this format.
1704 if (!gl_info->supported[NV_TEXTURE_SHADER])
1706 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1707 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1708 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1709 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1710 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1711 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1713 else
1715 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1716 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1717 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1719 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1720 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1721 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1724 if (!gl_info->supported[NV_TEXTURE_SHADER])
1726 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1727 * with each other
1729 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1730 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1731 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1732 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1733 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1734 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1735 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1736 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1737 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1739 else
1741 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1742 * are converted at surface loading time, but they do not need any modification in
1743 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1744 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1748 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1750 idx = getFmtIdx(WINED3DFMT_ATI2N);
1751 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1752 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1754 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1756 idx = getFmtIdx(WINED3DFMT_ATI2N);
1757 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1758 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1761 if (!gl_info->supported[APPLE_YCBCR_422])
1763 idx = getFmtIdx(WINED3DFMT_YUY2);
1764 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1766 idx = getFmtIdx(WINED3DFMT_UYVY);
1767 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1770 idx = getFmtIdx(WINED3DFMT_YV12);
1771 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
1772 gl_info->formats[idx].height_scale.numerator = 3;
1773 gl_info->formats[idx].height_scale.denominator = 2;
1774 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1776 if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
1778 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1779 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1782 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1784 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1785 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1788 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1790 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1791 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1792 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1793 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1795 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1796 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1799 if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
1801 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1802 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1804 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1805 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1807 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1808 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1811 if (gl_info->quirks & WINED3D_QUIRK_BROKEN_RGBA16)
1813 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_UNORM);
1814 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1817 /* ATI instancing hack: Although ATI cards do not support Shader Model
1818 * 3.0, they support instancing. To query if the card supports instancing
1819 * CheckDeviceFormat() with the special format MAKEFOURCC('I','N','S','T')
1820 * is used. Should an application check for this, provide a proper return
1821 * value. We can do instancing with all shader versions, but we need
1822 * vertex shaders.
1824 * Additionally applications have to set the D3DRS_POINTSIZE render state
1825 * to MAKEFOURCC('I','N','S','T') once to enable instancing. Wined3d
1826 * doesn't need that and just ignores it.
1828 * With Shader Model 3.0 capable cards Instancing 'just works' in Windows. */
1829 /* FIXME: This should just check the shader backend caps. */
1830 if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
1832 idx = getFmtIdx(WINED3DFMT_INST);
1833 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
1836 /* Depth bound test. To query if the card supports it CheckDeviceFormat()
1837 * with the special format MAKEFOURCC('N','V','D','B') is used. It is
1838 * enabled by setting D3DRS_ADAPTIVETESS_X render state to
1839 * MAKEFOURCC('N','V','D','B') and then controlled by setting
1840 * D3DRS_ADAPTIVETESS_Z (zMin) and D3DRS_ADAPTIVETESS_W (zMax) to test
1841 * value. */
1842 if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST])
1844 idx = getFmtIdx(WINED3DFMT_NVDB);
1845 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
1848 /* RESZ aka AMD DX9-level hack for multisampled depth buffer resolve. You query for RESZ
1849 * support by checking for availability of MAKEFOURCC('R','E','S','Z') surfaces with
1850 * RENDERTARGET usage. */
1851 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
1853 idx = getFmtIdx(WINED3DFMT_RESZ);
1854 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET;
1857 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1859 struct wined3d_format *format = &gl_info->formats[i];
1861 if (!(format->flags & WINED3DFMT_FLAG_TEXTURE))
1862 continue;
1864 if (!adapter->shader_backend->shader_color_fixup_supported(format->color_fixup)
1865 || !adapter->fragment_pipe->color_fixup_supported(format->color_fixup))
1866 format->flags &= ~WINED3DFMT_FLAG_TEXTURE;
1870 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1872 unsigned int i;
1874 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1876 struct wined3d_format *format;
1877 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1879 if (fmt_idx == -1)
1881 ERR("Format %s (%#x) not found.\n",
1882 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1883 return FALSE;
1886 format = &gl_info->formats[fmt_idx];
1887 format->emit_idx = format_vertex_info[i].emit_idx;
1888 format->component_count = format_vertex_info[i].component_count;
1889 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1890 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1891 format->gl_normalized = format_vertex_info[i].gl_normalized;
1892 format->component_size = format_vertex_info[i].component_size;
1895 return TRUE;
1898 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1900 if (!init_format_base_info(gl_info)) return FALSE;
1902 if (!init_format_block_info(gl_info))
1904 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1905 gl_info->formats = NULL;
1906 return FALSE;
1909 return TRUE;
1912 /* Context activation is done by the caller. */
1913 BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter)
1915 struct wined3d_gl_info *gl_info = &adapter->gl_info;
1917 if (!init_format_base_info(gl_info)) return FALSE;
1919 if (!init_format_block_info(gl_info)) goto fail;
1920 if (!init_format_texture_info(adapter, gl_info)) goto fail;
1921 if (!init_format_vertex_info(gl_info)) goto fail;
1923 apply_format_fixups(adapter, gl_info);
1924 init_format_fbo_compat_info(gl_info);
1925 init_format_filter_info(gl_info, adapter->driver_info.vendor);
1927 return TRUE;
1929 fail:
1930 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1931 gl_info->formats = NULL;
1932 return FALSE;
1935 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1936 enum wined3d_format_id format_id)
1938 int idx = getFmtIdx(format_id);
1940 if (idx == -1)
1942 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1943 debug_d3dformat(format_id), format_id);
1944 /* Get the caller a valid pointer */
1945 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1948 return &gl_info->formats[idx];
1951 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment,
1952 UINT width, UINT height, UINT depth)
1954 UINT size;
1956 if (format->id == WINED3DFMT_UNKNOWN)
1958 size = 0;
1960 else if (format->flags & WINED3DFMT_FLAG_BLOCKS)
1962 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1963 UINT row_count = (height + format->block_height - 1) / format->block_height;
1964 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1966 else
1968 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1971 if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
1973 /* The D3D format requirements make sure that the resulting format is an integer again */
1974 size *= format->height_scale.numerator;
1975 size /= format->height_scale.denominator;
1978 size *= depth;
1980 return size;
1983 /*****************************************************************************
1984 * Trace formatting of useful values
1986 const char *debug_d3dformat(enum wined3d_format_id format_id)
1988 switch (format_id)
1990 #define FMT_TO_STR(format_id) case format_id: return #format_id
1991 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1992 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1993 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1994 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1995 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1996 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1997 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1998 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1999 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
2000 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
2001 FMT_TO_STR(WINED3DFMT_P8_UINT);
2002 FMT_TO_STR(WINED3DFMT_L8_UNORM);
2003 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
2004 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
2005 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
2006 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
2007 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
2008 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
2009 FMT_TO_STR(WINED3DFMT_UYVY);
2010 FMT_TO_STR(WINED3DFMT_YUY2);
2011 FMT_TO_STR(WINED3DFMT_YV12);
2012 FMT_TO_STR(WINED3DFMT_DXT1);
2013 FMT_TO_STR(WINED3DFMT_DXT2);
2014 FMT_TO_STR(WINED3DFMT_DXT3);
2015 FMT_TO_STR(WINED3DFMT_DXT4);
2016 FMT_TO_STR(WINED3DFMT_DXT5);
2017 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
2018 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
2019 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
2020 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
2021 FMT_TO_STR(WINED3DFMT_D32_UNORM);
2022 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
2023 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
2024 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
2025 FMT_TO_STR(WINED3DFMT_L16_UNORM);
2026 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
2027 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
2028 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
2029 FMT_TO_STR(WINED3DFMT_ATI2N);
2030 FMT_TO_STR(WINED3DFMT_NVDB);
2031 FMT_TO_STR(WINED3DFMT_NVHU);
2032 FMT_TO_STR(WINED3DFMT_NVHS);
2033 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
2034 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
2035 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
2036 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
2037 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
2038 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
2039 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
2040 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
2041 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
2042 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
2043 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
2044 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
2045 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
2046 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
2047 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
2048 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
2049 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
2050 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
2051 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
2052 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
2053 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
2054 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
2055 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
2056 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
2057 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
2058 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
2059 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
2060 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
2061 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
2062 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
2063 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
2064 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
2065 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
2066 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
2067 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
2068 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
2069 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
2070 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
2071 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
2072 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
2073 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
2074 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
2075 FMT_TO_STR(WINED3DFMT_R32_UINT);
2076 FMT_TO_STR(WINED3DFMT_R32_SINT);
2077 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
2078 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
2079 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
2080 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
2081 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
2082 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
2083 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
2084 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
2085 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
2086 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
2087 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
2088 FMT_TO_STR(WINED3DFMT_D16_UNORM);
2089 FMT_TO_STR(WINED3DFMT_R16_UNORM);
2090 FMT_TO_STR(WINED3DFMT_R16_UINT);
2091 FMT_TO_STR(WINED3DFMT_R16_SNORM);
2092 FMT_TO_STR(WINED3DFMT_R16_SINT);
2093 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
2094 FMT_TO_STR(WINED3DFMT_R8_UNORM);
2095 FMT_TO_STR(WINED3DFMT_R8_UINT);
2096 FMT_TO_STR(WINED3DFMT_R8_SNORM);
2097 FMT_TO_STR(WINED3DFMT_R8_SINT);
2098 FMT_TO_STR(WINED3DFMT_A8_UNORM);
2099 FMT_TO_STR(WINED3DFMT_R1_UNORM);
2100 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
2101 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
2102 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
2103 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
2104 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
2105 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
2106 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
2107 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
2108 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
2109 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
2110 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
2111 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
2112 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
2113 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
2114 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
2115 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
2116 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
2117 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
2118 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
2119 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
2120 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
2121 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
2122 FMT_TO_STR(WINED3DFMT_INTZ);
2123 FMT_TO_STR(WINED3DFMT_RESZ);
2124 FMT_TO_STR(WINED3DFMT_NULL);
2125 FMT_TO_STR(WINED3DFMT_R16);
2126 FMT_TO_STR(WINED3DFMT_AL16);
2127 #undef FMT_TO_STR
2128 default:
2130 char fourcc[5];
2131 fourcc[0] = (char)(format_id);
2132 fourcc[1] = (char)(format_id >> 8);
2133 fourcc[2] = (char)(format_id >> 16);
2134 fourcc[3] = (char)(format_id >> 24);
2135 fourcc[4] = 0;
2136 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
2137 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
2138 else
2139 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
2141 return "unrecognized";
2145 const char *debug_d3ddevicetype(enum wined3d_device_type device_type)
2147 switch (device_type)
2149 #define DEVTYPE_TO_STR(dev) case dev: return #dev
2150 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_HAL);
2151 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_REF);
2152 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_SW);
2153 #undef DEVTYPE_TO_STR
2154 default:
2155 FIXME("Unrecognized device type %#x.\n", device_type);
2156 return "unrecognized";
2160 const char *debug_d3dusage(DWORD usage)
2162 char buf[333];
2164 buf[0] = '\0';
2165 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
2166 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
2167 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
2168 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
2169 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
2170 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
2171 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
2172 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
2173 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
2174 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
2175 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
2176 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
2177 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
2178 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
2179 #undef WINED3DUSAGE_TO_STR
2180 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
2182 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2185 const char *debug_d3dusagequery(DWORD usagequery)
2187 char buf[238];
2189 buf[0] = '\0';
2190 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
2191 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
2192 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
2193 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
2194 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
2195 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
2196 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
2197 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
2198 #undef WINED3DUSAGEQUERY_TO_STR
2199 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
2201 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2204 const char *debug_d3ddeclmethod(enum wined3d_decl_method method)
2206 switch (method)
2208 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
2209 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_DEFAULT);
2210 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_U);
2211 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_V);
2212 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_CROSS_UV);
2213 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_UV);
2214 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP);
2215 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP_PRESAMPLED);
2216 #undef WINED3DDECLMETHOD_TO_STR
2217 default:
2218 FIXME("Unrecognized declaration method %#x.\n", method);
2219 return "unrecognized";
2223 const char *debug_d3ddeclusage(enum wined3d_decl_usage usage)
2225 switch (usage)
2227 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
2228 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITION);
2229 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_WEIGHT);
2230 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_INDICES);
2231 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_NORMAL);
2232 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_PSIZE);
2233 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TEXCOORD);
2234 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TANGENT);
2235 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BINORMAL);
2236 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TESS_FACTOR);
2237 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITIONT);
2238 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_COLOR);
2239 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_FOG);
2240 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_DEPTH);
2241 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_SAMPLE);
2242 #undef WINED3DDECLUSAGE_TO_STR
2243 default:
2244 FIXME("Unrecognized %u declaration usage!\n", usage);
2245 return "unrecognized";
2249 const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
2251 switch (resource_type)
2253 #define RES_TO_STR(res) case res: return #res
2254 RES_TO_STR(WINED3D_RTYPE_SURFACE);
2255 RES_TO_STR(WINED3D_RTYPE_VOLUME);
2256 RES_TO_STR(WINED3D_RTYPE_TEXTURE);
2257 RES_TO_STR(WINED3D_RTYPE_VOLUME_TEXTURE);
2258 RES_TO_STR(WINED3D_RTYPE_CUBE_TEXTURE);
2259 RES_TO_STR(WINED3D_RTYPE_BUFFER);
2260 #undef RES_TO_STR
2261 default:
2262 FIXME("Unrecognized resource type %#x.\n", resource_type);
2263 return "unrecognized";
2267 const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type)
2269 switch (primitive_type)
2271 #define PRIM_TO_STR(prim) case prim: return #prim
2272 PRIM_TO_STR(WINED3D_PT_UNDEFINED);
2273 PRIM_TO_STR(WINED3D_PT_POINTLIST);
2274 PRIM_TO_STR(WINED3D_PT_LINELIST);
2275 PRIM_TO_STR(WINED3D_PT_LINESTRIP);
2276 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST);
2277 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP);
2278 PRIM_TO_STR(WINED3D_PT_TRIANGLEFAN);
2279 PRIM_TO_STR(WINED3D_PT_LINELIST_ADJ);
2280 PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ);
2281 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ);
2282 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ);
2283 #undef PRIM_TO_STR
2284 default:
2285 FIXME("Unrecognized %u primitive type!\n", primitive_type);
2286 return "unrecognized";
2290 const char *debug_d3drenderstate(enum wined3d_render_state state)
2292 switch (state)
2294 #define D3DSTATE_TO_STR(u) case u: return #u
2295 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIAS);
2296 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREPERSPECTIVE);
2297 D3DSTATE_TO_STR(WINED3D_RS_WRAPU);
2298 D3DSTATE_TO_STR(WINED3D_RS_WRAPV);
2299 D3DSTATE_TO_STR(WINED3D_RS_ZENABLE);
2300 D3DSTATE_TO_STR(WINED3D_RS_FILLMODE);
2301 D3DSTATE_TO_STR(WINED3D_RS_SHADEMODE);
2302 D3DSTATE_TO_STR(WINED3D_RS_LINEPATTERN);
2303 D3DSTATE_TO_STR(WINED3D_RS_MONOENABLE);
2304 D3DSTATE_TO_STR(WINED3D_RS_ROP2);
2305 D3DSTATE_TO_STR(WINED3D_RS_PLANEMASK);
2306 D3DSTATE_TO_STR(WINED3D_RS_ZWRITEENABLE);
2307 D3DSTATE_TO_STR(WINED3D_RS_ALPHATESTENABLE);
2308 D3DSTATE_TO_STR(WINED3D_RS_LASTPIXEL);
2309 D3DSTATE_TO_STR(WINED3D_RS_SRCBLEND);
2310 D3DSTATE_TO_STR(WINED3D_RS_DESTBLEND);
2311 D3DSTATE_TO_STR(WINED3D_RS_CULLMODE);
2312 D3DSTATE_TO_STR(WINED3D_RS_ZFUNC);
2313 D3DSTATE_TO_STR(WINED3D_RS_ALPHAREF);
2314 D3DSTATE_TO_STR(WINED3D_RS_ALPHAFUNC);
2315 D3DSTATE_TO_STR(WINED3D_RS_DITHERENABLE);
2316 D3DSTATE_TO_STR(WINED3D_RS_ALPHABLENDENABLE);
2317 D3DSTATE_TO_STR(WINED3D_RS_FOGENABLE);
2318 D3DSTATE_TO_STR(WINED3D_RS_SPECULARENABLE);
2319 D3DSTATE_TO_STR(WINED3D_RS_ZVISIBLE);
2320 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXEL);
2321 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXELX);
2322 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEDALPHA);
2323 D3DSTATE_TO_STR(WINED3D_RS_FOGCOLOR);
2324 D3DSTATE_TO_STR(WINED3D_RS_FOGTABLEMODE);
2325 D3DSTATE_TO_STR(WINED3D_RS_FOGSTART);
2326 D3DSTATE_TO_STR(WINED3D_RS_FOGEND);
2327 D3DSTATE_TO_STR(WINED3D_RS_FOGDENSITY);
2328 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEENABLE);
2329 D3DSTATE_TO_STR(WINED3D_RS_EDGEANTIALIAS);
2330 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYENABLE);
2331 D3DSTATE_TO_STR(WINED3D_RS_MIPMAPLODBIAS);
2332 D3DSTATE_TO_STR(WINED3D_RS_RANGEFOGENABLE);
2333 D3DSTATE_TO_STR(WINED3D_RS_ANISOTROPY);
2334 D3DSTATE_TO_STR(WINED3D_RS_FLUSHBATCH);
2335 D3DSTATE_TO_STR(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT);
2336 D3DSTATE_TO_STR(WINED3D_RS_STENCILENABLE);
2337 D3DSTATE_TO_STR(WINED3D_RS_STENCILFAIL);
2338 D3DSTATE_TO_STR(WINED3D_RS_STENCILZFAIL);
2339 D3DSTATE_TO_STR(WINED3D_RS_STENCILPASS);
2340 D3DSTATE_TO_STR(WINED3D_RS_STENCILFUNC);
2341 D3DSTATE_TO_STR(WINED3D_RS_STENCILREF);
2342 D3DSTATE_TO_STR(WINED3D_RS_STENCILMASK);
2343 D3DSTATE_TO_STR(WINED3D_RS_STENCILWRITEMASK);
2344 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREFACTOR);
2345 D3DSTATE_TO_STR(WINED3D_RS_WRAP0);
2346 D3DSTATE_TO_STR(WINED3D_RS_WRAP1);
2347 D3DSTATE_TO_STR(WINED3D_RS_WRAP2);
2348 D3DSTATE_TO_STR(WINED3D_RS_WRAP3);
2349 D3DSTATE_TO_STR(WINED3D_RS_WRAP4);
2350 D3DSTATE_TO_STR(WINED3D_RS_WRAP5);
2351 D3DSTATE_TO_STR(WINED3D_RS_WRAP6);
2352 D3DSTATE_TO_STR(WINED3D_RS_WRAP7);
2353 D3DSTATE_TO_STR(WINED3D_RS_CLIPPING);
2354 D3DSTATE_TO_STR(WINED3D_RS_LIGHTING);
2355 D3DSTATE_TO_STR(WINED3D_RS_EXTENTS);
2356 D3DSTATE_TO_STR(WINED3D_RS_AMBIENT);
2357 D3DSTATE_TO_STR(WINED3D_RS_FOGVERTEXMODE);
2358 D3DSTATE_TO_STR(WINED3D_RS_COLORVERTEX);
2359 D3DSTATE_TO_STR(WINED3D_RS_LOCALVIEWER);
2360 D3DSTATE_TO_STR(WINED3D_RS_NORMALIZENORMALS);
2361 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYBLENDENABLE);
2362 D3DSTATE_TO_STR(WINED3D_RS_DIFFUSEMATERIALSOURCE);
2363 D3DSTATE_TO_STR(WINED3D_RS_SPECULARMATERIALSOURCE);
2364 D3DSTATE_TO_STR(WINED3D_RS_AMBIENTMATERIALSOURCE);
2365 D3DSTATE_TO_STR(WINED3D_RS_EMISSIVEMATERIALSOURCE);
2366 D3DSTATE_TO_STR(WINED3D_RS_VERTEXBLEND);
2367 D3DSTATE_TO_STR(WINED3D_RS_CLIPPLANEENABLE);
2368 D3DSTATE_TO_STR(WINED3D_RS_SOFTWAREVERTEXPROCESSING);
2369 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE);
2370 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MIN);
2371 D3DSTATE_TO_STR(WINED3D_RS_POINTSPRITEENABLE);
2372 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALEENABLE);
2373 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_A);
2374 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_B);
2375 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_C);
2376 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEANTIALIAS);
2377 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEMASK);
2378 D3DSTATE_TO_STR(WINED3D_RS_PATCHEDGESTYLE);
2379 D3DSTATE_TO_STR(WINED3D_RS_PATCHSEGMENTS);
2380 D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN);
2381 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX);
2382 D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE);
2383 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
2384 D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR);
2385 D3DSTATE_TO_STR(WINED3D_RS_BLENDOP);
2386 D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE);
2387 D3DSTATE_TO_STR(WINED3D_RS_NORMALDEGREE);
2388 D3DSTATE_TO_STR(WINED3D_RS_SCISSORTESTENABLE);
2389 D3DSTATE_TO_STR(WINED3D_RS_SLOPESCALEDEPTHBIAS);
2390 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIASEDLINEENABLE);
2391 D3DSTATE_TO_STR(WINED3D_RS_MINTESSELLATIONLEVEL);
2392 D3DSTATE_TO_STR(WINED3D_RS_MAXTESSELLATIONLEVEL);
2393 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_X);
2394 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Y);
2395 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Z);
2396 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_W);
2397 D3DSTATE_TO_STR(WINED3D_RS_ENABLEADAPTIVETESSELLATION);
2398 D3DSTATE_TO_STR(WINED3D_RS_TWOSIDEDSTENCILMODE);
2399 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFAIL);
2400 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILZFAIL);
2401 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILPASS);
2402 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFUNC);
2403 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1);
2404 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2);
2405 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3);
2406 D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR);
2407 D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE);
2408 D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS);
2409 D3DSTATE_TO_STR(WINED3D_RS_WRAP8);
2410 D3DSTATE_TO_STR(WINED3D_RS_WRAP9);
2411 D3DSTATE_TO_STR(WINED3D_RS_WRAP10);
2412 D3DSTATE_TO_STR(WINED3D_RS_WRAP11);
2413 D3DSTATE_TO_STR(WINED3D_RS_WRAP12);
2414 D3DSTATE_TO_STR(WINED3D_RS_WRAP13);
2415 D3DSTATE_TO_STR(WINED3D_RS_WRAP14);
2416 D3DSTATE_TO_STR(WINED3D_RS_WRAP15);
2417 D3DSTATE_TO_STR(WINED3D_RS_SEPARATEALPHABLENDENABLE);
2418 D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
2419 D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
2420 D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
2421 #undef D3DSTATE_TO_STR
2422 default:
2423 FIXME("Unrecognized %u render state!\n", state);
2424 return "unrecognized";
2428 const char *debug_d3dsamplerstate(enum wined3d_sampler_state state)
2430 switch (state)
2432 #define D3DSTATE_TO_STR(u) case u: return #u
2433 D3DSTATE_TO_STR(WINED3D_SAMP_BORDER_COLOR);
2434 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_U);
2435 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_V);
2436 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_W);
2437 D3DSTATE_TO_STR(WINED3D_SAMP_MAG_FILTER);
2438 D3DSTATE_TO_STR(WINED3D_SAMP_MIN_FILTER);
2439 D3DSTATE_TO_STR(WINED3D_SAMP_MIP_FILTER);
2440 D3DSTATE_TO_STR(WINED3D_SAMP_MIPMAP_LOD_BIAS);
2441 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_MIP_LEVEL);
2442 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_ANISOTROPY);
2443 D3DSTATE_TO_STR(WINED3D_SAMP_SRGB_TEXTURE);
2444 D3DSTATE_TO_STR(WINED3D_SAMP_ELEMENT_INDEX);
2445 D3DSTATE_TO_STR(WINED3D_SAMP_DMAP_OFFSET);
2446 #undef D3DSTATE_TO_STR
2447 default:
2448 FIXME("Unrecognized %u sampler state!\n", state);
2449 return "unrecognized";
2453 const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type)
2455 switch (filter_type)
2457 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2458 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_NONE);
2459 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_POINT);
2460 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_LINEAR);
2461 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_ANISOTROPIC);
2462 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_FLAT_CUBIC);
2463 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_CUBIC);
2464 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_PYRAMIDAL_QUAD);
2465 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_QUAD);
2466 #undef D3DTEXTUREFILTERTYPE_TO_STR
2467 default:
2468 FIXME("Unrecognied texture filter type 0x%08x.\n", filter_type);
2469 return "unrecognized";
2473 const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state)
2475 switch (state)
2477 #define D3DSTATE_TO_STR(u) case u: return #u
2478 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_OP);
2479 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG1);
2480 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG2);
2481 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_OP);
2482 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG1);
2483 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG2);
2484 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT00);
2485 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT01);
2486 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT10);
2487 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT11);
2488 D3DSTATE_TO_STR(WINED3D_TSS_TEXCOORD_INDEX);
2489 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LSCALE);
2490 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LOFFSET);
2491 D3DSTATE_TO_STR(WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS);
2492 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG0);
2493 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG0);
2494 D3DSTATE_TO_STR(WINED3D_TSS_RESULT_ARG);
2495 D3DSTATE_TO_STR(WINED3D_TSS_CONSTANT);
2496 #undef D3DSTATE_TO_STR
2497 default:
2498 FIXME("Unrecognized %u texture state!\n", state);
2499 return "unrecognized";
2503 const char *debug_d3dtop(enum wined3d_texture_op d3dtop)
2505 switch (d3dtop)
2507 #define D3DTOP_TO_STR(u) case u: return #u
2508 D3DTOP_TO_STR(WINED3D_TOP_DISABLE);
2509 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG1);
2510 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG2);
2511 D3DTOP_TO_STR(WINED3D_TOP_MODULATE);
2512 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_2X);
2513 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_4X);
2514 D3DTOP_TO_STR(WINED3D_TOP_ADD);
2515 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED);
2516 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED_2X);
2517 D3DTOP_TO_STR(WINED3D_TOP_SUBTRACT);
2518 D3DTOP_TO_STR(WINED3D_TOP_ADD_SMOOTH);
2519 D3DTOP_TO_STR(WINED3D_TOP_BLEND_DIFFUSE_ALPHA);
2520 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA);
2521 D3DTOP_TO_STR(WINED3D_TOP_BLEND_FACTOR_ALPHA);
2522 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM);
2523 D3DTOP_TO_STR(WINED3D_TOP_BLEND_CURRENT_ALPHA);
2524 D3DTOP_TO_STR(WINED3D_TOP_PREMODULATE);
2525 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR);
2526 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA);
2527 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR);
2528 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA);
2529 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP);
2530 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP_LUMINANCE);
2531 D3DTOP_TO_STR(WINED3D_TOP_DOTPRODUCT3);
2532 D3DTOP_TO_STR(WINED3D_TOP_MULTIPLY_ADD);
2533 D3DTOP_TO_STR(WINED3D_TOP_LERP);
2534 #undef D3DTOP_TO_STR
2535 default:
2536 FIXME("Unrecognized texture op %#x.\n", d3dtop);
2537 return "unrecognized";
2541 const char *debug_d3dtstype(enum wined3d_transform_state tstype)
2543 switch (tstype)
2545 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2546 TSTYPE_TO_STR(WINED3D_TS_VIEW);
2547 TSTYPE_TO_STR(WINED3D_TS_PROJECTION);
2548 TSTYPE_TO_STR(WINED3D_TS_TEXTURE0);
2549 TSTYPE_TO_STR(WINED3D_TS_TEXTURE1);
2550 TSTYPE_TO_STR(WINED3D_TS_TEXTURE2);
2551 TSTYPE_TO_STR(WINED3D_TS_TEXTURE3);
2552 TSTYPE_TO_STR(WINED3D_TS_TEXTURE4);
2553 TSTYPE_TO_STR(WINED3D_TS_TEXTURE5);
2554 TSTYPE_TO_STR(WINED3D_TS_TEXTURE6);
2555 TSTYPE_TO_STR(WINED3D_TS_TEXTURE7);
2556 TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(0));
2557 #undef TSTYPE_TO_STR
2558 default:
2559 if (tstype > 256 && tstype < 512)
2561 FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype);
2562 return ("WINED3D_TS_WORLD_MATRIX > 0");
2564 FIXME("Unrecognized transform state %#x.\n", tstype);
2565 return "unrecognized";
2569 const char *debug_d3dstate(DWORD state)
2571 if (STATE_IS_RENDER(state))
2572 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2573 if (STATE_IS_TEXTURESTAGE(state))
2575 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2576 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2577 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2578 texture_stage, debug_d3dtexturestate(texture_state));
2580 if (STATE_IS_SAMPLER(state))
2581 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2582 if (STATE_IS_PIXELSHADER(state))
2583 return "STATE_PIXELSHADER";
2584 if (STATE_IS_TRANSFORM(state))
2585 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2586 if (STATE_IS_STREAMSRC(state))
2587 return "STATE_STREAMSRC";
2588 if (STATE_IS_INDEXBUFFER(state))
2589 return "STATE_INDEXBUFFER";
2590 if (STATE_IS_VDECL(state))
2591 return "STATE_VDECL";
2592 if (STATE_IS_VSHADER(state))
2593 return "STATE_VSHADER";
2594 if (STATE_IS_GEOMETRY_SHADER(state))
2595 return "STATE_GEOMETRY_SHADER";
2596 if (STATE_IS_VIEWPORT(state))
2597 return "STATE_VIEWPORT";
2598 if (STATE_IS_LIGHT_TYPE(state))
2599 return "STATE_LIGHT_TYPE";
2600 if (STATE_IS_ACTIVELIGHT(state))
2601 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2602 if (STATE_IS_SCISSORRECT(state))
2603 return "STATE_SCISSORRECT";
2604 if (STATE_IS_CLIPPLANE(state))
2605 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2606 if (STATE_IS_MATERIAL(state))
2607 return "STATE_MATERIAL";
2608 if (STATE_IS_FRONTFACE(state))
2609 return "STATE_FRONTFACE";
2610 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2611 return "STATE_POINTSPRITECOORDORIGIN";
2612 if (STATE_IS_BASEVERTEXINDEX(state))
2613 return "STATE_BASEVERTEXINDEX";
2614 if (STATE_IS_FRAMEBUFFER(state))
2615 return "STATE_FRAMEBUFFER";
2616 if (STATE_IS_POINT_SIZE_ENABLE(state))
2617 return "STATE_POINT_SIZE_ENABLE";
2619 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2622 const char *debug_d3dpool(enum wined3d_pool pool)
2624 switch (pool)
2626 #define POOL_TO_STR(p) case p: return #p
2627 POOL_TO_STR(WINED3D_POOL_DEFAULT);
2628 POOL_TO_STR(WINED3D_POOL_MANAGED);
2629 POOL_TO_STR(WINED3D_POOL_SYSTEM_MEM);
2630 POOL_TO_STR(WINED3D_POOL_SCRATCH);
2631 #undef POOL_TO_STR
2632 default:
2633 FIXME("Unrecognized pool %#x.\n", pool);
2634 return "unrecognized";
2638 const char *debug_fbostatus(GLenum status) {
2639 switch(status) {
2640 #define FBOSTATUS_TO_STR(u) case u: return #u
2641 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2642 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2643 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2644 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2645 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2646 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2647 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2648 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2649 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2650 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2651 #undef FBOSTATUS_TO_STR
2652 default:
2653 FIXME("Unrecognied FBO status 0x%08x\n", status);
2654 return "unrecognized";
2658 const char *debug_glerror(GLenum error) {
2659 switch(error) {
2660 #define GLERROR_TO_STR(u) case u: return #u
2661 GLERROR_TO_STR(GL_NO_ERROR);
2662 GLERROR_TO_STR(GL_INVALID_ENUM);
2663 GLERROR_TO_STR(GL_INVALID_VALUE);
2664 GLERROR_TO_STR(GL_INVALID_OPERATION);
2665 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2666 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2667 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2668 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2669 #undef GLERROR_TO_STR
2670 default:
2671 FIXME("Unrecognied GL error 0x%08x\n", error);
2672 return "unrecognized";
2676 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2678 switch(source)
2680 #define WINED3D_TO_STR(x) case x: return #x
2681 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2682 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2683 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2684 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2685 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2686 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2687 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2688 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2689 #undef WINED3D_TO_STR
2690 default:
2691 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2692 return "unrecognized";
2696 static const char *debug_complex_fixup(enum complex_fixup fixup)
2698 switch(fixup)
2700 #define WINED3D_TO_STR(x) case x: return #x
2701 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2702 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2703 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2704 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2705 #undef WINED3D_TO_STR
2706 default:
2707 FIXME("Unrecognized complex fixup %#x\n", fixup);
2708 return "unrecognized";
2712 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2714 if (is_complex_fixup(fixup))
2716 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2717 return;
2720 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2721 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2722 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2723 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2726 const char *debug_surflocation(DWORD flag) {
2727 char buf[128];
2729 buf[0] = 0;
2730 if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM"); /* 17 */
2731 if (flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE"); /* 19 */
2732 if (flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE"); /* 18 */
2733 if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX"); /* 18 */
2734 if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE"); /* 25 */
2735 if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED"); /* 22 */
2736 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2739 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2740 enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2742 if (op == WINED3D_TOP_DISABLE)
2743 return FALSE;
2744 if (state->textures[stage])
2745 return FALSE;
2747 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2748 && op != WINED3D_TOP_SELECT_ARG2)
2749 return TRUE;
2750 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2751 && op != WINED3D_TOP_SELECT_ARG1)
2752 return TRUE;
2753 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2754 && (op == WINED3D_TOP_MULTIPLY_ADD || op == WINED3D_TOP_LERP))
2755 return TRUE;
2757 return FALSE;
2760 /* Setup this textures matrix according to the texture flags. */
2761 /* Context activation is done by the caller (state handler). */
2762 void set_texture_matrix(const struct wined3d_gl_info *gl_info, const float *smat, DWORD flags,
2763 BOOL calculatedCoords, BOOL transformed, enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2765 float mat[16];
2767 gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
2768 checkGLcall("glMatrixMode(GL_TEXTURE)");
2770 if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed)
2772 gl_info->gl_ops.gl.p_glLoadIdentity();
2773 checkGLcall("glLoadIdentity()");
2774 return;
2777 if (flags == (WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED))
2779 ERR("Invalid texture transform flags: WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED.\n");
2780 return;
2783 memcpy(mat, smat, 16 * sizeof(float));
2785 if (flags & WINED3D_TTFF_PROJECTED)
2787 if (!ffp_proj_control)
2789 switch (flags & ~WINED3D_TTFF_PROJECTED)
2791 case WINED3D_TTFF_COUNT2:
2792 mat[ 3] = mat[ 1];
2793 mat[ 7] = mat[ 5];
2794 mat[11] = mat[ 9];
2795 mat[15] = mat[13];
2796 mat[ 1] = mat[ 5] = mat[ 9] = mat[13] = 0.0f;
2797 break;
2798 case WINED3D_TTFF_COUNT3:
2799 mat[ 3] = mat[ 2];
2800 mat[ 7] = mat[ 6];
2801 mat[11] = mat[10];
2802 mat[15] = mat[14];
2803 mat[ 2] = mat[ 6] = mat[10] = mat[14] = 0.0f;
2804 break;
2807 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2808 if(!calculatedCoords) {
2809 switch(vtx_fmt)
2811 case WINED3DFMT_R32_FLOAT:
2812 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2813 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2814 * the input value to the transformation will be 0, so the matrix value is irrelevant
2816 mat[12] = mat[4];
2817 mat[13] = mat[5];
2818 mat[14] = mat[6];
2819 mat[15] = mat[7];
2820 break;
2821 case WINED3DFMT_R32G32_FLOAT:
2822 /* See above, just 3rd and 4th coord
2824 mat[12] = mat[8];
2825 mat[13] = mat[9];
2826 mat[14] = mat[10];
2827 mat[15] = mat[11];
2828 break;
2829 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2830 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2832 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2833 * into a bad place. The division elimination below will apply to make sure the
2834 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2836 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2837 break;
2838 default:
2839 FIXME("Unexpected fixed function texture coord input\n");
2842 if (!ffp_proj_control)
2844 switch (flags & ~WINED3D_TTFF_PROJECTED)
2846 /* case WINED3D_TTFF_COUNT1: Won't ever get here. */
2847 case WINED3D_TTFF_COUNT2:
2848 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2849 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2850 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2851 * the 4th coord evaluates to 1.0 to eliminate that.
2853 * If the fixed function pipeline is used, the 4th value remains unused,
2854 * so there is no danger in doing this. With vertex shaders we have a
2855 * problem. Should an app hit that problem, the code here would have to
2856 * check for pixel shaders, and the shader has to undo the default gl divide.
2858 * A more serious problem occurs if the app passes 4 coordinates in, and the
2859 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2860 * or a replacement shader. */
2861 default:
2862 mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2867 gl_info->gl_ops.gl.p_glLoadMatrixf(mat);
2868 checkGLcall("glLoadMatrixf(mat)");
2871 /* This small helper function is used to convert a bitmask into the number of masked bits */
2872 unsigned int count_bits(unsigned int mask)
2874 unsigned int count;
2875 for (count = 0; mask; ++count)
2877 mask &= mask - 1;
2879 return count;
2882 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2883 * The later function requires individual color components. */
2884 BOOL getColorBits(const struct wined3d_format *format,
2885 BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2887 TRACE("format %s.\n", debug_d3dformat(format->id));
2889 switch (format->id)
2891 case WINED3DFMT_B10G10R10A2_UNORM:
2892 case WINED3DFMT_R10G10B10A2_UNORM:
2893 case WINED3DFMT_B8G8R8X8_UNORM:
2894 case WINED3DFMT_B8G8R8_UNORM:
2895 case WINED3DFMT_B8G8R8A8_UNORM:
2896 case WINED3DFMT_R8G8B8A8_UNORM:
2897 case WINED3DFMT_B5G5R5X1_UNORM:
2898 case WINED3DFMT_B5G5R5A1_UNORM:
2899 case WINED3DFMT_B5G6R5_UNORM:
2900 case WINED3DFMT_B4G4R4X4_UNORM:
2901 case WINED3DFMT_B4G4R4A4_UNORM:
2902 case WINED3DFMT_B2G3R3_UNORM:
2903 case WINED3DFMT_P8_UINT_A8_UNORM:
2904 case WINED3DFMT_P8_UINT:
2905 break;
2906 default:
2907 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2908 return FALSE;
2911 *redSize = format->red_size;
2912 *greenSize = format->green_size;
2913 *blueSize = format->blue_size;
2914 *alphaSize = format->alpha_size;
2915 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2917 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2918 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2919 return TRUE;
2922 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2923 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
2925 TRACE("format %s.\n", debug_d3dformat(format->id));
2927 switch (format->id)
2929 case WINED3DFMT_D16_LOCKABLE:
2930 case WINED3DFMT_D16_UNORM:
2931 case WINED3DFMT_S1_UINT_D15_UNORM:
2932 case WINED3DFMT_X8D24_UNORM:
2933 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2934 case WINED3DFMT_D24_UNORM_S8_UINT:
2935 case WINED3DFMT_S8_UINT_D24_FLOAT:
2936 case WINED3DFMT_D32_UNORM:
2937 case WINED3DFMT_D32_FLOAT:
2938 case WINED3DFMT_INTZ:
2939 break;
2940 default:
2941 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2942 return FALSE;
2945 *depthSize = format->depth_size;
2946 *stencilSize = format->stencil_size;
2948 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2949 *depthSize, *stencilSize, debug_d3dformat(format->id));
2950 return TRUE;
2953 /* Note: It's the caller's responsibility to ensure values can be expressed
2954 * in the requested format. UNORM formats for example can only express values
2955 * in the range 0.0f -> 1.0f. */
2956 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color)
2958 static const struct
2960 enum wined3d_format_id format_id;
2961 float r_mul;
2962 float g_mul;
2963 float b_mul;
2964 float a_mul;
2965 BYTE r_shift;
2966 BYTE g_shift;
2967 BYTE b_shift;
2968 BYTE a_shift;
2970 conv[] =
2972 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2973 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2974 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2975 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2976 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2977 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2978 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2979 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2980 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2981 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2982 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2983 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2984 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2985 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2987 const struct wined3d_format *format = surface->resource.format;
2988 unsigned int i;
2990 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2991 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2993 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2995 DWORD ret;
2997 if (format->id != conv[i].format_id) continue;
2999 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
3000 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
3001 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
3002 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
3004 TRACE("Returning 0x%08x.\n", ret);
3006 return ret;
3009 if (format->id == WINED3DFMT_P8_UINT)
3011 PALETTEENTRY *e;
3012 BYTE r, g, b, a;
3014 if (!surface->palette)
3016 WARN("Surface doesn't have a palette, returning 0.\n");
3017 return 0;
3020 r = (BYTE)((color->r * 255.0f) + 0.5f);
3021 g = (BYTE)((color->g * 255.0f) + 0.5f);
3022 b = (BYTE)((color->b * 255.0f) + 0.5f);
3023 a = (BYTE)((color->a * 255.0f) + 0.5f);
3025 e = &surface->palette->palents[a];
3026 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
3027 return a;
3029 WARN("Alpha didn't match index, searching full palette.\n");
3031 for (i = 0; i < 256; ++i)
3033 e = &surface->palette->palents[i];
3034 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
3035 return i;
3038 FIXME("Unable to convert color to palette index.\n");
3040 return 0;
3043 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
3045 return 0;
3048 /* DirectDraw stuff */
3049 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
3051 switch (depth)
3053 case 8: return WINED3DFMT_P8_UINT;
3054 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
3055 case 16: return WINED3DFMT_B5G6R5_UNORM;
3056 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
3057 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
3058 default: return WINED3DFMT_UNKNOWN;
3062 void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
3063 const struct wined3d_matrix *src2)
3065 struct wined3d_matrix temp;
3067 /* Now do the multiplication 'by hand'.
3068 I know that all this could be optimised, but this will be done later :-) */
3069 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);
3070 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);
3071 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);
3072 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);
3074 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);
3075 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);
3076 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);
3077 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);
3079 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);
3080 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);
3081 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);
3082 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);
3084 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);
3085 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);
3086 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);
3087 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);
3089 /* And copy the new matrix in the good storage.. */
3090 memcpy(dest, &temp, 16 * sizeof(float));
3093 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
3094 DWORD size = 0;
3095 int i;
3096 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
3098 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
3099 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
3100 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
3101 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
3102 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
3103 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
3104 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
3105 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
3106 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
3107 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
3108 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
3109 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
3110 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
3111 default: ERR("Unexpected position mask\n");
3113 for (i = 0; i < numTextures; i++) {
3114 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
3117 return size;
3120 void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d_state *state,
3121 struct ffp_frag_settings *settings, BOOL ignore_textype)
3123 #define ARG1 0x01
3124 #define ARG2 0x02
3125 #define ARG0 0x04
3126 static const unsigned char args[WINED3D_TOP_LERP + 1] =
3128 /* undefined */ 0,
3129 /* D3DTOP_DISABLE */ 0,
3130 /* D3DTOP_SELECTARG1 */ ARG1,
3131 /* D3DTOP_SELECTARG2 */ ARG2,
3132 /* D3DTOP_MODULATE */ ARG1 | ARG2,
3133 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
3134 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
3135 /* D3DTOP_ADD */ ARG1 | ARG2,
3136 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
3137 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
3138 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
3139 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
3140 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
3141 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
3142 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
3143 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
3144 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
3145 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
3146 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
3147 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
3148 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
3149 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
3150 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
3151 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
3152 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
3153 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
3154 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
3156 unsigned int i;
3157 DWORD ttff;
3158 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
3159 const struct wined3d_surface *rt = state->fb->render_targets[0];
3160 const struct wined3d_gl_info *gl_info = context->gl_info;
3161 const struct wined3d_d3d_info *d3d_info = context->d3d_info;
3163 for (i = 0; i < d3d_info->limits.ffp_blend_stages; ++i)
3165 const struct wined3d_texture *texture;
3167 settings->op[i].padding = 0;
3168 if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
3170 settings->op[i].cop = WINED3D_TOP_DISABLE;
3171 settings->op[i].aop = WINED3D_TOP_DISABLE;
3172 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
3173 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
3174 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
3175 settings->op[i].dst = resultreg;
3176 settings->op[i].tex_type = tex_1d;
3177 settings->op[i].projected = proj_none;
3178 i++;
3179 break;
3182 if ((texture = state->textures[i]))
3184 settings->op[i].color_fixup = texture->resource.format->color_fixup;
3185 if (ignore_textype)
3187 settings->op[i].tex_type = tex_1d;
3189 else
3191 switch (texture->target)
3193 case GL_TEXTURE_1D:
3194 settings->op[i].tex_type = tex_1d;
3195 break;
3196 case GL_TEXTURE_2D:
3197 settings->op[i].tex_type = tex_2d;
3198 break;
3199 case GL_TEXTURE_3D:
3200 settings->op[i].tex_type = tex_3d;
3201 break;
3202 case GL_TEXTURE_CUBE_MAP_ARB:
3203 settings->op[i].tex_type = tex_cube;
3204 break;
3205 case GL_TEXTURE_RECTANGLE_ARB:
3206 settings->op[i].tex_type = tex_rect;
3207 break;
3210 } else {
3211 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
3212 settings->op[i].tex_type = tex_1d;
3215 cop = state->texture_states[i][WINED3D_TSS_COLOR_OP];
3216 aop = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
3218 carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG1] : ARG_UNUSED;
3219 carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG2] : ARG_UNUSED;
3220 carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG0] : ARG_UNUSED;
3222 if (is_invalid_op(state, i, cop, carg1, carg2, carg0))
3224 carg0 = ARG_UNUSED;
3225 carg2 = ARG_UNUSED;
3226 carg1 = WINED3DTA_CURRENT;
3227 cop = WINED3D_TOP_SELECT_ARG1;
3230 if (cop == WINED3D_TOP_DOTPRODUCT3)
3232 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
3233 * the color result to the alpha component of the destination
3235 aop = cop;
3236 aarg1 = carg1;
3237 aarg2 = carg2;
3238 aarg0 = carg0;
3240 else
3242 aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] : ARG_UNUSED;
3243 aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] : ARG_UNUSED;
3244 aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] : ARG_UNUSED;
3247 if (!i && state->textures[0] && state->render_states[WINED3D_RS_COLORKEYENABLE])
3249 GLenum texture_dimensions;
3251 texture = state->textures[0];
3252 texture_dimensions = texture->target;
3254 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3256 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3258 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size)
3260 if (aop == WINED3D_TOP_DISABLE)
3262 aarg1 = WINED3DTA_TEXTURE;
3263 aop = WINED3D_TOP_SELECT_ARG1;
3265 else if (aop == WINED3D_TOP_SELECT_ARG1 && aarg1 != WINED3DTA_TEXTURE)
3267 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3269 aarg2 = WINED3DTA_TEXTURE;
3270 aop = WINED3D_TOP_MODULATE;
3272 else aarg1 = WINED3DTA_TEXTURE;
3274 else if (aop == WINED3D_TOP_SELECT_ARG2 && aarg2 != WINED3DTA_TEXTURE)
3276 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3278 aarg1 = WINED3DTA_TEXTURE;
3279 aop = WINED3D_TOP_MODULATE;
3281 else aarg2 = WINED3DTA_TEXTURE;
3287 if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0))
3289 aarg0 = ARG_UNUSED;
3290 aarg2 = ARG_UNUSED;
3291 aarg1 = WINED3DTA_CURRENT;
3292 aop = WINED3D_TOP_SELECT_ARG1;
3295 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
3296 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
3298 ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
3299 if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3))
3300 settings->op[i].projected = proj_count3;
3301 else if (ttff & WINED3D_TTFF_PROJECTED)
3302 settings->op[i].projected = proj_count4;
3303 else
3304 settings->op[i].projected = proj_none;
3306 else
3308 settings->op[i].projected = proj_none;
3311 settings->op[i].cop = cop;
3312 settings->op[i].aop = aop;
3313 settings->op[i].carg0 = carg0;
3314 settings->op[i].carg1 = carg1;
3315 settings->op[i].carg2 = carg2;
3316 settings->op[i].aarg0 = aarg0;
3317 settings->op[i].aarg1 = aarg1;
3318 settings->op[i].aarg2 = aarg2;
3320 if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP)
3321 settings->op[i].dst = tempreg;
3322 else
3323 settings->op[i].dst = resultreg;
3326 /* Clear unsupported stages */
3327 for(; i < MAX_TEXTURES; i++) {
3328 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
3331 if (!state->render_states[WINED3D_RS_FOGENABLE])
3333 settings->fog = WINED3D_FFP_PS_FOG_OFF;
3335 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
3337 if (use_vs(state) || state->vertex_declaration->position_transformed)
3339 settings->fog = WINED3D_FFP_PS_FOG_LINEAR;
3341 else
3343 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
3345 case WINED3D_FOG_NONE:
3346 case WINED3D_FOG_LINEAR:
3347 settings->fog = WINED3D_FFP_PS_FOG_LINEAR;
3348 break;
3349 case WINED3D_FOG_EXP:
3350 settings->fog = WINED3D_FFP_PS_FOG_EXP;
3351 break;
3352 case WINED3D_FOG_EXP2:
3353 settings->fog = WINED3D_FFP_PS_FOG_EXP2;
3354 break;
3358 else
3360 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
3362 case WINED3D_FOG_LINEAR:
3363 settings->fog = WINED3D_FFP_PS_FOG_LINEAR;
3364 break;
3365 case WINED3D_FOG_EXP:
3366 settings->fog = WINED3D_FFP_PS_FOG_EXP;
3367 break;
3368 case WINED3D_FOG_EXP2:
3369 settings->fog = WINED3D_FFP_PS_FOG_EXP2;
3370 break;
3373 if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB]
3374 && state->render_states[WINED3D_RS_SRGBWRITEENABLE]
3375 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
3377 settings->sRGB_write = 1;
3378 } else {
3379 settings->sRGB_write = 0;
3381 if (d3d_info->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
3382 || !state->render_states[WINED3D_RS_CLIPPLANEENABLE])
3384 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3385 * the fixed function vertex pipeline is used(which always supports clipplanes), or
3386 * if no clipplane is enabled
3388 settings->emul_clipplanes = 0;
3389 } else {
3390 settings->emul_clipplanes = 1;
3394 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3395 const struct ffp_frag_settings *settings)
3397 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3398 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3401 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3403 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3404 * whereas desc points to an extended structure with implementation specific parts. */
3405 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3407 ERR("Failed to insert ffp frag shader.\n");
3411 /* Activates the texture dimension according to the bound D3D texture. Does
3412 * not care for the colorop or correct gl texture unit (when using nvrc).
3413 * Requires the caller to activate the correct unit. */
3414 /* Context activation is done by the caller (state handler). */
3415 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3417 if (texture)
3419 switch (texture->target)
3421 case GL_TEXTURE_2D:
3422 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3423 checkGLcall("glDisable(GL_TEXTURE_3D)");
3424 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3426 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3427 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3429 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3431 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3432 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3434 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3435 checkGLcall("glEnable(GL_TEXTURE_2D)");
3436 break;
3437 case GL_TEXTURE_RECTANGLE_ARB:
3438 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3439 checkGLcall("glDisable(GL_TEXTURE_2D)");
3440 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3441 checkGLcall("glDisable(GL_TEXTURE_3D)");
3442 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3444 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3445 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3447 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_RECTANGLE_ARB);
3448 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3449 break;
3450 case GL_TEXTURE_3D:
3451 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3453 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3454 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3456 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3458 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3459 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3461 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3462 checkGLcall("glDisable(GL_TEXTURE_2D)");
3463 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D);
3464 checkGLcall("glEnable(GL_TEXTURE_3D)");
3465 break;
3466 case GL_TEXTURE_CUBE_MAP_ARB:
3467 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3468 checkGLcall("glDisable(GL_TEXTURE_2D)");
3469 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3470 checkGLcall("glDisable(GL_TEXTURE_3D)");
3471 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3473 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3474 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3476 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3477 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3478 break;
3481 else
3483 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3484 checkGLcall("glEnable(GL_TEXTURE_2D)");
3485 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3486 checkGLcall("glDisable(GL_TEXTURE_3D)");
3487 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3489 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3490 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3492 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3494 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3495 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3497 /* Binding textures is done by samplers. A dummy texture will be bound */
3501 /* Context activation is done by the caller (state handler). */
3502 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3504 DWORD sampler = state_id - STATE_SAMPLER(0);
3505 DWORD mapped_stage = context->tex_unit_map[sampler];
3507 /* No need to enable / disable anything here for unused samplers. The
3508 * tex_colorop handler takes care. Also no action is needed with pixel
3509 * shaders, or if tex_colorop will take care of this business. */
3510 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
3511 return;
3512 if (sampler >= state->lowest_disabled_stage)
3513 return;
3514 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)))
3515 return;
3517 texture_activate_dimensions(state->textures[sampler], context->gl_info);
3520 void *wined3d_rb_alloc(size_t size)
3522 return HeapAlloc(GetProcessHeap(), 0, size);
3525 void *wined3d_rb_realloc(void *ptr, size_t size)
3527 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3530 void wined3d_rb_free(void *ptr)
3532 HeapFree(GetProcessHeap(), 0, ptr);
3535 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3537 const struct ffp_frag_settings *ka = key;
3538 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3540 return memcmp(ka, kb, sizeof(*ka));
3543 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3545 wined3d_rb_alloc,
3546 wined3d_rb_realloc,
3547 wined3d_rb_free,
3548 ffp_frag_program_key_compare,
3551 void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct wined3d_stream_info *si,
3552 struct wined3d_ffp_vs_settings *settings)
3554 unsigned int coord_idx, i;
3556 if (si->position_transformed)
3558 memset(settings, 0, sizeof(*settings));
3560 settings->transformed = 1;
3561 settings->point_size = state->gl_primitive_type == GL_POINTS;
3562 if (!state->render_states[WINED3D_RS_FOGENABLE])
3563 settings->fog_mode = WINED3D_FFP_VS_FOG_OFF;
3564 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
3565 settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
3566 else
3567 settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD;
3569 for (i = 0; i < MAX_TEXTURES; ++i)
3571 coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
3572 if (coord_idx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
3573 settings->texcoords |= 1 << i;
3574 settings->texgen[i] = (state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT)
3575 & WINED3D_FFP_TCI_MASK;
3577 return;
3580 settings->transformed = 0;
3581 settings->clipping = state->render_states[WINED3D_RS_CLIPPING]
3582 && state->render_states[WINED3D_RS_CLIPPLANEENABLE];
3583 settings->normal = !!(si->use_map & (1 << WINED3D_FFP_NORMAL));
3584 settings->normalize = settings->normal && state->render_states[WINED3D_RS_NORMALIZENORMALS];
3585 settings->lighting = !!state->render_states[WINED3D_RS_LIGHTING];
3586 settings->localviewer = !!state->render_states[WINED3D_RS_LOCALVIEWER];
3587 settings->point_size = state->gl_primitive_type == GL_POINTS;
3589 if (state->render_states[WINED3D_RS_COLORVERTEX] && (si->use_map & (1 << WINED3D_FFP_DIFFUSE)))
3591 settings->diffuse_source = state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE];
3592 settings->emission_source = state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE];
3593 settings->ambient_source = state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE];
3594 settings->specular_source = state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE];
3596 else
3598 settings->diffuse_source = WINED3D_MCS_MATERIAL;
3599 settings->emission_source = WINED3D_MCS_MATERIAL;
3600 settings->ambient_source = WINED3D_MCS_MATERIAL;
3601 settings->specular_source = WINED3D_MCS_MATERIAL;
3604 settings->texcoords = 0;
3605 for (i = 0; i < MAX_TEXTURES; ++i)
3607 coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
3608 if (coord_idx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
3609 settings->texcoords |= 1 << i;
3610 settings->texgen[i] = (state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT)
3611 & WINED3D_FFP_TCI_MASK;
3614 settings->light_type = 0;
3615 for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i)
3617 if (state->lights[i])
3618 settings->light_type |= (state->lights[i]->OriginalParms.type
3619 & WINED3D_FFP_LIGHT_TYPE_MASK) << WINED3D_FFP_LIGHT_TYPE_SHIFT(i);
3622 settings->ortho_fog = 0;
3623 if (!state->render_states[WINED3D_RS_FOGENABLE])
3624 settings->fog_mode = WINED3D_FFP_VS_FOG_OFF;
3625 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
3627 settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
3629 if (state->transforms[WINED3D_TS_PROJECTION].u.m[0][3] == 0.0f
3630 && state->transforms[WINED3D_TS_PROJECTION].u.m[1][3] == 0.0f
3631 && state->transforms[WINED3D_TS_PROJECTION].u.m[2][3] == 0.0f
3632 && state->transforms[WINED3D_TS_PROJECTION].u.m[3][3] == 1.0f)
3633 settings->ortho_fog = 1;
3635 else if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE)
3636 settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD;
3637 else if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
3638 settings->fog_mode = WINED3D_FFP_VS_FOG_RANGE;
3639 else
3640 settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
3642 settings->padding = 0;
3645 static int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3647 const struct wined3d_ffp_vs_settings *ka = key;
3648 const struct wined3d_ffp_vs_settings *kb = &WINE_RB_ENTRY_VALUE(entry,
3649 const struct wined3d_ffp_vs_desc, entry)->settings;
3651 return memcmp(ka, kb, sizeof(*ka));
3654 const struct wine_rb_functions wined3d_ffp_vertex_program_rb_functions =
3656 wined3d_rb_alloc,
3657 wined3d_rb_realloc,
3658 wined3d_rb_free,
3659 wined3d_ffp_vertex_program_key_compare,
3662 UINT wined3d_log2i(UINT32 x)
3664 static const UINT l[] =
3666 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3667 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3668 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3669 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3670 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3671 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3672 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3673 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3674 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3675 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3676 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3677 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3678 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3679 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3680 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3681 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3683 UINT32 i;
3685 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3688 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3689 const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
3690 const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
3692 static const struct blit_shader * const blitters[] =
3694 &arbfp_blit,
3695 &ffp_blit,
3696 &cpu_blit,
3698 unsigned int i;
3700 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3702 if (blitters[i]->blit_supported(gl_info, blit_op,
3703 src_rect, src_usage, src_pool, src_format,
3704 dst_rect, dst_usage, dst_pool, dst_format))
3705 return blitters[i];
3708 return NULL;
3711 void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
3713 const struct wined3d_viewport *vp = &state->viewport;
3715 SetRect(rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
3717 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
3718 IntersectRect(rect, rect, &state->scissor_rect);
3721 const char *wined3d_debug_location(DWORD location)
3723 char buf[200];
3725 buf[0] = '\0';
3726 #define LOCATION_TO_STR(u) if (location & u) { strcat(buf, " | "#u); location &= ~u; }
3727 LOCATION_TO_STR(WINED3D_LOCATION_DISCARDED);
3728 LOCATION_TO_STR(WINED3D_LOCATION_SYSMEM);
3729 LOCATION_TO_STR(WINED3D_LOCATION_BUFFER);
3730 LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_RGB);
3731 LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_SRGB);
3732 #undef LOCATION_TO_STR
3733 if (location) FIXME("Unrecognized location flag(s) %#x.\n", location);
3735 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
3738 /* This should be equivalent to using the %.8e format specifier, but always
3739 * using '.' as decimal separator. This doesn't handle +/-INF or NAN, since
3740 * the GLSL and ARB parsers wouldn't be able to handle those anyway. */
3741 void wined3d_ftoa(float value, char *s)
3743 int x, frac, exponent;
3744 const char *sign = "";
3745 double d;
3747 d = value;
3748 if (copysignf(1.0f, value) < 0.0f)
3750 d = -d;
3751 sign = "-";
3754 if (d == 0.0f)
3756 x = 0;
3757 frac = 0;
3758 exponent = 0;
3760 else
3762 double t, diff;
3764 exponent = floorf(log10f(d));
3765 d /= pow(10.0, exponent);
3767 x = d;
3768 t = (d - x) * 100000000;
3769 frac = t;
3770 diff = t - frac;
3772 if ((diff > 0.5) || (diff == 0.5 && (frac & 1)))
3774 if (++frac >= 100000000)
3776 frac = 0;
3777 ++x;
3782 sprintf(s, "%s%d.%08de%+03d", sign, x, frac, exponent);