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