VirtualBox

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

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

header fixes

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