VirtualBox

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

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

wine: update to 1.6.2

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