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