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