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