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