Partial merge of condrv_restructure branch r65657.
[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_NV12, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
54 {WINED3DFMT_DXT1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
55 {WINED3DFMT_DXT2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
56 {WINED3DFMT_DXT3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
57 {WINED3DFMT_DXT4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
58 {WINED3DFMT_DXT5, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
59 {WINED3DFMT_MULTI2_ARGB8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
60 {WINED3DFMT_G8R8_G8B8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
61 {WINED3DFMT_R8G8_B8G8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
62 /* IEEE formats */
63 {WINED3DFMT_R32_FLOAT, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
64 {WINED3DFMT_R32G32_FLOAT, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0},
65 {WINED3DFMT_R32G32B32_FLOAT, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0},
66 {WINED3DFMT_R32G32B32A32_FLOAT, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0},
67 /* Hmm? */
68 {WINED3DFMT_R8G8_SNORM_Cx, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
69 /* Float */
70 {WINED3DFMT_R16_FLOAT, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
71 {WINED3DFMT_R16G16_FLOAT, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
72 {WINED3DFMT_R16G16_SINT, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
73 {WINED3DFMT_R16G16B16A16_FLOAT, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
74 {WINED3DFMT_R16G16B16A16_SINT, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
75 /* Palettized formats */
76 {WINED3DFMT_P8_UINT_A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 8, 2, 0, 0},
77 {WINED3DFMT_P8_UINT, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
78 /* Standard ARGB formats. */
79 {WINED3DFMT_B8G8R8_UNORM, 8, 8, 8, 0, 16, 8, 0, 0, 3, 0, 0},
80 {WINED3DFMT_B8G8R8A8_UNORM, 8, 8, 8, 8, 16, 8, 0, 24, 4, 0, 0},
81 {WINED3DFMT_B8G8R8X8_UNORM, 8, 8, 8, 0, 16, 8, 0, 0, 4, 0, 0},
82 {WINED3DFMT_B5G6R5_UNORM, 5, 6, 5, 0, 11, 5, 0, 0, 2, 0, 0},
83 {WINED3DFMT_B5G5R5X1_UNORM, 5, 5, 5, 0, 10, 5, 0, 0, 2, 0, 0},
84 {WINED3DFMT_B5G5R5A1_UNORM, 5, 5, 5, 1, 10, 5, 0, 15, 2, 0, 0},
85 {WINED3DFMT_B4G4R4A4_UNORM, 4, 4, 4, 4, 8, 4, 0, 12, 2, 0, 0},
86 {WINED3DFMT_B2G3R3_UNORM, 3, 3, 2, 0, 5, 2, 0, 0, 1, 0, 0},
87 {WINED3DFMT_R8_UNORM, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
88 {WINED3DFMT_A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 0, 1, 0, 0},
89 {WINED3DFMT_B2G3R3A8_UNORM, 3, 3, 2, 8, 5, 2, 0, 8, 2, 0, 0},
90 {WINED3DFMT_B4G4R4X4_UNORM, 4, 4, 4, 0, 8, 4, 0, 0, 2, 0, 0},
91 {WINED3DFMT_R10G10B10A2_UNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
92 {WINED3DFMT_R10G10B10A2_UINT, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
93 {WINED3DFMT_R10G10B10A2_SNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
94 {WINED3DFMT_R8G8B8A8_UNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
95 {WINED3DFMT_R8G8B8A8_UINT, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
96 {WINED3DFMT_R8G8B8X8_UNORM, 8, 8, 8, 0, 0, 8, 16, 0, 4, 0, 0},
97 {WINED3DFMT_R16G16_UNORM, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
98 {WINED3DFMT_B10G10R10A2_UNORM, 10, 10, 10, 2, 20, 10, 0, 30, 4, 0, 0},
99 {WINED3DFMT_R16G16B16A16_UNORM, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
100 /* Luminance */
101 {WINED3DFMT_L8_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
102 {WINED3DFMT_L8A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 8, 2, 0, 0},
103 {WINED3DFMT_L4A4_UNORM, 0, 0, 0, 4, 0, 0, 0, 4, 1, 0, 0},
104 {WINED3DFMT_L16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
105 /* Bump mapping stuff */
106 {WINED3DFMT_R8G8_SNORM, 8, 8, 0, 0, 0, 8, 0, 0, 2, 0, 0},
107 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 5, 5, 0, 0, 0, 5, 0, 0, 2, 0, 0},
108 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 8, 8, 0, 0, 0, 8, 0, 0, 4, 0, 0},
109 {WINED3DFMT_R8G8B8A8_SNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
110 {WINED3DFMT_R16G16_SNORM, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
111 {WINED3DFMT_R10G11B11_SNORM, 10, 11, 11, 0, 0, 10, 21, 0, 4, 0, 0},
112 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
113 /* Depth stencil formats */
114 {WINED3DFMT_D16_LOCKABLE, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0},
115 {WINED3DFMT_D32_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0},
116 {WINED3DFMT_S1_UINT_D15_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 15, 1},
117 {WINED3DFMT_D24_UNORM_S8_UINT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
118 {WINED3DFMT_X8D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 0},
119 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 4},
120 {WINED3DFMT_D16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0},
121 {WINED3DFMT_D32_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0},
122 {WINED3DFMT_S8_UINT_D24_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
123 {WINED3DFMT_VERTEXDATA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
124 {WINED3DFMT_R16_UINT, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
125 {WINED3DFMT_R32_UINT, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
126 {WINED3DFMT_R32G32_UINT, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0},
127 {WINED3DFMT_R32G32B32_UINT, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0},
128 {WINED3DFMT_R32G32B32A32_UINT, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0},
129 {WINED3DFMT_R16G16B16A16_SNORM, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
130 /* Vendor-specific formats */
131 {WINED3DFMT_ATI2N, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
132 {WINED3DFMT_NVDB, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
133 {WINED3DFMT_INST, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
134 {WINED3DFMT_INTZ, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
135 {WINED3DFMT_RESZ, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
136 {WINED3DFMT_NVHU, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
137 {WINED3DFMT_NVHS, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
138 {WINED3DFMT_NULL, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
139 /* Unsure about them, could not find a Windows driver that supports them */
140 {WINED3DFMT_R16, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
141 {WINED3DFMT_AL16, 0, 0, 0, 16, 0, 0, 0, 16, 4, 0, 0},
142 /* Typeless */
143 {WINED3DFMT_R8_TYPELESS, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
144 {WINED3DFMT_R8G8_TYPELESS, 8, 8, 0, 0, 0, 8, 0, 0, 2, 0, 0},
145 {WINED3DFMT_R8G8B8A8_TYPELESS, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
146 {WINED3DFMT_R16_TYPELESS, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
147 {WINED3DFMT_R16G16_TYPELESS, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
148 {WINED3DFMT_R16G16B16A16_TYPELESS, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
149 {WINED3DFMT_R32_TYPELESS, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
150 {WINED3DFMT_R32G32_TYPELESS, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0},
151 {WINED3DFMT_R32G32B32_TYPELESS, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0},
152 {WINED3DFMT_R32G32B32A32_TYPELESS, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0},
153 };
154
155 struct wined3d_format_base_flags
156 {
157 enum wined3d_format_id id;
158 DWORD flags;
159 };
160
161 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
162 * still needs to use the correct block based calculation for e.g. the
163 * resource size. */
164 static const struct wined3d_format_base_flags format_base_flags[] =
165 {
166 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
171 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
172 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
173 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
174 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
175 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
176 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
177 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_BROKEN_PITCH},
178 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
179 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
181 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
182 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
184 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
185 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
186 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
187 };
188
189 struct wined3d_format_block_info
190 {
191 enum wined3d_format_id id;
192 UINT block_width;
193 UINT block_height;
194 UINT block_byte_count;
195 BOOL verify;
196 };
197
198 static const struct wined3d_format_block_info format_block_info[] =
199 {
200 {WINED3DFMT_DXT1, 4, 4, 8, TRUE},
201 {WINED3DFMT_DXT2, 4, 4, 16, TRUE},
202 {WINED3DFMT_DXT3, 4, 4, 16, TRUE},
203 {WINED3DFMT_DXT4, 4, 4, 16, TRUE},
204 {WINED3DFMT_DXT5, 4, 4, 16, TRUE},
205 {WINED3DFMT_ATI2N, 4, 4, 16, FALSE},
206 {WINED3DFMT_YUY2, 2, 1, 4, FALSE},
207 {WINED3DFMT_UYVY, 2, 1, 4, FALSE},
208 };
209
210 struct wined3d_format_vertex_info
211 {
212 enum wined3d_format_id id;
213 enum wined3d_ffp_emit_idx emit_idx;
214 GLint component_count;
215 GLenum gl_vtx_type;
216 GLint gl_vtx_format;
217 GLboolean gl_normalized;
218 unsigned int component_size;
219 };
220
221 static const struct wined3d_format_vertex_info format_vertex_info[] =
222 {
223 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
224 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
225 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
226 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
227 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
228 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
229 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
230 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
231 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
232 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
233 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
234 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
235 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
236 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
237 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
238 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
239 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)},
240 {WINED3DFMT_R32_UINT, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_INT, 1, GL_FALSE, sizeof(UINT)},
241 {WINED3DFMT_R32G32_UINT, WINED3D_FFP_EMIT_INVALID, 2, GL_UNSIGNED_INT, 2, GL_FALSE, sizeof(UINT)},
242 {WINED3DFMT_R32G32B32_UINT, WINED3D_FFP_EMIT_INVALID, 3, GL_UNSIGNED_INT, 3, GL_FALSE, sizeof(UINT)},
243 {WINED3DFMT_R32G32B32A32_UINT, WINED3D_FFP_EMIT_INVALID, 4, GL_UNSIGNED_INT, 4, GL_FALSE, sizeof(UINT)},
244 };
245
246 struct wined3d_format_texture_info
247 {
248 enum wined3d_format_id id;
249 GLint gl_internal;
250 GLint gl_srgb_internal;
251 GLint gl_rt_internal;
252 GLint gl_format;
253 GLint gl_type;
254 unsigned int conv_byte_count;
255 unsigned int flags;
256 enum wined3d_gl_extension extension;
257 void (*convert)(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
258 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth);
259 };
260
261 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
262 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
263 {
264 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
265 * format+type combination to load it. Thus convert it to A8L8, then load it
266 * with A4L4 internal, but A8L8 format+type
267 */
268 unsigned int x, y, z;
269 const unsigned char *Source;
270 unsigned char *Dest;
271
272 for (z = 0; z < depth; z++)
273 {
274 for (y = 0; y < height; y++)
275 {
276 Source = src + z * src_slice_pitch + y * src_row_pitch;
277 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
278 for (x = 0; x < width; x++ )
279 {
280 unsigned char color = (*Source++);
281 /* A */ Dest[1] = (color & 0xf0) << 0;
282 /* L */ Dest[0] = (color & 0x0f) << 4;
283 Dest += 2;
284 }
285 }
286 }
287 }
288
289 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
290 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
291 {
292 unsigned int x, y, z;
293 const WORD *Source;
294
295 for (z = 0; z < depth; z++)
296 {
297 for (y = 0; y < height; y++)
298 {
299 unsigned short *Dest_s = (unsigned short *) (dst + z * dst_slice_pitch + y * dst_row_pitch);
300 Source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch);
301 for (x = 0; x < width; x++ )
302 {
303 short color = (*Source++);
304 unsigned char l = ((color >> 10) & 0xfc);
305 short v = ((color >> 5) & 0x3e);
306 short u = ((color ) & 0x1f);
307 short v_conv = v + 16;
308 short u_conv = u + 16;
309
310 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
311 Dest_s += 1;
312 }
313 }
314 }
315 }
316
317 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
318 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
319 {
320 unsigned int x, y, z;
321 const WORD *Source;
322 unsigned char *Dest;
323
324 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
325 * fixed function and shaders without further conversion once the surface is
326 * loaded
327 */
328 for (z = 0; z < depth; z++)
329 {
330 for (y = 0; y < height; y++)
331 {
332 Source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch);
333 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
334 for (x = 0; x < width; x++ )
335 {
336 short color = (*Source++);
337 unsigned char l = ((color >> 10) & 0xfc);
338 char v = ((color >> 5) & 0x3e);
339 char u = ((color ) & 0x1f);
340
341 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
342 * and doubles the positive range. Thus shift left only once, gl does the 2nd
343 * shift. GL reads a signed value and converts it into an unsigned value.
344 */
345 /* M */ Dest[2] = l << 1;
346
347 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
348 * from 5 bit values to 8 bit values.
349 */
350 /* V */ Dest[1] = v << 3;
351 /* U */ Dest[0] = u << 3;
352 Dest += 3;
353 }
354 }
355 }
356 }
357
358 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
359 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
360 {
361 unsigned int x, y, z;
362 const short *Source;
363 unsigned char *Dest;
364
365 for (z = 0; z < depth; z++)
366 {
367 for (y = 0; y < height; y++)
368 {
369 Source = (const short *)(src + z * src_slice_pitch + y * src_row_pitch);
370 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
371 for (x = 0; x < width; x++ )
372 {
373 const short color = (*Source++);
374 /* B */ Dest[0] = 0xff;
375 /* G */ Dest[1] = (color >> 8) + 128; /* V */
376 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
377 Dest += 3;
378 }
379 }
380 }
381 }
382
383 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
384 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
385 {
386 unsigned int x, y, z;
387 const DWORD *Source;
388 unsigned char *Dest;
389
390 /* Doesn't work correctly with the fixed function pipeline, but can work in
391 * shaders if the shader is adjusted. (There's no use for this format in gl's
392 * standard fixed function pipeline anyway).
393 */
394 for (z = 0; z < depth; z++)
395 {
396 for (y = 0; y < height; y++)
397 {
398 Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
399 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
400 for (x = 0; x < width; x++ )
401 {
402 LONG color = (*Source++);
403 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
404 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
405 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
406 Dest += 4;
407 }
408 }
409 }
410 }
411
412 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
413 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
414 {
415 unsigned int x, y, z;
416 const DWORD *Source;
417 unsigned char *Dest;
418
419 /* This implementation works with the fixed function pipeline and shaders
420 * without further modification after converting the surface.
421 */
422 for (z = 0; z < depth; z++)
423 {
424 for (y = 0; y < height; y++)
425 {
426 Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
427 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
428 for (x = 0; x < width; x++ )
429 {
430 LONG color = (*Source++);
431 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
432 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
433 /* U */ Dest[0] = (color & 0xff); /* U */
434 /* I */ Dest[3] = 255; /* X */
435 Dest += 4;
436 }
437 }
438 }
439 }
440
441 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
442 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
443 {
444 unsigned int x, y, z;
445 const DWORD *Source;
446 unsigned char *Dest;
447
448 for (z = 0; z < depth; z++)
449 {
450 for (y = 0; y < height; y++)
451 {
452 Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
453 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
454 for (x = 0; x < width; x++ )
455 {
456 LONG color = (*Source++);
457 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
458 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
459 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
460 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
461 Dest += 4;
462 }
463 }
464 }
465 }
466
467 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
468 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
469 {
470 unsigned int x, y, z;
471 const DWORD *Source;
472 unsigned short *Dest;
473
474 for (z = 0; z < depth; z++)
475 {
476 for (y = 0; y < height; y++)
477 {
478 Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
479 Dest = (unsigned short *) (dst + z * dst_slice_pitch + y * dst_row_pitch);
480 for (x = 0; x < width; x++ )
481 {
482 const DWORD color = (*Source++);
483 /* B */ Dest[0] = 0xffff;
484 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
485 /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */
486 Dest += 3;
487 }
488 }
489 }
490 }
491
492 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
493 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
494 {
495 unsigned int x, y, z;
496 const WORD *Source;
497 WORD *Dest;
498
499 for (z = 0; z < depth; z++)
500 {
501 for (y = 0; y < height; y++)
502 {
503 Source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch);
504 Dest = (WORD *) (dst + z * dst_slice_pitch + y * dst_row_pitch);
505 for (x = 0; x < width; x++ )
506 {
507 WORD green = (*Source++);
508 WORD red = (*Source++);
509 Dest[0] = green;
510 Dest[1] = red;
511 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
512 * shader overwrites it anyway */
513 Dest[2] = 0xffff;
514 Dest += 3;
515 }
516 }
517 }
518 }
519
520 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
521 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
522 {
523 unsigned int x, y, z;
524 const float *Source;
525 float *Dest;
526
527 for (z = 0; z < depth; z++)
528 {
529 for (y = 0; y < height; y++)
530 {
531 Source = (const float *)(src + z * src_slice_pitch + y * src_row_pitch);
532 Dest = (float *) (dst + z * dst_slice_pitch + y * dst_row_pitch);
533 for (x = 0; x < width; x++ )
534 {
535 float green = (*Source++);
536 float red = (*Source++);
537 Dest[0] = green;
538 Dest[1] = red;
539 Dest[2] = 1.0f;
540 Dest += 3;
541 }
542 }
543 }
544 }
545
546 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
547 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
548 {
549 unsigned int x, y, z;
550
551 for (z = 0; z < depth; z++)
552 {
553 for (y = 0; y < height; ++y)
554 {
555 const WORD *source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch);
556 DWORD *dest = (DWORD *)(dst + z * dst_slice_pitch + y * dst_row_pitch);
557
558 for (x = 0; x < width; ++x)
559 {
560 /* The depth data is normalized, so needs to be scaled,
561 * the stencil data isn't. Scale depth data by
562 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
563 WORD d15 = source[x] >> 1;
564 DWORD d24 = (d15 << 9) + (d15 >> 6);
565 dest[x] = (d24 << 8) | (source[x] & 0x1);
566 }
567 }
568 }
569 }
570
571 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
572 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
573 {
574 unsigned int x, y, z;
575
576 for (z = 0; z < depth; z++)
577 {
578 for (y = 0; y < height; ++y)
579 {
580 const DWORD *source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
581 DWORD *dest = (DWORD *)(dst + z * dst_slice_pitch + y * dst_row_pitch);
582
583 for (x = 0; x < width; ++x)
584 {
585 /* Just need to clear out the X4 part. */
586 dest[x] = source[x] & ~0xf0;
587 }
588 }
589 }
590 }
591
592 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
593 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
594 {
595 unsigned int x, y, z;
596
597 for (z = 0; z < depth; z++)
598 {
599 for (y = 0; y < height; ++y)
600 {
601 const DWORD *source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
602 float *dest_f = (float *)(dst + z * dst_slice_pitch + y * dst_row_pitch);
603 DWORD *dest_s = (DWORD *)dest_f;
604
605 for (x = 0; x < width; ++x)
606 {
607 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
608 dest_s[x * 2 + 1] = source[x] & 0xff;
609 }
610 }
611 }
612 }
613
614 /* The following formats explicitly don't have WINED3DFMT_FLAG_TEXTURE set:
615 *
616 * These are never supported on native.
617 * WINED3DFMT_B8G8R8_UNORM
618 * WINED3DFMT_B2G3R3_UNORM
619 * WINED3DFMT_L4A4_UNORM
620 * WINED3DFMT_S1_UINT_D15_UNORM
621 * WINED3DFMT_S4X4_UINT_D24_UNORM
622 *
623 * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of ddraw.
624 * Since it is not widely available, don't offer it. Further no Windows driver
625 * offers WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either.
626 * WINED3DFMT_P8_UINT
627 * WINED3DFMT_P8_UINT_A8_UNORM
628 *
629 * These formats seem to be similar to the HILO formats in
630 * GL_NV_texture_shader. NVHU is said to be GL_UNSIGNED_HILO16,
631 * NVHS GL_SIGNED_HILO16. Rumours say that D3D computes a 3rd channel
632 * similarly to D3DFMT_CxV8U8 (So NVHS could be called D3DFMT_CxV16U16). ATI
633 * refused to support formats which can easily be emulated with pixel shaders,
634 * so applications have to deal with not having NVHS and NVHU.
635 * WINED3DFMT_NVHU
636 * WINED3DFMT_NVHS */
637 static const struct wined3d_format_texture_info format_texture_info[] =
638 {
639 /* format id gl_internal gl_srgb_internal gl_rt_internal
640 gl_format gl_type conv_byte_count
641 flags
642 extension convert */
643 /* FourCC formats */
644 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
645 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
646 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
647 * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
648 * endian machine
649 */
650 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
651 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
652 WINED3DFMT_FLAG_FILTERING,
653 WINED3D_GL_EXT_NONE, NULL},
654 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
655 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 0,
656 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
657 APPLE_YCBCR_422, NULL},
658 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
659 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
660 WINED3DFMT_FLAG_FILTERING,
661 WINED3D_GL_EXT_NONE, NULL},
662 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
663 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, 0,
664 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
665 APPLE_YCBCR_422, NULL},
666 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
667 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
668 WINED3DFMT_FLAG_FILTERING,
669 WINED3D_GL_EXT_NONE, NULL},
670 {WINED3DFMT_NV12, GL_ALPHA, GL_ALPHA, 0,
671 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
672 WINED3DFMT_FLAG_FILTERING,
673 WINED3D_GL_EXT_NONE, NULL},
674 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
675 GL_RGBA, GL_UNSIGNED_BYTE, 0,
676 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
677 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
678 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
679 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
680 GL_RGBA, GL_UNSIGNED_BYTE, 0,
681 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
682 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
683 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
684 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
685 GL_RGBA, GL_UNSIGNED_BYTE, 0,
686 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
687 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
688 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
689 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
690 GL_RGBA, GL_UNSIGNED_BYTE, 0,
691 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
692 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
693 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
694 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
695 GL_RGBA, GL_UNSIGNED_BYTE, 0,
696 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
697 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
698 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
699 /* IEEE formats */
700 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
701 GL_RED, GL_FLOAT, 0,
702 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
703 ARB_TEXTURE_FLOAT, NULL},
704 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
705 GL_RED, GL_FLOAT, 0,
706 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
707 ARB_TEXTURE_RG, NULL},
708 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
709 GL_RGB, GL_FLOAT, 12,
710 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
711 ARB_TEXTURE_FLOAT, convert_r32g32_float},
712 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
713 GL_RG, GL_FLOAT, 0,
714 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
715 ARB_TEXTURE_RG, NULL},
716 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
717 GL_RGBA, GL_FLOAT, 0,
718 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
719 ARB_TEXTURE_FLOAT, NULL},
720 /* Float */
721 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
722 GL_RED, GL_HALF_FLOAT_ARB, 0,
723 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
724 ARB_TEXTURE_FLOAT, NULL},
725 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
726 GL_RED, GL_HALF_FLOAT_ARB, 0,
727 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
728 ARB_TEXTURE_RG, NULL},
729 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
730 GL_RGB, GL_HALF_FLOAT_ARB, 6,
731 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
732 ARB_TEXTURE_FLOAT, convert_r16g16},
733 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
734 GL_RG, GL_HALF_FLOAT_ARB, 0,
735 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
736 ARB_TEXTURE_RG, NULL},
737 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
738 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
739 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET
740 | WINED3DFMT_FLAG_VTF,
741 ARB_TEXTURE_FLOAT, NULL},
742 /* Palettized formats */
743 {WINED3DFMT_P8_UINT, GL_ALPHA8, GL_ALPHA8, 0,
744 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
745 0,
746 0, NULL},
747 /* Standard ARGB formats */
748 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
749 GL_BGR, GL_UNSIGNED_BYTE, 0,
750 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
751 WINED3D_GL_EXT_NONE, NULL},
752 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_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 | WINED3DFMT_FLAG_VTF,
757 WINED3D_GL_EXT_NONE, NULL},
758 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
759 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
760 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
761 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
762 WINED3D_GL_EXT_NONE, NULL},
763 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
764 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
765 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
766 | WINED3DFMT_FLAG_RENDERTARGET,
767 WINED3D_GL_EXT_NONE, NULL},
768 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
769 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
770 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
771 WINED3D_GL_EXT_NONE, NULL},
772 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
773 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
774 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
775 WINED3D_GL_EXT_NONE, NULL},
776 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
777 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
778 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
779 | WINED3DFMT_FLAG_SRGB_READ,
780 WINED3D_GL_EXT_NONE, NULL},
781 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
782 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
783 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
784 WINED3D_GL_EXT_NONE, NULL},
785 {WINED3DFMT_R8_UNORM, GL_R8, GL_R8, 0,
786 GL_RED, GL_UNSIGNED_BYTE, 0,
787 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
788 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
789 ARB_TEXTURE_RG, NULL},
790 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
791 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
792 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
793 WINED3D_GL_EXT_NONE, NULL},
794 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
795 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
796 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
797 WINED3D_GL_EXT_NONE, NULL},
798 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
799 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
800 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
801 | WINED3DFMT_FLAG_RENDERTARGET,
802 WINED3D_GL_EXT_NONE, NULL},
803 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
804 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
805 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
806 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE
807 | WINED3DFMT_FLAG_VTF,
808 WINED3D_GL_EXT_NONE, NULL},
809 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
810 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
811 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
812 WINED3D_GL_EXT_NONE, NULL},
813 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
814 GL_RGB, GL_UNSIGNED_SHORT, 6,
815 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
816 WINED3D_GL_EXT_NONE, convert_r16g16},
817 {WINED3DFMT_R16G16_UNORM, GL_RG16, GL_RG16, 0,
818 GL_RG, GL_UNSIGNED_SHORT, 0,
819 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
820 | WINED3DFMT_FLAG_RENDERTARGET,
821 ARB_TEXTURE_RG, NULL},
822 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
823 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
824 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
825 | WINED3DFMT_FLAG_RENDERTARGET,
826 WINED3D_GL_EXT_NONE, NULL},
827 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
828 GL_RGBA, GL_UNSIGNED_SHORT, 0,
829 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
830 | WINED3DFMT_FLAG_RENDERTARGET,
831 WINED3D_GL_EXT_NONE, NULL},
832 /* Luminance */
833 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
834 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
835 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
836 | WINED3DFMT_FLAG_SRGB_READ,
837 WINED3D_GL_EXT_NONE, NULL},
838 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
839 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
840 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
841 | WINED3DFMT_FLAG_SRGB_READ,
842 WINED3D_GL_EXT_NONE, NULL},
843 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
844 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
845 WINED3DFMT_FLAG_FILTERING,
846 WINED3D_GL_EXT_NONE, convert_l4a4_unorm},
847 /* Bump mapping stuff */
848 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
849 GL_BGR, GL_UNSIGNED_BYTE, 3,
850 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
851 | WINED3DFMT_FLAG_BUMPMAP,
852 WINED3D_GL_EXT_NONE, convert_r8g8_snorm},
853 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
854 GL_DSDT_NV, GL_BYTE, 0,
855 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
856 | WINED3DFMT_FLAG_BUMPMAP,
857 NV_TEXTURE_SHADER, NULL},
858 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
859 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
860 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
861 | WINED3DFMT_FLAG_BUMPMAP,
862 WINED3D_GL_EXT_NONE, convert_r5g5_snorm_l6_unorm},
863 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
864 GL_DSDT_MAG_NV, GL_BYTE, 3,
865 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
866 | WINED3DFMT_FLAG_BUMPMAP,
867 NV_TEXTURE_SHADER, convert_r5g5_snorm_l6_unorm_nv},
868 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
869 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
870 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
871 | WINED3DFMT_FLAG_BUMPMAP,
872 WINED3D_GL_EXT_NONE, convert_r8g8_snorm_l8x8_unorm},
873 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
874 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
875 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
876 | WINED3DFMT_FLAG_BUMPMAP,
877 NV_TEXTURE_SHADER, convert_r8g8_snorm_l8x8_unorm_nv},
878 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
879 GL_BGRA, GL_UNSIGNED_BYTE, 4,
880 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
881 | WINED3DFMT_FLAG_BUMPMAP,
882 WINED3D_GL_EXT_NONE, convert_r8g8b8a8_snorm},
883 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
884 GL_RGBA, GL_BYTE, 0,
885 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
886 | WINED3DFMT_FLAG_BUMPMAP,
887 NV_TEXTURE_SHADER, NULL},
888 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
889 GL_BGR, GL_UNSIGNED_SHORT, 6,
890 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
891 | WINED3DFMT_FLAG_BUMPMAP,
892 WINED3D_GL_EXT_NONE, convert_r16g16_snorm},
893 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
894 GL_HILO_NV, GL_SHORT, 0,
895 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
896 | WINED3DFMT_FLAG_BUMPMAP,
897 NV_TEXTURE_SHADER, NULL},
898 /* Depth stencil formats */
899 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0,
900 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
901 WINED3DFMT_FLAG_DEPTH,
902 WINED3D_GL_EXT_NONE, NULL},
903 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
904 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
905 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
906 ARB_DEPTH_TEXTURE, NULL},
907 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0,
908 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
909 WINED3DFMT_FLAG_DEPTH,
910 WINED3D_GL_EXT_NONE, NULL},
911 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
912 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
913 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
914 ARB_DEPTH_TEXTURE, NULL},
915 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
916 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
917 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
918 ARB_DEPTH_TEXTURE, NULL},
919 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
920 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
921 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
922 EXT_PACKED_DEPTH_STENCIL, convert_s1_uint_d15_unorm},
923 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
924 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
925 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
926 ARB_FRAMEBUFFER_OBJECT, convert_s1_uint_d15_unorm},
927 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
928 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
929 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
930 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
931 ARB_DEPTH_TEXTURE, NULL},
932 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
933 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
934 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
935 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
936 EXT_PACKED_DEPTH_STENCIL, NULL},
937 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
938 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
939 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
940 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
941 ARB_FRAMEBUFFER_OBJECT, NULL},
942 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0,
943 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
944 WINED3DFMT_FLAG_DEPTH,
945 WINED3D_GL_EXT_NONE, NULL},
946 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
947 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
948 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
949 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
950 ARB_DEPTH_TEXTURE, NULL},
951 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
952 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
953 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
954 ARB_DEPTH_TEXTURE, NULL},
955 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
956 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
957 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
958 EXT_PACKED_DEPTH_STENCIL, convert_s4x4_uint_d24_unorm},
959 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
960 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
961 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
962 ARB_FRAMEBUFFER_OBJECT, convert_s4x4_uint_d24_unorm},
963 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0,
964 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
965 WINED3DFMT_FLAG_DEPTH,
966 WINED3D_GL_EXT_NONE, NULL},
967 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
968 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
969 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
970 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
971 ARB_DEPTH_TEXTURE, NULL},
972 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
973 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
974 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
975 WINED3D_GL_EXT_NONE, NULL},
976 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
977 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
978 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
979 ARB_DEPTH_BUFFER_FLOAT, NULL},
980 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
981 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
982 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
983 ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float},
984 /* Vendor-specific formats */
985 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
986 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
987 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
988 | WINED3DFMT_FLAG_COMPRESSED,
989 ATI_TEXTURE_COMPRESSION_3DC, NULL},
990 {WINED3DFMT_ATI2N, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0,
991 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
992 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
993 | WINED3DFMT_FLAG_COMPRESSED,
994 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
995 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
996 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
997 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
998 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
999 EXT_PACKED_DEPTH_STENCIL, NULL},
1000 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
1001 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
1002 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1003 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
1004 ARB_FRAMEBUFFER_OBJECT, NULL},
1005 {WINED3DFMT_NULL, 0, 0, 0,
1006 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
1007 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET,
1008 ARB_FRAMEBUFFER_OBJECT, NULL},
1009 };
1010
1011 static inline int getFmtIdx(enum wined3d_format_id format_id)
1012 {
1013 /* First check if the format is at the position of its value.
1014 * This will catch the argb formats before the loop is entered. */
1015 if (format_id < (sizeof(formats) / sizeof(*formats))
1016 && formats[format_id].id == format_id)
1017 {
1018 return format_id;
1019 }
1020 else
1021 {
1022 unsigned int i;
1023
1024 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
1025 {
1026 if (formats[i].id == format_id) return i;
1027 }
1028 }
1029 return -1;
1030 }
1031
1032 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
1033 {
1034 UINT format_count = sizeof(formats) / sizeof(*formats);
1035 UINT i;
1036
1037 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
1038 if (!gl_info->formats)
1039 {
1040 ERR("Failed to allocate memory.\n");
1041 return FALSE;
1042 }
1043
1044 for (i = 0; i < format_count; ++i)
1045 {
1046 struct wined3d_format *format = &gl_info->formats[i];
1047 format->id = formats[i].id;
1048 format->red_size = formats[i].red_size;
1049 format->green_size = formats[i].green_size;
1050 format->blue_size = formats[i].blue_size;
1051 format->alpha_size = formats[i].alpha_size;
1052 format->red_offset = formats[i].red_offset;
1053 format->green_offset = formats[i].green_offset;
1054 format->blue_offset = formats[i].blue_offset;
1055 format->alpha_offset = formats[i].alpha_offset;
1056 format->byte_count = formats[i].bpp;
1057 format->depth_size = formats[i].depth_size;
1058 format->stencil_size = formats[i].stencil_size;
1059 format->block_width = 1;
1060 format->block_height = 1;
1061 format->block_byte_count = formats[i].bpp;
1062 }
1063
1064 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
1065 {
1066 int fmt_idx = getFmtIdx(format_base_flags[i].id);
1067
1068 if (fmt_idx == -1)
1069 {
1070 ERR("Format %s (%#x) not found.\n",
1071 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
1072 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1073 return FALSE;
1074 }
1075
1076 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
1077 }
1078
1079 return TRUE;
1080 }
1081
1082 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
1083 {
1084 unsigned int i;
1085
1086 for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i)
1087 {
1088 struct wined3d_format *format;
1089 int fmt_idx = getFmtIdx(format_block_info[i].id);
1090
1091 if (fmt_idx == -1)
1092 {
1093 ERR("Format %s (%#x) not found.\n",
1094 debug_d3dformat(format_block_info[i].id), format_block_info[i].id);
1095 return FALSE;
1096 }
1097
1098 format = &gl_info->formats[fmt_idx];
1099 format->block_width = format_block_info[i].block_width;
1100 format->block_height = format_block_info[i].block_height;
1101 format->block_byte_count = format_block_info[i].block_byte_count;
1102 format->flags |= WINED3DFMT_FLAG_BLOCKS;
1103 if (!format_block_info[i].verify)
1104 format->flags |= WINED3DFMT_FLAG_BLOCKS_NO_VERIFY;
1105 }
1106
1107 return TRUE;
1108 }
1109
1110 /* Context activation is done by the caller. */
1111 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
1112 {
1113 /* Check if the default internal format is supported as a frame buffer
1114 * target, otherwise fall back to the render target internal.
1115 *
1116 * Try to stick to the standard format if possible, this limits precision differences. */
1117 GLenum status;
1118 GLuint tex;
1119
1120 while (gl_info->gl_ops.gl.p_glGetError());
1121 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1122
1123 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1124 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1125
1126 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0,
1127 format->glFormat, format->glType, NULL);
1128 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1129 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1130
1131 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1132
1133 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1134 checkGLcall("Framebuffer format check");
1135
1136 if (status == GL_FRAMEBUFFER_COMPLETE)
1137 {
1138 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1139 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1140 format->rtInternal = format->glInternal;
1141 }
1142 else
1143 {
1144 if (!format->rtInternal)
1145 {
1146 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1147 {
1148 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1149 " and no fallback specified.\n", debug_d3dformat(format->id));
1150 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1151 }
1152 else
1153 {
1154 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1155 }
1156 format->rtInternal = format->glInternal;
1157 }
1158 else
1159 {
1160 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1161 debug_d3dformat(format->id));
1162
1163 while (gl_info->gl_ops.gl.p_glGetError());
1164
1165 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1166
1167 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0,
1168 format->glFormat, format->glType, NULL);
1169 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1170 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1171
1172 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1173
1174 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1175 checkGLcall("Framebuffer format check");
1176
1177 if (status == GL_FRAMEBUFFER_COMPLETE)
1178 {
1179 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1180 debug_d3dformat(format->id));
1181 }
1182 else
1183 {
1184 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1185 debug_d3dformat(format->id));
1186 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1187 }
1188 }
1189 }
1190
1191 if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1192 || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1193 && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
1194 && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA
1195 && (format->red_size || format->alpha_size))
1196 {
1197 DWORD readback[16 * 16], color, r_range, a_range;
1198 BYTE r, a;
1199 BOOL match = TRUE;
1200 GLuint rb;
1201
1202 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1203 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1204 {
1205 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1206 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1207 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1208 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1209 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1210 checkGLcall("RB attachment");
1211 }
1212
1213 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1214 gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1215 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1216 if (gl_info->gl_ops.gl.p_glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1217 {
1218 while (gl_info->gl_ops.gl.p_glGetError());
1219 TRACE("Format doesn't support post-pixelshader blending.\n");
1220 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1221 }
1222 else
1223 {
1224 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1225 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16);
1226 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1227 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1228 gl_info->gl_ops.gl.p_glLoadIdentity();
1229 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1230 gl_info->gl_ops.gl.p_glLoadIdentity();
1231
1232 gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1233
1234 /* Draw a full-black quad */
1235 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1236 gl_info->gl_ops.gl.p_glColor4f(0.0f, 0.0f, 0.0f, 1.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_glVertex3f(-1.0f, 1.0f, 0.0f);
1240 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1241 gl_info->gl_ops.gl.p_glEnd();
1242
1243 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1244 /* Draw a half-transparent red quad */
1245 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1246 gl_info->gl_ops.gl.p_glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
1247 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1248 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1249 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1250 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1251 gl_info->gl_ops.gl.p_glEnd();
1252
1253 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1254
1255 /* Rebinding texture to workaround a fglrx bug. */
1256 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1257 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1258 checkGLcall("Post-pixelshader blending check");
1259
1260 color = readback[7 * 16 + 7];
1261 a = color >> 24;
1262 r = (color & 0x00ff0000) >> 16;
1263
1264 r_range = format->red_size < 8 ? 1 << (8 - format->red_size) : 1;
1265 a_range = format->alpha_size < 8 ? 1 << (8 - format->alpha_size) : 1;
1266 if (format->red_size && (r < 0x7f - r_range || r > 0x7f + r_range))
1267 match = FALSE;
1268 else if (format->alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range))
1269 match = FALSE;
1270 if (!match)
1271 {
1272 TRACE("Format doesn't support post-pixelshader blending.\n");
1273 TRACE("Color output: %#x\n", color);
1274 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1275 }
1276 else
1277 {
1278 TRACE("Format supports post-pixelshader blending.\n");
1279 TRACE("Color output: %#x\n", color);
1280 format->flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1281 }
1282 }
1283
1284 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1285 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1286 {
1287 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1288 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1289 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1290 checkGLcall("RB cleanup");
1291 }
1292 }
1293
1294 if (format->glInternal != format->glGammaInternal)
1295 {
1296 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0,
1297 format->glFormat, format->glType, NULL);
1298 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1299
1300 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1301 checkGLcall("Framebuffer format check");
1302
1303 if (status == GL_FRAMEBUFFER_COMPLETE)
1304 {
1305 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1306 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1307 }
1308 else
1309 {
1310 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1311 }
1312 }
1313 else if (status == GL_FRAMEBUFFER_COMPLETE)
1314 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1315
1316 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1317 }
1318
1319 static void query_format_flag(struct wined3d_gl_info *gl_info, struct wined3d_format *format,
1320 GLint internal, GLenum pname, DWORD flag, const char *string)
1321 {
1322 GLint value;
1323
1324 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, internal, pname, 1, &value);
1325 if (value == GL_FULL_SUPPORT)
1326 {
1327 TRACE("Format %s supports %s.\n", debug_d3dformat(format->id), string);
1328 format->flags |= flag;
1329 }
1330 else
1331 {
1332 TRACE("Format %s doesn't support %s.\n", debug_d3dformat(format->id), string);
1333 format->flags &= ~flag;
1334 }
1335 }
1336
1337 /* Context activation is done by the caller. */
1338 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1339 {
1340 unsigned int i;
1341 GLuint fbo;
1342
1343 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
1344 {
1345 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1346 {
1347 GLint value;
1348 struct wined3d_format *format = &gl_info->formats[i];
1349
1350 if (!format->glInternal)
1351 continue;
1352 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1353 continue;
1354
1355 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->glInternal,
1356 GL_FRAMEBUFFER_RENDERABLE, 1, &value);
1357 if (value == GL_FULL_SUPPORT)
1358 {
1359 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1360 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1361 format->rtInternal = format->glInternal;
1362
1363 query_format_flag(gl_info, format, format->glInternal, GL_FRAMEBUFFER_BLEND,
1364 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING, "post-pixelshader blending");
1365 }
1366 else
1367 {
1368 if (!format->rtInternal)
1369 {
1370 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1371 {
1372 WARN("Format %s with rendertarget flag is not supported as FBO color attachment"
1373 " and no fallback specified.\n", debug_d3dformat(format->id));
1374 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1375 }
1376 else
1377 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1378 format->rtInternal = format->glInternal;
1379 }
1380 else
1381 {
1382 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->rtInternal,
1383 GL_FRAMEBUFFER_RENDERABLE, 1, &value);
1384 if (value == GL_FULL_SUPPORT)
1385 {
1386 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1387 debug_d3dformat(format->id));
1388 }
1389 else
1390 {
1391 WARN("Format %s rtInternal format is not supported as FBO color attachment.\n",
1392 debug_d3dformat(format->id));
1393 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1394 }
1395 }
1396 }
1397
1398 if (format->glInternal != format->glGammaInternal)
1399 {
1400 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->glGammaInternal,
1401 GL_FRAMEBUFFER_RENDERABLE, 1, &value);
1402 if (value == GL_FULL_SUPPORT)
1403 {
1404 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1405 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1406 }
1407 else
1408 {
1409 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1410 }
1411 }
1412 else if (format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)
1413 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1414 }
1415 return;
1416 }
1417
1418 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1419 {
1420 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1421 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1422 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1423 gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0);
1424 }
1425
1426 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1427 {
1428 struct wined3d_format *format = &gl_info->formats[i];
1429
1430 if (!format->glInternal) continue;
1431
1432 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1433 {
1434 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1435 debug_d3dformat(format->id));
1436 continue;
1437 }
1438
1439 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1440 {
1441 TRACE("Skipping format %s because it's a compressed format.\n",
1442 debug_d3dformat(format->id));
1443 continue;
1444 }
1445
1446 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1447 {
1448 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1449 check_fbo_compat(gl_info, format);
1450 }
1451 else
1452 {
1453 format->rtInternal = format->glInternal;
1454 }
1455 }
1456
1457 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1458 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1459 }
1460
1461 static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1462 {
1463 struct fragment_caps fragment_caps;
1464 struct shader_caps shader_caps;
1465 BOOL srgb_write;
1466 unsigned int i;
1467
1468 adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
1469 adapter->shader_backend->shader_get_caps(gl_info, &shader_caps);
1470 srgb_write = (fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_SRGB_WRITE)
1471 && (shader_caps.wined3d_caps & WINED3D_SHADER_CAP_SRGB_WRITE);
1472
1473 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1474 {
1475 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1476 struct wined3d_format *format;
1477
1478 if (fmt_idx == -1)
1479 {
1480 ERR("Format %s (%#x) not found.\n",
1481 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1482 return FALSE;
1483 }
1484
1485 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1486
1487 format = &gl_info->formats[fmt_idx];
1488
1489 /* ARB_texture_rg defines floating point formats, but only if
1490 * ARB_texture_float is also supported. */
1491 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1492 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1493 continue;
1494
1495 format->glInternal = format_texture_info[i].gl_internal;
1496 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1497 format->rtInternal = format_texture_info[i].gl_rt_internal;
1498 format->glFormat = format_texture_info[i].gl_format;
1499 format->glType = format_texture_info[i].gl_type;
1500 format->color_fixup = COLOR_FIXUP_IDENTITY;
1501 format->flags |= format_texture_info[i].flags;
1502 format->height_scale.numerator = 1;
1503 format->height_scale.denominator = 1;
1504
1505 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
1506 {
1507 query_format_flag(gl_info, format, format->glInternal, GL_VERTEX_TEXTURE,
1508 WINED3DFMT_FLAG_VTF, "vertex texture usage");
1509 query_format_flag(gl_info, format, format->glInternal, GL_FILTER,
1510 WINED3DFMT_FLAG_FILTERING, "filtering");
1511
1512 if (format->glGammaInternal != format->glInternal)
1513 {
1514 query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_READ,
1515 WINED3DFMT_FLAG_SRGB_READ, "sRGB read");
1516
1517 if (srgb_write)
1518 query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_WRITE,
1519 WINED3DFMT_FLAG_SRGB_WRITE, "sRGB write");
1520 else
1521 format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
1522
1523 if (!(format->flags & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE)))
1524 format->glGammaInternal = format->glInternal;
1525 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1526 format->glInternal = format->glGammaInternal;
1527 }
1528 }
1529 else
1530 {
1531 if (!gl_info->limits.vertex_samplers)
1532 format->flags &= ~WINED3DFMT_FLAG_VTF;
1533
1534 if (!(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1535 format->flags |= WINED3DFMT_FLAG_FILTERING;
1536 else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT)
1537 format->flags &= ~WINED3DFMT_FLAG_VTF;
1538
1539 if (format->glGammaInternal != format->glInternal)
1540 {
1541 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1542 if (!gl_info->supported[EXT_TEXTURE_SRGB])
1543 {
1544 format->glGammaInternal = format->glInternal;
1545 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1546 }
1547 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1548 {
1549 format->glInternal = format->glGammaInternal;
1550 }
1551 }
1552
1553 if ((format->flags & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write)
1554 format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
1555 }
1556
1557 /* Texture conversion stuff */
1558 format->convert = format_texture_info[i].convert;
1559 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1560 }
1561
1562 return TRUE;
1563 }
1564
1565 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1566 {
1567 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1568 c1 >>= 8; c2 >>= 8;
1569 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1570 c1 >>= 8; c2 >>= 8;
1571 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1572 c1 >>= 8; c2 >>= 8;
1573 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1574 return TRUE;
1575 }
1576
1577 /* A context is provided by the caller */
1578 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1579 {
1580 static const DWORD data[] = {0x00000000, 0xffffffff};
1581 GLuint tex, fbo, buffer;
1582 DWORD readback[16 * 1];
1583 BOOL ret = FALSE;
1584
1585 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1586 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1587 * falling back to software. If this changes in the future this code will get fooled and
1588 * apps might hit the software path due to incorrectly advertised caps.
1589 *
1590 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1591 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1592 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1593 */
1594
1595 while (gl_info->gl_ops.gl.p_glGetError());
1596
1597 gl_info->gl_ops.gl.p_glGenTextures(1, &buffer);
1598 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1599 memset(readback, 0x7e, sizeof(readback));
1600 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0,
1601 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1602 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1603 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1604 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1605 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1606 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1607
1608 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1609 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1610 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0,
1611 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1612 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1613 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1614 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1615 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1616 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1617 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
1618
1619 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1620 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1621 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1622 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1623
1624 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1);
1625 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1626 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1627 gl_info->gl_ops.gl.p_glLoadIdentity();
1628 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1629 gl_info->gl_ops.gl.p_glLoadIdentity();
1630
1631 gl_info->gl_ops.gl.p_glClearColor(0, 1, 0, 0);
1632 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1633
1634 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1635 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 0.0);
1636 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, -1.0f);
1637 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 0.0);
1638 gl_info->gl_ops.gl.p_glVertex2f(1.0f, -1.0f);
1639 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 1.0);
1640 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, 1.0f);
1641 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 1.0);
1642 gl_info->gl_ops.gl.p_glVertex2f(1.0f, 1.0f);
1643 gl_info->gl_ops.gl.p_glEnd();
1644
1645 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1646 memset(readback, 0x7f, sizeof(readback));
1647 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1648 if (color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5)
1649 || color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1650 {
1651 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, assuming no filtering\n",
1652 readback[6], readback[9]);
1653 ret = FALSE;
1654 }
1655 else
1656 {
1657 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1658 readback[6], readback[9]);
1659 ret = TRUE;
1660 }
1661
1662 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1663 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1664 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1665 gl_info->gl_ops.gl.p_glDeleteTextures(1, &buffer);
1666
1667 if (gl_info->gl_ops.gl.p_glGetError())
1668 {
1669 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1670 ret = FALSE;
1671 }
1672
1673 return ret;
1674 }
1675
1676 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1677 {
1678 struct wined3d_format *format;
1679 unsigned int fmt_idx, i;
1680 static const enum wined3d_format_id fmts16[] =
1681 {
1682 WINED3DFMT_R16_FLOAT,
1683 WINED3DFMT_R16G16_FLOAT,
1684 WINED3DFMT_R16G16B16A16_FLOAT,
1685 };
1686 BOOL filtered;
1687
1688 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
1689 /* This was already handled by init_format_texture_info(). */
1690 return;
1691
1692 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1693 {
1694 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1695 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1696 {
1697 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1698 filtered = TRUE;
1699 }
1700 else if (gl_info->limits.glsl_varyings > 44)
1701 {
1702 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1703 filtered = TRUE;
1704 }
1705 else
1706 {
1707 TRACE("Assuming no float16 blending\n");
1708 filtered = FALSE;
1709 }
1710
1711 if(filtered)
1712 {
1713 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1714 {
1715 fmt_idx = getFmtIdx(fmts16[i]);
1716 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1717 }
1718 }
1719 return;
1720 }
1721
1722 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1723 {
1724 fmt_idx = getFmtIdx(fmts16[i]);
1725 format = &gl_info->formats[fmt_idx];
1726 if (!format->glInternal) continue; /* Not supported by GL */
1727
1728 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1729 if(filtered)
1730 {
1731 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1732 format->flags |= WINED3DFMT_FLAG_FILTERING;
1733 }
1734 else
1735 {
1736 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1737 }
1738 }
1739 }
1740
1741 static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1742 {
1743 unsigned int i;
1744 int idx;
1745
1746 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1747 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1748 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1749
1750 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1751 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1752 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1753
1754 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1755 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1756 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1757
1758 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1759 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1760 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1761
1762 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1763 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1764 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1765
1766 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1767 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1768 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1769 * the only driver that implements it(fglrx) has a buggy implementation.
1770 *
1771 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1772 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1773 * conversion for this format.
1774 */
1775 if (!gl_info->supported[NV_TEXTURE_SHADER])
1776 {
1777 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1778 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1779 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1780 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1781 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1782 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1783 }
1784 else
1785 {
1786 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1787 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1788 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1789
1790 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1791 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1792 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1793 }
1794
1795 if (!gl_info->supported[NV_TEXTURE_SHADER])
1796 {
1797 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1798 * with each other
1799 */
1800 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1801 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1802 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1803 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1804 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1805 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1806 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1807 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1808 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1809 }
1810 else
1811 {
1812 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1813 * are converted at surface loading time, but they do not need any modification in
1814 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1815 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1816 */
1817 }
1818
1819 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1820 {
1821 idx = getFmtIdx(WINED3DFMT_ATI2N);
1822 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1823 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1824 }
1825 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1826 {
1827 idx = getFmtIdx(WINED3DFMT_ATI2N);
1828 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1829 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1830 }
1831
1832 if (!gl_info->supported[APPLE_YCBCR_422])
1833 {
1834 idx = getFmtIdx(WINED3DFMT_YUY2);
1835 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1836
1837 idx = getFmtIdx(WINED3DFMT_UYVY);
1838 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1839 }
1840
1841 idx = getFmtIdx(WINED3DFMT_YV12);
1842 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
1843 gl_info->formats[idx].height_scale.numerator = 3;
1844 gl_info->formats[idx].height_scale.denominator = 2;
1845 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1846
1847 idx = getFmtIdx(WINED3DFMT_NV12);
1848 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
1849 gl_info->formats[idx].height_scale.numerator = 3;
1850 gl_info->formats[idx].height_scale.denominator = 2;
1851 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_NV12);
1852
1853 if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
1854 {
1855 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1856 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1857 }
1858
1859 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1860 {
1861 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1862 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1863 }
1864
1865 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1866 {
1867 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1868 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1869 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1870 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1871
1872 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1873 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1874 }
1875
1876 if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
1877 {
1878 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1879 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1880
1881 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1882 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1883
1884 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1885 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1886 }
1887
1888 if (gl_info->quirks & WINED3D_QUIRK_BROKEN_RGBA16)
1889 {
1890 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_UNORM);
1891 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1892 }
1893
1894 /* ATI instancing hack: Although ATI cards do not support Shader Model
1895 * 3.0, they support instancing. To query if the card supports instancing
1896 * CheckDeviceFormat() with the special format MAKEFOURCC('I','N','S','T')
1897 * is used. Should an application check for this, provide a proper return
1898 * value. We can do instancing with all shader versions, but we need
1899 * vertex shaders.
1900 *
1901 * Additionally applications have to set the D3DRS_POINTSIZE render state
1902 * to MAKEFOURCC('I','N','S','T') once to enable instancing. Wined3d
1903 * doesn't need that and just ignores it.
1904 *
1905 * With Shader Model 3.0 capable cards Instancing 'just works' in Windows. */
1906 /* FIXME: This should just check the shader backend caps. */
1907 if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
1908 {
1909 idx = getFmtIdx(WINED3DFMT_INST);
1910 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
1911 }
1912
1913 /* Depth bound test. To query if the card supports it CheckDeviceFormat()
1914 * with the special format MAKEFOURCC('N','V','D','B') is used. It is
1915 * enabled by setting D3DRS_ADAPTIVETESS_X render state to
1916 * MAKEFOURCC('N','V','D','B') and then controlled by setting
1917 * D3DRS_ADAPTIVETESS_Z (zMin) and D3DRS_ADAPTIVETESS_W (zMax) to test
1918 * value. */
1919 if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST])
1920 {
1921 idx = getFmtIdx(WINED3DFMT_NVDB);
1922 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
1923 }
1924
1925 /* RESZ aka AMD DX9-level hack for multisampled depth buffer resolve. You query for RESZ
1926 * support by checking for availability of MAKEFOURCC('R','E','S','Z') surfaces with
1927 * RENDERTARGET usage. */
1928 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
1929 {
1930 idx = getFmtIdx(WINED3DFMT_RESZ);
1931 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET;
1932 }
1933
1934 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1935 {
1936 struct wined3d_format *format = &gl_info->formats[i];
1937
1938 if (!(format->flags & WINED3DFMT_FLAG_TEXTURE))
1939 continue;
1940
1941 if (!adapter->shader_backend->shader_color_fixup_supported(format->color_fixup)
1942 || !adapter->fragment_pipe->color_fixup_supported(format->color_fixup))
1943 format->flags &= ~WINED3DFMT_FLAG_TEXTURE;
1944 }
1945 }
1946
1947 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1948 {
1949 unsigned int i;
1950
1951 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1952 {
1953 struct wined3d_format *format;
1954 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1955
1956 if (fmt_idx == -1)
1957 {
1958 ERR("Format %s (%#x) not found.\n",
1959 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1960 return FALSE;
1961 }
1962
1963 format = &gl_info->formats[fmt_idx];
1964 format->emit_idx = format_vertex_info[i].emit_idx;
1965 format->component_count = format_vertex_info[i].component_count;
1966 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1967 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1968 format->gl_normalized = format_vertex_info[i].gl_normalized;
1969 format->component_size = format_vertex_info[i].component_size;
1970 }
1971
1972 return TRUE;
1973 }
1974
1975 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1976 {
1977 if (!init_format_base_info(gl_info)) return FALSE;
1978
1979 if (!init_format_block_info(gl_info))
1980 {
1981 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1982 gl_info->formats = NULL;
1983 return FALSE;
1984 }
1985
1986 return TRUE;
1987 }
1988
1989 /* Context activation is done by the caller. */
1990 BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter)
1991 {
1992 struct wined3d_gl_info *gl_info = &adapter->gl_info;
1993
1994 if (!init_format_base_info(gl_info)) return FALSE;
1995
1996 if (!init_format_block_info(gl_info)) goto fail;
1997 if (!init_format_texture_info(adapter, gl_info)) goto fail;
1998 if (!init_format_vertex_info(gl_info)) goto fail;
1999
2000 apply_format_fixups(adapter, gl_info);
2001 init_format_fbo_compat_info(gl_info);
2002 init_format_filter_info(gl_info, adapter->driver_info.vendor);
2003
2004 return TRUE;
2005
2006 fail:
2007 HeapFree(GetProcessHeap(), 0, gl_info->formats);
2008 gl_info->formats = NULL;
2009 return FALSE;
2010 }
2011
2012 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
2013 enum wined3d_format_id format_id)
2014 {
2015 int idx = getFmtIdx(format_id);
2016
2017 if (idx == -1)
2018 {
2019 FIXME("Can't find format %s (%#x) in the format lookup table\n",
2020 debug_d3dformat(format_id), format_id);
2021 /* Get the caller a valid pointer */
2022 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
2023 }
2024
2025 return &gl_info->formats[idx];
2026 }
2027
2028 UINT wined3d_format_calculate_pitch(const struct wined3d_format *format, UINT width)
2029 {
2030 /* For block based formats, pitch means the amount of bytes to the next
2031 * row of blocks rather than the next row of pixels. */
2032 if (format->flags & WINED3DFMT_FLAG_BLOCKS)
2033 return format->block_byte_count * ((width + format->block_width - 1) / format->block_width);
2034
2035 return format->byte_count * width;
2036 }
2037
2038 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment,
2039 UINT width, UINT height, UINT depth)
2040 {
2041 UINT pitch = wined3d_format_calculate_pitch(format, width);
2042 UINT size;
2043
2044 if (format->id == WINED3DFMT_UNKNOWN)
2045 {
2046 size = 0;
2047 }
2048 else if (format->flags & WINED3DFMT_FLAG_BLOCKS)
2049 {
2050 UINT row_count = (height + format->block_height - 1) / format->block_height;
2051 size = row_count * ((pitch + alignment - 1) & ~(alignment - 1));
2052 }
2053 else
2054 {
2055 size = height * ((pitch + alignment - 1) & ~(alignment - 1));
2056 }
2057
2058 if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
2059 {
2060 /* The D3D format requirements make sure that the resulting format is an integer again */
2061 size *= format->height_scale.numerator;
2062 size /= format->height_scale.denominator;
2063 }
2064
2065 size *= depth;
2066
2067 return size;
2068 }
2069
2070 /*****************************************************************************
2071 * Trace formatting of useful values
2072 */
2073 const char *debug_d3dformat(enum wined3d_format_id format_id)
2074 {
2075 switch (format_id)
2076 {
2077 #define FMT_TO_STR(format_id) case format_id: return #format_id
2078 FMT_TO_STR(WINED3DFMT_UNKNOWN);
2079 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
2080 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
2081 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
2082 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
2083 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
2084 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
2085 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
2086 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
2087 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
2088 FMT_TO_STR(WINED3DFMT_P8_UINT);
2089 FMT_TO_STR(WINED3DFMT_L8_UNORM);
2090 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
2091 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
2092 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
2093 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
2094 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
2095 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
2096 FMT_TO_STR(WINED3DFMT_UYVY);
2097 FMT_TO_STR(WINED3DFMT_YUY2);
2098 FMT_TO_STR(WINED3DFMT_YV12);
2099 FMT_TO_STR(WINED3DFMT_NV12);
2100 FMT_TO_STR(WINED3DFMT_DXT1);
2101 FMT_TO_STR(WINED3DFMT_DXT2);
2102 FMT_TO_STR(WINED3DFMT_DXT3);
2103 FMT_TO_STR(WINED3DFMT_DXT4);
2104 FMT_TO_STR(WINED3DFMT_DXT5);
2105 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
2106 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
2107 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
2108 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
2109 FMT_TO_STR(WINED3DFMT_D32_UNORM);
2110 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
2111 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
2112 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
2113 FMT_TO_STR(WINED3DFMT_L16_UNORM);
2114 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
2115 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
2116 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
2117 FMT_TO_STR(WINED3DFMT_ATI2N);
2118 FMT_TO_STR(WINED3DFMT_NVDB);
2119 FMT_TO_STR(WINED3DFMT_NVHU);
2120 FMT_TO_STR(WINED3DFMT_NVHS);
2121 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
2122 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
2123 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
2124 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
2125 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
2126 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
2127 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
2128 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
2129 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
2130 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
2131 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
2132 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
2133 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
2134 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
2135 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
2136 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
2137 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
2138 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
2139 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
2140 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
2141 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
2142 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
2143 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
2144 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
2145 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
2146 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
2147 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
2148 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
2149 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
2150 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
2151 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
2152 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
2153 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
2154 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
2155 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
2156 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
2157 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
2158 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
2159 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
2160 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
2161 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
2162 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
2163 FMT_TO_STR(WINED3DFMT_R32_UINT);
2164 FMT_TO_STR(WINED3DFMT_R32_SINT);
2165 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
2166 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
2167 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
2168 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
2169 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
2170 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
2171 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
2172 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
2173 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
2174 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
2175 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
2176 FMT_TO_STR(WINED3DFMT_D16_UNORM);
2177 FMT_TO_STR(WINED3DFMT_R16_UNORM);
2178 FMT_TO_STR(WINED3DFMT_R16_UINT);
2179 FMT_TO_STR(WINED3DFMT_R16_SNORM);
2180 FMT_TO_STR(WINED3DFMT_R16_SINT);
2181 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
2182 FMT_TO_STR(WINED3DFMT_R8_UNORM);
2183 FMT_TO_STR(WINED3DFMT_R8_UINT);
2184 FMT_TO_STR(WINED3DFMT_R8_SNORM);
2185 FMT_TO_STR(WINED3DFMT_R8_SINT);
2186 FMT_TO_STR(WINED3DFMT_A8_UNORM);
2187 FMT_TO_STR(WINED3DFMT_R1_UNORM);
2188 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
2189 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
2190 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
2191 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
2192 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
2193 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
2194 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
2195 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
2196 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
2197 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
2198 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
2199 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
2200 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
2201 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
2202 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
2203 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
2204 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
2205 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
2206 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
2207 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
2208 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
2209 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
2210 FMT_TO_STR(WINED3DFMT_INTZ);
2211 FMT_TO_STR(WINED3DFMT_RESZ);
2212 FMT_TO_STR(WINED3DFMT_NULL);
2213 FMT_TO_STR(WINED3DFMT_R16);
2214 FMT_TO_STR(WINED3DFMT_AL16);
2215 #undef FMT_TO_STR
2216 default:
2217 {
2218 char fourcc[5];
2219 fourcc[0] = (char)(format_id);
2220 fourcc[1] = (char)(format_id >> 8);
2221 fourcc[2] = (char)(format_id >> 16);
2222 fourcc[3] = (char)(format_id >> 24);
2223 fourcc[4] = 0;
2224 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
2225 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
2226 else
2227 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
2228 }
2229 return "unrecognized";
2230 }
2231 }
2232
2233 const char *debug_d3ddevicetype(enum wined3d_device_type device_type)
2234 {
2235 switch (device_type)
2236 {
2237 #define DEVTYPE_TO_STR(dev) case dev: return #dev
2238 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_HAL);
2239 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_REF);
2240 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_SW);
2241 #undef DEVTYPE_TO_STR
2242 default:
2243 FIXME("Unrecognized device type %#x.\n", device_type);
2244 return "unrecognized";
2245 }
2246 }
2247
2248 const char *debug_d3dusage(DWORD usage)
2249 {
2250 char buf[333];
2251
2252 buf[0] = '\0';
2253 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
2254 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
2255 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
2256 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
2257 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
2258 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
2259 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
2260 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
2261 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
2262 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
2263 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
2264 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
2265 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
2266 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
2267 #undef WINED3DUSAGE_TO_STR
2268 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
2269
2270 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2271 }
2272
2273 const char *debug_d3dusagequery(DWORD usagequery)
2274 {
2275 char buf[238];
2276
2277 buf[0] = '\0';
2278 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
2279 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
2280 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
2281 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
2282 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
2283 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
2284 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
2285 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
2286 #undef WINED3DUSAGEQUERY_TO_STR
2287 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
2288
2289 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2290 }
2291
2292 const char *debug_d3ddeclmethod(enum wined3d_decl_method method)
2293 {
2294 switch (method)
2295 {
2296 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
2297 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_DEFAULT);
2298 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_U);
2299 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_V);
2300 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_CROSS_UV);
2301 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_UV);
2302 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP);
2303 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP_PRESAMPLED);
2304 #undef WINED3DDECLMETHOD_TO_STR
2305 default:
2306 FIXME("Unrecognized declaration method %#x.\n", method);
2307 return "unrecognized";
2308 }
2309 }
2310
2311 const char *debug_d3ddeclusage(enum wined3d_decl_usage usage)
2312 {
2313 switch (usage)
2314 {
2315 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
2316 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITION);
2317 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_WEIGHT);
2318 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_INDICES);
2319 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_NORMAL);
2320 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_PSIZE);
2321 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TEXCOORD);
2322 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TANGENT);
2323 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BINORMAL);
2324 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TESS_FACTOR);
2325 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITIONT);
2326 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_COLOR);
2327 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_FOG);
2328 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_DEPTH);
2329 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_SAMPLE);
2330 #undef WINED3DDECLUSAGE_TO_STR
2331 default:
2332 FIXME("Unrecognized %u declaration usage!\n", usage);
2333 return "unrecognized";
2334 }
2335 }
2336
2337 const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
2338 {
2339 switch (resource_type)
2340 {
2341 #define RES_TO_STR(res) case res: return #res
2342 RES_TO_STR(WINED3D_RTYPE_SURFACE);
2343 RES_TO_STR(WINED3D_RTYPE_VOLUME);
2344 RES_TO_STR(WINED3D_RTYPE_TEXTURE);
2345 RES_TO_STR(WINED3D_RTYPE_VOLUME_TEXTURE);
2346 RES_TO_STR(WINED3D_RTYPE_CUBE_TEXTURE);
2347 RES_TO_STR(WINED3D_RTYPE_BUFFER);
2348 #undef RES_TO_STR
2349 default:
2350 FIXME("Unrecognized resource type %#x.\n", resource_type);
2351 return "unrecognized";
2352 }
2353 }
2354
2355 const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type)
2356 {
2357 switch (primitive_type)
2358 {
2359 #define PRIM_TO_STR(prim) case prim: return #prim
2360 PRIM_TO_STR(WINED3D_PT_UNDEFINED);
2361 PRIM_TO_STR(WINED3D_PT_POINTLIST);
2362 PRIM_TO_STR(WINED3D_PT_LINELIST);
2363 PRIM_TO_STR(WINED3D_PT_LINESTRIP);
2364 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST);
2365 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP);
2366 PRIM_TO_STR(WINED3D_PT_TRIANGLEFAN);
2367 PRIM_TO_STR(WINED3D_PT_LINELIST_ADJ);
2368 PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ);
2369 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ);
2370 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ);
2371 #undef PRIM_TO_STR
2372 default:
2373 FIXME("Unrecognized %u primitive type!\n", primitive_type);
2374 return "unrecognized";
2375 }
2376 }
2377
2378 const char *debug_d3drenderstate(enum wined3d_render_state state)
2379 {
2380 switch (state)
2381 {
2382 #define D3DSTATE_TO_STR(u) case u: return #u
2383 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIAS);
2384 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREPERSPECTIVE);
2385 D3DSTATE_TO_STR(WINED3D_RS_WRAPU);
2386 D3DSTATE_TO_STR(WINED3D_RS_WRAPV);
2387 D3DSTATE_TO_STR(WINED3D_RS_ZENABLE);
2388 D3DSTATE_TO_STR(WINED3D_RS_FILLMODE);
2389 D3DSTATE_TO_STR(WINED3D_RS_SHADEMODE);
2390 D3DSTATE_TO_STR(WINED3D_RS_LINEPATTERN);
2391 D3DSTATE_TO_STR(WINED3D_RS_MONOENABLE);
2392 D3DSTATE_TO_STR(WINED3D_RS_ROP2);
2393 D3DSTATE_TO_STR(WINED3D_RS_PLANEMASK);
2394 D3DSTATE_TO_STR(WINED3D_RS_ZWRITEENABLE);
2395 D3DSTATE_TO_STR(WINED3D_RS_ALPHATESTENABLE);
2396 D3DSTATE_TO_STR(WINED3D_RS_LASTPIXEL);
2397 D3DSTATE_TO_STR(WINED3D_RS_SRCBLEND);
2398 D3DSTATE_TO_STR(WINED3D_RS_DESTBLEND);
2399 D3DSTATE_TO_STR(WINED3D_RS_CULLMODE);
2400 D3DSTATE_TO_STR(WINED3D_RS_ZFUNC);
2401 D3DSTATE_TO_STR(WINED3D_RS_ALPHAREF);
2402 D3DSTATE_TO_STR(WINED3D_RS_ALPHAFUNC);
2403 D3DSTATE_TO_STR(WINED3D_RS_DITHERENABLE);
2404 D3DSTATE_TO_STR(WINED3D_RS_ALPHABLENDENABLE);
2405 D3DSTATE_TO_STR(WINED3D_RS_FOGENABLE);
2406 D3DSTATE_TO_STR(WINED3D_RS_SPECULARENABLE);
2407 D3DSTATE_TO_STR(WINED3D_RS_ZVISIBLE);
2408 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXEL);
2409 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXELX);
2410 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEDALPHA);
2411 D3DSTATE_TO_STR(WINED3D_RS_FOGCOLOR);
2412 D3DSTATE_TO_STR(WINED3D_RS_FOGTABLEMODE);
2413 D3DSTATE_TO_STR(WINED3D_RS_FOGSTART);
2414 D3DSTATE_TO_STR(WINED3D_RS_FOGEND);
2415 D3DSTATE_TO_STR(WINED3D_RS_FOGDENSITY);
2416 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEENABLE);
2417 D3DSTATE_TO_STR(WINED3D_RS_EDGEANTIALIAS);
2418 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYENABLE);
2419 D3DSTATE_TO_STR(WINED3D_RS_MIPMAPLODBIAS);
2420 D3DSTATE_TO_STR(WINED3D_RS_RANGEFOGENABLE);
2421 D3DSTATE_TO_STR(WINED3D_RS_ANISOTROPY);
2422 D3DSTATE_TO_STR(WINED3D_RS_FLUSHBATCH);
2423 D3DSTATE_TO_STR(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT);
2424 D3DSTATE_TO_STR(WINED3D_RS_STENCILENABLE);
2425 D3DSTATE_TO_STR(WINED3D_RS_STENCILFAIL);
2426 D3DSTATE_TO_STR(WINED3D_RS_STENCILZFAIL);
2427 D3DSTATE_TO_STR(WINED3D_RS_STENCILPASS);
2428 D3DSTATE_TO_STR(WINED3D_RS_STENCILFUNC);
2429 D3DSTATE_TO_STR(WINED3D_RS_STENCILREF);
2430 D3DSTATE_TO_STR(WINED3D_RS_STENCILMASK);
2431 D3DSTATE_TO_STR(WINED3D_RS_STENCILWRITEMASK);
2432 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREFACTOR);
2433 D3DSTATE_TO_STR(WINED3D_RS_WRAP0);
2434 D3DSTATE_TO_STR(WINED3D_RS_WRAP1);
2435 D3DSTATE_TO_STR(WINED3D_RS_WRAP2);
2436 D3DSTATE_TO_STR(WINED3D_RS_WRAP3);
2437 D3DSTATE_TO_STR(WINED3D_RS_WRAP4);
2438 D3DSTATE_TO_STR(WINED3D_RS_WRAP5);
2439 D3DSTATE_TO_STR(WINED3D_RS_WRAP6);
2440 D3DSTATE_TO_STR(WINED3D_RS_WRAP7);
2441 D3DSTATE_TO_STR(WINED3D_RS_CLIPPING);
2442 D3DSTATE_TO_STR(WINED3D_RS_LIGHTING);
2443 D3DSTATE_TO_STR(WINED3D_RS_EXTENTS);
2444 D3DSTATE_TO_STR(WINED3D_RS_AMBIENT);
2445 D3DSTATE_TO_STR(WINED3D_RS_FOGVERTEXMODE);
2446 D3DSTATE_TO_STR(WINED3D_RS_COLORVERTEX);
2447 D3DSTATE_TO_STR(WINED3D_RS_LOCALVIEWER);
2448 D3DSTATE_TO_STR(WINED3D_RS_NORMALIZENORMALS);
2449 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYBLENDENABLE);
2450 D3DSTATE_TO_STR(WINED3D_RS_DIFFUSEMATERIALSOURCE);
2451 D3DSTATE_TO_STR(WINED3D_RS_SPECULARMATERIALSOURCE);
2452 D3DSTATE_TO_STR(WINED3D_RS_AMBIENTMATERIALSOURCE);
2453 D3DSTATE_TO_STR(WINED3D_RS_EMISSIVEMATERIALSOURCE);
2454 D3DSTATE_TO_STR(WINED3D_RS_VERTEXBLEND);
2455 D3DSTATE_TO_STR(WINED3D_RS_CLIPPLANEENABLE);
2456 D3DSTATE_TO_STR(WINED3D_RS_SOFTWAREVERTEXPROCESSING);
2457 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE);
2458 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MIN);
2459 D3DSTATE_TO_STR(WINED3D_RS_POINTSPRITEENABLE);
2460 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALEENABLE);
2461 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_A);
2462 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_B);
2463 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_C);
2464 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEANTIALIAS);
2465 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEMASK);
2466 D3DSTATE_TO_STR(WINED3D_RS_PATCHEDGESTYLE);
2467 D3DSTATE_TO_STR(WINED3D_RS_PATCHSEGMENTS);
2468 D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN);
2469 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX);
2470 D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE);
2471 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
2472 D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR);
2473 D3DSTATE_TO_STR(WINED3D_RS_BLENDOP);
2474 D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE);
2475 D3DSTATE_TO_STR(WINED3D_RS_NORMALDEGREE);
2476 D3DSTATE_TO_STR(WINED3D_RS_SCISSORTESTENABLE);
2477 D3DSTATE_TO_STR(WINED3D_RS_SLOPESCALEDEPTHBIAS);
2478 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIASEDLINEENABLE);
2479 D3DSTATE_TO_STR(WINED3D_RS_MINTESSELLATIONLEVEL);
2480 D3DSTATE_TO_STR(WINED3D_RS_MAXTESSELLATIONLEVEL);
2481 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_X);
2482 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Y);
2483 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Z);
2484 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_W);
2485 D3DSTATE_TO_STR(WINED3D_RS_ENABLEADAPTIVETESSELLATION);
2486 D3DSTATE_TO_STR(WINED3D_RS_TWOSIDEDSTENCILMODE);
2487 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFAIL);
2488 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILZFAIL);
2489 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILPASS);
2490 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFUNC);
2491 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1);
2492 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2);
2493 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3);
2494 D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR);
2495 D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE);
2496 D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS);
2497 D3DSTATE_TO_STR(WINED3D_RS_WRAP8);
2498 D3DSTATE_TO_STR(WINED3D_RS_WRAP9);
2499 D3DSTATE_TO_STR(WINED3D_RS_WRAP10);
2500 D3DSTATE_TO_STR(WINED3D_RS_WRAP11);
2501 D3DSTATE_TO_STR(WINED3D_RS_WRAP12);
2502 D3DSTATE_TO_STR(WINED3D_RS_WRAP13);
2503 D3DSTATE_TO_STR(WINED3D_RS_WRAP14);
2504 D3DSTATE_TO_STR(WINED3D_RS_WRAP15);
2505 D3DSTATE_TO_STR(WINED3D_RS_SEPARATEALPHABLENDENABLE);
2506 D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
2507 D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
2508 D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
2509 #undef D3DSTATE_TO_STR
2510 default:
2511 FIXME("Unrecognized %u render state!\n", state);
2512 return "unrecognized";
2513 }
2514 }
2515
2516 const char *debug_d3dsamplerstate(enum wined3d_sampler_state state)
2517 {
2518 switch (state)
2519 {
2520 #define D3DSTATE_TO_STR(u) case u: return #u
2521 D3DSTATE_TO_STR(WINED3D_SAMP_BORDER_COLOR);
2522 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_U);
2523 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_V);
2524 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_W);
2525 D3DSTATE_TO_STR(WINED3D_SAMP_MAG_FILTER);
2526 D3DSTATE_TO_STR(WINED3D_SAMP_MIN_FILTER);
2527 D3DSTATE_TO_STR(WINED3D_SAMP_MIP_FILTER);
2528 D3DSTATE_TO_STR(WINED3D_SAMP_MIPMAP_LOD_BIAS);
2529 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_MIP_LEVEL);
2530 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_ANISOTROPY);
2531 D3DSTATE_TO_STR(WINED3D_SAMP_SRGB_TEXTURE);
2532 D3DSTATE_TO_STR(WINED3D_SAMP_ELEMENT_INDEX);
2533 D3DSTATE_TO_STR(WINED3D_SAMP_DMAP_OFFSET);
2534 #undef D3DSTATE_TO_STR
2535 default:
2536 FIXME("Unrecognized %u sampler state!\n", state);
2537 return "unrecognized";
2538 }
2539 }
2540
2541 const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type)
2542 {
2543 switch (filter_type)
2544 {
2545 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2546 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_NONE);
2547 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_POINT);
2548 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_LINEAR);
2549 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_ANISOTROPIC);
2550 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_FLAT_CUBIC);
2551 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_CUBIC);
2552 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_PYRAMIDAL_QUAD);
2553 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_QUAD);
2554 #undef D3DTEXTUREFILTERTYPE_TO_STR
2555 default:
2556 FIXME("Unrecognied texture filter type 0x%08x.\n", filter_type);
2557 return "unrecognized";
2558 }
2559 }
2560
2561 const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state)
2562 {
2563 switch (state)
2564 {
2565 #define D3DSTATE_TO_STR(u) case u: return #u
2566 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_OP);
2567 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG1);
2568 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG2);
2569 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_OP);
2570 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG1);
2571 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG2);
2572 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT00);
2573 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT01);
2574 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT10);
2575 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT11);
2576 D3DSTATE_TO_STR(WINED3D_TSS_TEXCOORD_INDEX);
2577 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LSCALE);
2578 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LOFFSET);
2579 D3DSTATE_TO_STR(WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS);
2580 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG0);
2581 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG0);
2582 D3DSTATE_TO_STR(WINED3D_TSS_RESULT_ARG);
2583 D3DSTATE_TO_STR(WINED3D_TSS_CONSTANT);
2584 #undef D3DSTATE_TO_STR
2585 default:
2586 FIXME("Unrecognized %u texture state!\n", state);
2587 return "unrecognized";
2588 }
2589 }
2590
2591 const char *debug_d3dtop(enum wined3d_texture_op d3dtop)
2592 {
2593 switch (d3dtop)
2594 {
2595 #define D3DTOP_TO_STR(u) case u: return #u
2596 D3DTOP_TO_STR(WINED3D_TOP_DISABLE);
2597 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG1);
2598 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG2);
2599 D3DTOP_TO_STR(WINED3D_TOP_MODULATE);
2600 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_2X);
2601 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_4X);
2602 D3DTOP_TO_STR(WINED3D_TOP_ADD);
2603 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED);
2604 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED_2X);
2605 D3DTOP_TO_STR(WINED3D_TOP_SUBTRACT);
2606 D3DTOP_TO_STR(WINED3D_TOP_ADD_SMOOTH);
2607 D3DTOP_TO_STR(WINED3D_TOP_BLEND_DIFFUSE_ALPHA);
2608 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA);
2609 D3DTOP_TO_STR(WINED3D_TOP_BLEND_FACTOR_ALPHA);
2610 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM);
2611 D3DTOP_TO_STR(WINED3D_TOP_BLEND_CURRENT_ALPHA);
2612 D3DTOP_TO_STR(WINED3D_TOP_PREMODULATE);
2613 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR);
2614 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA);
2615 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR);
2616 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA);
2617 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP);
2618 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP_LUMINANCE);
2619 D3DTOP_TO_STR(WINED3D_TOP_DOTPRODUCT3);
2620 D3DTOP_TO_STR(WINED3D_TOP_MULTIPLY_ADD);
2621 D3DTOP_TO_STR(WINED3D_TOP_LERP);
2622 #undef D3DTOP_TO_STR
2623 default:
2624 FIXME("Unrecognized texture op %#x.\n", d3dtop);
2625 return "unrecognized";
2626 }
2627 }
2628
2629 const char *debug_d3dtstype(enum wined3d_transform_state tstype)
2630 {
2631 switch (tstype)
2632 {
2633 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2634 TSTYPE_TO_STR(WINED3D_TS_VIEW);
2635 TSTYPE_TO_STR(WINED3D_TS_PROJECTION);
2636 TSTYPE_TO_STR(WINED3D_TS_TEXTURE0);
2637 TSTYPE_TO_STR(WINED3D_TS_TEXTURE1);
2638 TSTYPE_TO_STR(WINED3D_TS_TEXTURE2);
2639 TSTYPE_TO_STR(WINED3D_TS_TEXTURE3);
2640 TSTYPE_TO_STR(WINED3D_TS_TEXTURE4);
2641 TSTYPE_TO_STR(WINED3D_TS_TEXTURE5);
2642 TSTYPE_TO_STR(WINED3D_TS_TEXTURE6);
2643 TSTYPE_TO_STR(WINED3D_TS_TEXTURE7);
2644 TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(0));
2645 #undef TSTYPE_TO_STR
2646 default:
2647 if (tstype > 256 && tstype < 512)
2648 {
2649 FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype);
2650 return ("WINED3D_TS_WORLD_MATRIX > 0");
2651 }
2652 FIXME("Unrecognized transform state %#x.\n", tstype);
2653 return "unrecognized";
2654 }
2655 }
2656
2657 static const char *debug_shader_type(enum wined3d_shader_type type)
2658 {
2659 switch(type)
2660 {
2661 #define WINED3D_TO_STR(type) case type: return #type
2662 WINED3D_TO_STR(WINED3D_SHADER_TYPE_PIXEL);
2663 WINED3D_TO_STR(WINED3D_SHADER_TYPE_VERTEX);
2664 WINED3D_TO_STR(WINED3D_SHADER_TYPE_GEOMETRY);
2665 #undef WINED3D_TO_STR
2666 default:
2667 FIXME("Unrecognized shader type %#x.\n", type);
2668 return "unrecognized";
2669 }
2670 }
2671
2672 const char *debug_d3dstate(DWORD state)
2673 {
2674 if (STATE_IS_RENDER(state))
2675 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2676 if (STATE_IS_TEXTURESTAGE(state))
2677 {
2678 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2679 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2680 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2681 texture_stage, debug_d3dtexturestate(texture_state));
2682 }
2683 if (STATE_IS_SAMPLER(state))
2684 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2685 if (STATE_IS_SHADER(state))
2686 return wine_dbg_sprintf("STATE_SHADER(%s)", debug_shader_type(state - STATE_SHADER(0)));
2687 if (STATE_IS_CONSTANT_BUFFER(state))
2688 return wine_dbg_sprintf("STATE_CONSTANT_BUFFER(%s)", debug_shader_type(state - STATE_CONSTANT_BUFFER(0)));
2689 if (STATE_IS_TRANSFORM(state))
2690 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2691 if (STATE_IS_STREAMSRC(state))
2692 return "STATE_STREAMSRC";
2693 if (STATE_IS_INDEXBUFFER(state))
2694 return "STATE_INDEXBUFFER";
2695 if (STATE_IS_VDECL(state))
2696 return "STATE_VDECL";
2697 if (STATE_IS_VIEWPORT(state))
2698 return "STATE_VIEWPORT";
2699 if (STATE_IS_LIGHT_TYPE(state))
2700 return "STATE_LIGHT_TYPE";
2701 if (STATE_IS_ACTIVELIGHT(state))
2702 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2703 if (STATE_IS_SCISSORRECT(state))
2704 return "STATE_SCISSORRECT";
2705 if (STATE_IS_CLIPPLANE(state))
2706 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2707 if (STATE_IS_MATERIAL(state))
2708 return "STATE_MATERIAL";
2709 if (STATE_IS_FRONTFACE(state))
2710 return "STATE_FRONTFACE";
2711 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2712 return "STATE_POINTSPRITECOORDORIGIN";
2713 if (STATE_IS_BASEVERTEXINDEX(state))
2714 return "STATE_BASEVERTEXINDEX";
2715 if (STATE_IS_FRAMEBUFFER(state))
2716 return "STATE_FRAMEBUFFER";
2717 if (STATE_IS_POINT_SIZE_ENABLE(state))
2718 return "STATE_POINT_SIZE_ENABLE";
2719
2720 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2721 }
2722
2723 const char *debug_d3dpool(enum wined3d_pool pool)
2724 {
2725 switch (pool)
2726 {
2727 #define POOL_TO_STR(p) case p: return #p
2728 POOL_TO_STR(WINED3D_POOL_DEFAULT);
2729 POOL_TO_STR(WINED3D_POOL_MANAGED);
2730 POOL_TO_STR(WINED3D_POOL_SYSTEM_MEM);
2731 POOL_TO_STR(WINED3D_POOL_SCRATCH);
2732 #undef POOL_TO_STR
2733 default:
2734 FIXME("Unrecognized pool %#x.\n", pool);
2735 return "unrecognized";
2736 }
2737 }
2738
2739 const char *debug_fbostatus(GLenum status) {
2740 switch(status) {
2741 #define FBOSTATUS_TO_STR(u) case u: return #u
2742 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2743 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2744 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2745 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2746 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2747 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2748 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2749 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2750 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2751 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2752 #undef FBOSTATUS_TO_STR
2753 default:
2754 FIXME("Unrecognied FBO status 0x%08x\n", status);
2755 return "unrecognized";
2756 }
2757 }
2758
2759 const char *debug_glerror(GLenum error) {
2760 switch(error) {
2761 #define GLERROR_TO_STR(u) case u: return #u
2762 GLERROR_TO_STR(GL_NO_ERROR);
2763 GLERROR_TO_STR(GL_INVALID_ENUM);
2764 GLERROR_TO_STR(GL_INVALID_VALUE);
2765 GLERROR_TO_STR(GL_INVALID_OPERATION);
2766 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2767 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2768 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2769 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2770 #undef GLERROR_TO_STR
2771 default:
2772 FIXME("Unrecognied GL error 0x%08x\n", error);
2773 return "unrecognized";
2774 }
2775 }
2776
2777 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2778 {
2779 switch(source)
2780 {
2781 #define WINED3D_TO_STR(x) case x: return #x
2782 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2783 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2784 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2785 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2786 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2787 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2788 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2789 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2790 #undef WINED3D_TO_STR
2791 default:
2792 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2793 return "unrecognized";
2794 }
2795 }
2796
2797 static const char *debug_complex_fixup(enum complex_fixup fixup)
2798 {
2799 switch(fixup)
2800 {
2801 #define WINED3D_TO_STR(x) case x: return #x
2802 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2803 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2804 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2805 WINED3D_TO_STR(COMPLEX_FIXUP_NV12);
2806 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2807 #undef WINED3D_TO_STR
2808 default:
2809 FIXME("Unrecognized complex fixup %#x\n", fixup);
2810 return "unrecognized";
2811 }
2812 }
2813
2814 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2815 {
2816 if (is_complex_fixup(fixup))
2817 {
2818 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2819 return;
2820 }
2821
2822 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2823 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2824 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2825 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2826 }
2827
2828 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2829 enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2830 {
2831 if (op == WINED3D_TOP_DISABLE)
2832 return FALSE;
2833 if (state->textures[stage])
2834 return FALSE;
2835
2836 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2837 && op != WINED3D_TOP_SELECT_ARG2)
2838 return TRUE;
2839 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2840 && op != WINED3D_TOP_SELECT_ARG1)
2841 return TRUE;
2842 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2843 && (op == WINED3D_TOP_MULTIPLY_ADD || op == WINED3D_TOP_LERP))
2844 return TRUE;
2845
2846 return FALSE;
2847 }
2848
2849 /* Setup this textures matrix according to the texture flags. */
2850 /* Context activation is done by the caller (state handler). */
2851 void set_texture_matrix(const struct wined3d_gl_info *gl_info, const float *smat, DWORD flags,
2852 BOOL calculatedCoords, BOOL transformed, enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2853 {
2854 float mat[16];
2855
2856 gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
2857 checkGLcall("glMatrixMode(GL_TEXTURE)");
2858
2859 if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed)
2860 {
2861 gl_info->gl_ops.gl.p_glLoadIdentity();
2862 checkGLcall("glLoadIdentity()");
2863 return;
2864 }
2865
2866 if (flags == (WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED))
2867 {
2868 ERR("Invalid texture transform flags: WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED.\n");
2869 return;
2870 }
2871
2872 memcpy(mat, smat, 16 * sizeof(float));
2873
2874 if (flags & WINED3D_TTFF_PROJECTED)
2875 {
2876 if (!ffp_proj_control)
2877 {
2878 switch (flags & ~WINED3D_TTFF_PROJECTED)
2879 {
2880 case WINED3D_TTFF_COUNT2:
2881 mat[ 3] = mat[ 1];
2882 mat[ 7] = mat[ 5];
2883 mat[11] = mat[ 9];
2884 mat[15] = mat[13];
2885 mat[ 1] = mat[ 5] = mat[ 9] = mat[13] = 0.0f;
2886 break;
2887 case WINED3D_TTFF_COUNT3:
2888 mat[ 3] = mat[ 2];
2889 mat[ 7] = mat[ 6];
2890 mat[11] = mat[10];
2891 mat[15] = mat[14];
2892 mat[ 2] = mat[ 6] = mat[10] = mat[14] = 0.0f;
2893 break;
2894 }
2895 }
2896 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2897 if(!calculatedCoords) {
2898 switch(vtx_fmt)
2899 {
2900 case WINED3DFMT_R32_FLOAT:
2901 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2902 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2903 * the input value to the transformation will be 0, so the matrix value is irrelevant
2904 */
2905 mat[12] = mat[4];
2906 mat[13] = mat[5];
2907 mat[14] = mat[6];
2908 mat[15] = mat[7];
2909 break;
2910 case WINED3DFMT_R32G32_FLOAT:
2911 /* See above, just 3rd and 4th coord
2912 */
2913 mat[12] = mat[8];
2914 mat[13] = mat[9];
2915 mat[14] = mat[10];
2916 mat[15] = mat[11];
2917 break;
2918 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2919 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2920
2921 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2922 * into a bad place. The division elimination below will apply to make sure the
2923 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2924 */
2925 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2926 break;
2927 default:
2928 FIXME("Unexpected fixed function texture coord input\n");
2929 }
2930 }
2931 if (!ffp_proj_control)
2932 {
2933 switch (flags & ~WINED3D_TTFF_PROJECTED)
2934 {
2935 /* case WINED3D_TTFF_COUNT1: Won't ever get here. */
2936 case WINED3D_TTFF_COUNT2:
2937 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2938 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2939 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2940 * the 4th coord evaluates to 1.0 to eliminate that.
2941 *
2942 * If the fixed function pipeline is used, the 4th value remains unused,
2943 * so there is no danger in doing this. With vertex shaders we have a
2944 * problem. Should an app hit that problem, the code here would have to
2945 * check for pixel shaders, and the shader has to undo the default gl divide.
2946 *
2947 * A more serious problem occurs if the app passes 4 coordinates in, and the
2948 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2949 * or a replacement shader. */
2950 default:
2951 mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2952 }
2953 }
2954 }
2955
2956 gl_info->gl_ops.gl.p_glLoadMatrixf(mat);
2957 checkGLcall("glLoadMatrixf(mat)");
2958 }
2959
2960 /* This small helper function is used to convert a bitmask into the number of masked bits */
2961 unsigned int count_bits(unsigned int mask)
2962 {
2963 unsigned int count;
2964 for (count = 0; mask; ++count)
2965 {
2966 mask &= mask - 1;
2967 }
2968 return count;
2969 }
2970
2971 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2972 * The later function requires individual color components. */
2973 BOOL getColorBits(const struct wined3d_format *format,
2974 BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2975 {
2976 TRACE("format %s.\n", debug_d3dformat(format->id));
2977
2978 switch (format->id)
2979 {
2980 case WINED3DFMT_B10G10R10A2_UNORM:
2981 case WINED3DFMT_R10G10B10A2_UNORM:
2982 case WINED3DFMT_B8G8R8X8_UNORM:
2983 case WINED3DFMT_B8G8R8_UNORM:
2984 case WINED3DFMT_B8G8R8A8_UNORM:
2985 case WINED3DFMT_R8G8B8A8_UNORM:
2986 case WINED3DFMT_B5G5R5X1_UNORM:
2987 case WINED3DFMT_B5G5R5A1_UNORM:
2988 case WINED3DFMT_B5G6R5_UNORM:
2989 case WINED3DFMT_B4G4R4X4_UNORM:
2990 case WINED3DFMT_B4G4R4A4_UNORM:
2991 case WINED3DFMT_B2G3R3_UNORM:
2992 case WINED3DFMT_P8_UINT_A8_UNORM:
2993 case WINED3DFMT_P8_UINT:
2994 break;
2995 default:
2996 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2997 return FALSE;
2998 }
2999
3000 *redSize = format->red_size;
3001 *greenSize = format->green_size;
3002 *blueSize = format->blue_size;
3003 *alphaSize = format->alpha_size;
3004 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
3005
3006 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
3007 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
3008 return TRUE;
3009 }
3010
3011 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
3012 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
3013 {
3014 TRACE("format %s.\n", debug_d3dformat(format->id));
3015
3016 switch (format->id)
3017 {
3018 case WINED3DFMT_D16_LOCKABLE:
3019 case WINED3DFMT_D16_UNORM:
3020 case WINED3DFMT_S1_UINT_D15_UNORM:
3021 case WINED3DFMT_X8D24_UNORM:
3022 case WINED3DFMT_S4X4_UINT_D24_UNORM:
3023 case WINED3DFMT_D24_UNORM_S8_UINT:
3024 case WINED3DFMT_S8_UINT_D24_FLOAT:
3025 case WINED3DFMT_D32_UNORM:
3026 case WINED3DFMT_D32_FLOAT:
3027 case WINED3DFMT_INTZ:
3028 break;
3029 default:
3030 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
3031 return FALSE;
3032 }
3033
3034 *depthSize = format->depth_size;
3035 *stencilSize = format->stencil_size;
3036
3037 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
3038 *depthSize, *stencilSize, debug_d3dformat(format->id));
3039 return TRUE;
3040 }
3041
3042 /* Note: It's the caller's responsibility to ensure values can be expressed
3043 * in the requested format. UNORM formats for example can only express values
3044 * in the range 0.0f -> 1.0f. */
3045 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color)
3046 {
3047 static const struct
3048 {
3049 enum wined3d_format_id format_id;
3050 float r_mul;
3051 float g_mul;
3052 float b_mul;
3053 float a_mul;
3054 BYTE r_shift;
3055 BYTE g_shift;
3056 BYTE b_shift;
3057 BYTE a_shift;
3058 }
3059 conv[] =
3060 {
3061 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
3062 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
3063 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
3064 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
3065 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
3066 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
3067 {WINED3DFMT_R8_UNORM, 255.0f, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0},
3068 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
3069 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
3070 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
3071 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
3072 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
3073 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
3074 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
3075 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
3076 {WINED3DFMT_P8_UINT, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
3077 };
3078 const struct wined3d_format *format = surface->resource.format;
3079 unsigned int i;
3080
3081 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
3082 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
3083
3084 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
3085 {
3086 DWORD ret;
3087
3088 if (format->id != conv[i].format_id) continue;
3089
3090 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
3091 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
3092 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
3093 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
3094
3095 TRACE("Returning 0x%08x.\n", ret);
3096
3097 return ret;
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_format *rt_format = state->fb->render_targets[0]->format;
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_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 }