VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/utils.c@ 46521

Last change on this file since 46521 was 46521, checked in by vboxsync, 11 years ago

wine/new: export

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette