gdi32: Don't overflow the buffer in GetGlyphOutline.
[wine/multimedia.git] / dlls / wined3d / utils.c
blobe969fa7d2041f709e27ec8d9452632e5c67e6056
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_R8_UNORM, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
89 {WINED3DFMT_A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 0, 1, 0, 0},
90 {WINED3DFMT_B2G3R3A8_UNORM, 3, 3, 2, 8, 5, 2, 0, 8, 2, 0, 0},
91 {WINED3DFMT_B4G4R4X4_UNORM, 4, 4, 4, 0, 8, 4, 0, 0, 2, 0, 0},
92 {WINED3DFMT_R10G10B10A2_UNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
93 {WINED3DFMT_R10G10B10A2_UINT, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
94 {WINED3DFMT_R10G10B10A2_SNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
95 {WINED3DFMT_R8G8B8A8_UNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
96 {WINED3DFMT_R8G8B8A8_UINT, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
97 {WINED3DFMT_R8G8B8X8_UNORM, 8, 8, 8, 0, 0, 8, 16, 0, 4, 0, 0},
98 {WINED3DFMT_R16G16_UNORM, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
99 {WINED3DFMT_B10G10R10A2_UNORM, 10, 10, 10, 2, 20, 10, 0, 30, 4, 0, 0},
100 {WINED3DFMT_R16G16B16A16_UNORM, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
101 /* Luminance */
102 {WINED3DFMT_L8_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
103 {WINED3DFMT_L8A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 8, 2, 0, 0},
104 {WINED3DFMT_L4A4_UNORM, 0, 0, 0, 4, 0, 0, 0, 4, 1, 0, 0},
105 {WINED3DFMT_L16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
106 /* Bump mapping stuff */
107 {WINED3DFMT_R8G8_SNORM, 8, 8, 0, 0, 0, 8, 0, 0, 2, 0, 0},
108 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 5, 5, 0, 0, 0, 5, 0, 0, 2, 0, 0},
109 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 8, 8, 0, 0, 0, 8, 0, 0, 4, 0, 0},
110 {WINED3DFMT_R8G8B8A8_SNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
111 {WINED3DFMT_R16G16_SNORM, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
112 {WINED3DFMT_R10G11B11_SNORM, 10, 11, 11, 0, 0, 10, 21, 0, 4, 0, 0},
113 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
114 /* Depth stencil formats */
115 {WINED3DFMT_D16_LOCKABLE, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0},
116 {WINED3DFMT_D32_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0},
117 {WINED3DFMT_S1_UINT_D15_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 15, 1},
118 {WINED3DFMT_D24_UNORM_S8_UINT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
119 {WINED3DFMT_X8D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 0},
120 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 4},
121 {WINED3DFMT_D16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0},
122 {WINED3DFMT_D32_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0},
123 {WINED3DFMT_S8_UINT_D24_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
124 {WINED3DFMT_VERTEXDATA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
125 {WINED3DFMT_R16_UINT, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
126 {WINED3DFMT_R32_UINT, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
127 {WINED3DFMT_R32G32_UINT, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0},
128 {WINED3DFMT_R32G32B32_UINT, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0},
129 {WINED3DFMT_R32G32B32A32_UINT, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0},
130 {WINED3DFMT_R16G16B16A16_SNORM, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
131 /* Vendor-specific formats */
132 {WINED3DFMT_ATI2N, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
133 {WINED3DFMT_NVDB, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
134 {WINED3DFMT_INST, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
135 {WINED3DFMT_INTZ, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
136 {WINED3DFMT_RESZ, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
137 {WINED3DFMT_NVHU, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
138 {WINED3DFMT_NVHS, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
139 {WINED3DFMT_NULL, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
140 /* Unsure about them, could not find a Windows driver that supports them */
141 {WINED3DFMT_R16, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
142 {WINED3DFMT_AL16, 0, 0, 0, 16, 0, 0, 0, 16, 4, 0, 0},
143 /* Typeless */
144 {WINED3DFMT_R8_TYPELESS, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
145 {WINED3DFMT_R8G8_TYPELESS, 8, 8, 0, 0, 0, 8, 0, 0, 2, 0, 0},
146 {WINED3DFMT_R8G8B8A8_TYPELESS, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
147 {WINED3DFMT_R16_TYPELESS, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
148 {WINED3DFMT_R16G16_TYPELESS, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
149 {WINED3DFMT_R16G16B16A16_TYPELESS, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
150 {WINED3DFMT_R32_TYPELESS, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
151 {WINED3DFMT_R32G32_TYPELESS, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0},
152 {WINED3DFMT_R32G32B32_TYPELESS, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0},
153 {WINED3DFMT_R32G32B32A32_TYPELESS, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0},
156 struct wined3d_format_base_flags
158 enum wined3d_format_id id;
159 DWORD flags;
162 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
163 * still needs to use the correct block based calculation for e.g. the
164 * resource size. */
165 static const struct wined3d_format_base_flags format_base_flags[] =
167 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
171 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
172 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
173 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
174 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
175 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
176 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
177 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
178 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_BROKEN_PITCH},
179 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
180 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
181 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
182 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
184 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
185 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
186 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
187 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
190 struct wined3d_format_block_info
192 enum wined3d_format_id id;
193 UINT block_width;
194 UINT block_height;
195 UINT block_byte_count;
196 BOOL verify;
199 static const struct wined3d_format_block_info format_block_info[] =
201 {WINED3DFMT_DXT1, 4, 4, 8, TRUE},
202 {WINED3DFMT_DXT2, 4, 4, 16, TRUE},
203 {WINED3DFMT_DXT3, 4, 4, 16, TRUE},
204 {WINED3DFMT_DXT4, 4, 4, 16, TRUE},
205 {WINED3DFMT_DXT5, 4, 4, 16, TRUE},
206 {WINED3DFMT_ATI2N, 4, 4, 16, FALSE},
207 {WINED3DFMT_YUY2, 2, 1, 4, FALSE},
208 {WINED3DFMT_UYVY, 2, 1, 4, FALSE},
211 struct wined3d_format_vertex_info
213 enum wined3d_format_id id;
214 enum wined3d_ffp_emit_idx emit_idx;
215 GLint component_count;
216 GLenum gl_vtx_type;
217 GLint gl_vtx_format;
218 GLboolean gl_normalized;
219 unsigned int component_size;
222 static const struct wined3d_format_vertex_info format_vertex_info[] =
224 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
225 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
226 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
227 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
228 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
229 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
230 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
231 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
232 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
233 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
234 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
235 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
236 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
237 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
238 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
239 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
240 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)},
241 {WINED3DFMT_R32_UINT, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_INT, 1, GL_FALSE, sizeof(UINT)},
242 {WINED3DFMT_R32G32_UINT, WINED3D_FFP_EMIT_INVALID, 2, GL_UNSIGNED_INT, 2, GL_FALSE, sizeof(UINT)},
243 {WINED3DFMT_R32G32B32_UINT, WINED3D_FFP_EMIT_INVALID, 3, GL_UNSIGNED_INT, 3, GL_FALSE, sizeof(UINT)},
244 {WINED3DFMT_R32G32B32A32_UINT, WINED3D_FFP_EMIT_INVALID, 4, GL_UNSIGNED_INT, 4, GL_FALSE, sizeof(UINT)},
247 struct wined3d_format_texture_info
249 enum wined3d_format_id id;
250 GLint gl_internal;
251 GLint gl_srgb_internal;
252 GLint gl_rt_internal;
253 GLint gl_format;
254 GLint gl_type;
255 unsigned int conv_byte_count;
256 unsigned int flags;
257 enum wined3d_gl_extension extension;
258 void (*convert)(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
259 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth);
262 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
263 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
265 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
266 * format+type combination to load it. Thus convert it to A8L8, then load it
267 * with A4L4 internal, but A8L8 format+type
269 unsigned int x, y, z;
270 const unsigned char *Source;
271 unsigned char *Dest;
273 for (z = 0; z < depth; z++)
275 for (y = 0; y < height; y++)
277 Source = src + z * src_slice_pitch + y * src_row_pitch;
278 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
279 for (x = 0; x < width; x++ )
281 unsigned char color = (*Source++);
282 /* A */ Dest[1] = (color & 0xf0) << 0;
283 /* L */ Dest[0] = (color & 0x0f) << 4;
284 Dest += 2;
290 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
291 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
293 unsigned int x, y, z;
294 const WORD *Source;
296 for (z = 0; z < depth; z++)
298 for (y = 0; y < height; y++)
300 unsigned short *Dest_s = (unsigned short *) (dst + z * dst_slice_pitch + y * dst_row_pitch);
301 Source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch);
302 for (x = 0; x < width; x++ )
304 short color = (*Source++);
305 unsigned char l = ((color >> 10) & 0xfc);
306 short v = ((color >> 5) & 0x3e);
307 short u = ((color ) & 0x1f);
308 short v_conv = v + 16;
309 short u_conv = u + 16;
311 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
312 Dest_s += 1;
318 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
319 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
321 unsigned int x, y, z;
322 const WORD *Source;
323 unsigned char *Dest;
325 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
326 * fixed function and shaders without further conversion once the surface is
327 * loaded
329 for (z = 0; z < depth; z++)
331 for (y = 0; y < height; y++)
333 Source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch);
334 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
335 for (x = 0; x < width; x++ )
337 short color = (*Source++);
338 unsigned char l = ((color >> 10) & 0xfc);
339 char v = ((color >> 5) & 0x3e);
340 char u = ((color ) & 0x1f);
342 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
343 * and doubles the positive range. Thus shift left only once, gl does the 2nd
344 * shift. GL reads a signed value and converts it into an unsigned value.
346 /* M */ Dest[2] = l << 1;
348 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
349 * from 5 bit values to 8 bit values.
351 /* V */ Dest[1] = v << 3;
352 /* U */ Dest[0] = u << 3;
353 Dest += 3;
359 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
360 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
362 unsigned int x, y, z;
363 const short *Source;
364 unsigned char *Dest;
366 for (z = 0; z < depth; z++)
368 for (y = 0; y < height; y++)
370 Source = (const short *)(src + z * src_slice_pitch + y * src_row_pitch);
371 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
372 for (x = 0; x < width; x++ )
374 const short color = (*Source++);
375 /* B */ Dest[0] = 0xff;
376 /* G */ Dest[1] = (color >> 8) + 128; /* V */
377 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
378 Dest += 3;
384 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
385 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
387 unsigned int x, y, z;
388 const DWORD *Source;
389 unsigned char *Dest;
391 /* Doesn't work correctly with the fixed function pipeline, but can work in
392 * shaders if the shader is adjusted. (There's no use for this format in gl's
393 * standard fixed function pipeline anyway).
395 for (z = 0; z < depth; z++)
397 for (y = 0; y < height; y++)
399 Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
400 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
401 for (x = 0; x < width; x++ )
403 LONG color = (*Source++);
404 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
405 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
406 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
407 Dest += 4;
413 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
414 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
416 unsigned int x, y, z;
417 const DWORD *Source;
418 unsigned char *Dest;
420 /* This implementation works with the fixed function pipeline and shaders
421 * without further modification after converting the surface.
423 for (z = 0; z < depth; z++)
425 for (y = 0; y < height; y++)
427 Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
428 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
429 for (x = 0; x < width; x++ )
431 LONG color = (*Source++);
432 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
433 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
434 /* U */ Dest[0] = (color & 0xff); /* U */
435 /* I */ Dest[3] = 255; /* X */
436 Dest += 4;
442 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
443 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
445 unsigned int x, y, z;
446 const DWORD *Source;
447 unsigned char *Dest;
449 for (z = 0; z < depth; z++)
451 for (y = 0; y < height; y++)
453 Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
454 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
455 for (x = 0; x < width; x++ )
457 LONG color = (*Source++);
458 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
459 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
460 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
461 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
462 Dest += 4;
468 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
469 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
471 unsigned int x, y, z;
472 const DWORD *Source;
473 unsigned short *Dest;
475 for (z = 0; z < depth; z++)
477 for (y = 0; y < height; y++)
479 Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
480 Dest = (unsigned short *) (dst + z * dst_slice_pitch + y * dst_row_pitch);
481 for (x = 0; x < width; x++ )
483 const DWORD color = (*Source++);
484 /* B */ Dest[0] = 0xffff;
485 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
486 /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */
487 Dest += 3;
493 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
494 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
496 unsigned int x, y, z;
497 const WORD *Source;
498 WORD *Dest;
500 for (z = 0; z < depth; z++)
502 for (y = 0; y < height; y++)
504 Source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch);
505 Dest = (WORD *) (dst + z * dst_slice_pitch + y * dst_row_pitch);
506 for (x = 0; x < width; x++ )
508 WORD green = (*Source++);
509 WORD red = (*Source++);
510 Dest[0] = green;
511 Dest[1] = red;
512 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
513 * shader overwrites it anyway */
514 Dest[2] = 0xffff;
515 Dest += 3;
521 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
522 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
524 unsigned int x, y, z;
525 const float *Source;
526 float *Dest;
528 for (z = 0; z < depth; z++)
530 for (y = 0; y < height; y++)
532 Source = (const float *)(src + z * src_slice_pitch + y * src_row_pitch);
533 Dest = (float *) (dst + z * dst_slice_pitch + y * dst_row_pitch);
534 for (x = 0; x < width; x++ )
536 float green = (*Source++);
537 float red = (*Source++);
538 Dest[0] = green;
539 Dest[1] = red;
540 Dest[2] = 1.0f;
541 Dest += 3;
547 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
548 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
550 unsigned int x, y, z;
552 for (z = 0; z < depth; z++)
554 for (y = 0; y < height; ++y)
556 const WORD *source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch);
557 DWORD *dest = (DWORD *)(dst + z * dst_slice_pitch + y * dst_row_pitch);
559 for (x = 0; x < width; ++x)
561 /* The depth data is normalized, so needs to be scaled,
562 * the stencil data isn't. Scale depth data by
563 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
564 WORD d15 = source[x] >> 1;
565 DWORD d24 = (d15 << 9) + (d15 >> 6);
566 dest[x] = (d24 << 8) | (source[x] & 0x1);
572 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
573 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
575 unsigned int x, y, z;
577 for (z = 0; z < depth; z++)
579 for (y = 0; y < height; ++y)
581 const DWORD *source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
582 DWORD *dest = (DWORD *)(dst + z * dst_slice_pitch + y * dst_row_pitch);
584 for (x = 0; x < width; ++x)
586 /* Just need to clear out the X4 part. */
587 dest[x] = source[x] & ~0xf0;
593 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
594 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
596 unsigned int x, y, z;
598 for (z = 0; z < depth; z++)
600 for (y = 0; y < height; ++y)
602 const DWORD *source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
603 float *dest_f = (float *)(dst + z * dst_slice_pitch + y * dst_row_pitch);
604 DWORD *dest_s = (DWORD *)dest_f;
606 for (x = 0; x < width; ++x)
608 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
609 dest_s[x * 2 + 1] = source[x] & 0xff;
615 static BOOL color_in_range(const struct wined3d_color_key *color_key, DWORD color)
617 /* FIXME: Is this really how color keys are supposed to work? I think it
618 * makes more sense to compare the individual channels. */
619 return color >= color_key->color_space_low_value
620 && color <= color_key->color_space_high_value;
623 static void convert_p8_uint_b8g8r8a8_unorm(const BYTE *src, unsigned int src_pitch,
624 BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
625 const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
627 const BYTE *src_row;
628 unsigned int x, y;
629 DWORD *dst_row;
631 if (!palette)
633 /* FIXME: This should probably use the system palette. */
634 FIXME("P8 surface loaded without a palette.\n");
636 for (y = 0; y < height; ++y)
638 memset(&dst[dst_pitch * y], 0, width * 4);
641 return;
644 for (y = 0; y < height; ++y)
646 src_row = &src[src_pitch * y];
647 dst_row = (DWORD *)&dst[dst_pitch * y];
648 for (x = 0; x < width; ++x)
650 BYTE src_color = src_row[x];
651 dst_row[x] = 0xff000000
652 | (palette->colors[src_color].rgbRed << 16)
653 | (palette->colors[src_color].rgbGreen << 8)
654 | palette->colors[src_color].rgbBlue;
659 static void convert_b5g6r5_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, unsigned int src_pitch,
660 BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
661 const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
663 const WORD *src_row;
664 unsigned int x, y;
665 WORD *dst_row;
667 for (y = 0; y < height; ++y)
669 src_row = (WORD *)&src[src_pitch * y];
670 dst_row = (WORD *)&dst[dst_pitch * y];
671 for (x = 0; x < width; ++x)
673 WORD src_color = src_row[x];
674 if (!color_in_range(color_key, src_color))
675 dst_row[x] = 0x8000 | ((src_color & 0xffc0) >> 1) | (src_color & 0x1f);
676 else
677 dst_row[x] = ((src_color & 0xffc0) >> 1) | (src_color & 0x1f);
682 static void convert_b5g5r5x1_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, unsigned int src_pitch,
683 BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
684 const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
686 const WORD *src_row;
687 unsigned int x, y;
688 WORD *dst_row;
690 for (y = 0; y < height; ++y)
692 src_row = (WORD *)&src[src_pitch * y];
693 dst_row = (WORD *)&dst[dst_pitch * y];
694 for (x = 0; x < width; ++x)
696 WORD src_color = src_row[x];
697 if (color_in_range(color_key, src_color))
698 dst_row[x] = src_color & ~0x8000;
699 else
700 dst_row[x] = src_color | 0x8000;
705 static void convert_b8g8r8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch,
706 BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
707 const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
709 const BYTE *src_row;
710 unsigned int x, y;
711 DWORD *dst_row;
713 for (y = 0; y < height; ++y)
715 src_row = &src[src_pitch * y];
716 dst_row = (DWORD *)&dst[dst_pitch * y];
717 for (x = 0; x < width; ++x)
719 DWORD src_color = (src_row[x * 3 + 2] << 16) | (src_row[x * 3 + 1] << 8) | src_row[x * 3];
720 if (!color_in_range(color_key, src_color))
721 dst_row[x] = src_color | 0xff000000;
726 static void convert_b8g8r8x8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch,
727 BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
728 const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
730 const DWORD *src_row;
731 unsigned int x, y;
732 DWORD *dst_row;
734 for (y = 0; y < height; ++y)
736 src_row = (DWORD *)&src[src_pitch * y];
737 dst_row = (DWORD *)&dst[dst_pitch * y];
738 for (x = 0; x < width; ++x)
740 DWORD src_color = src_row[x];
741 if (color_in_range(color_key, src_color))
742 dst_row[x] = src_color & ~0xff000000;
743 else
744 dst_row[x] = src_color | 0xff000000;
749 static void convert_b8g8r8a8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch,
750 BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
751 const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
753 const DWORD *src_row;
754 unsigned int x, y;
755 DWORD *dst_row;
757 for (y = 0; y < height; ++y)
759 src_row = (DWORD *)&src[src_pitch * y];
760 dst_row = (DWORD *)&dst[dst_pitch * y];
761 for (x = 0; x < width; ++x)
763 DWORD src_color = src_row[x];
764 if (color_in_range(color_key, src_color))
765 src_color &= ~0xff000000;
766 dst_row[x] = src_color;
771 const struct wined3d_color_key_conversion * wined3d_format_get_color_key_conversion(
772 const struct wined3d_texture *texture, BOOL need_alpha_ck)
774 const struct wined3d_format *format = texture->resource.format;
775 unsigned int i;
777 static const struct
779 enum wined3d_format_id src_format;
780 struct wined3d_color_key_conversion conversion;
782 color_key_info[] =
784 {WINED3DFMT_B5G6R5_UNORM, {WINED3DFMT_B5G5R5A1_UNORM, convert_b5g6r5_unorm_b5g5r5a1_unorm_color_key }},
785 {WINED3DFMT_B5G5R5X1_UNORM, {WINED3DFMT_B5G5R5A1_UNORM, convert_b5g5r5x1_unorm_b5g5r5a1_unorm_color_key }},
786 {WINED3DFMT_B8G8R8_UNORM, {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8_unorm_b8g8r8a8_unorm_color_key }},
787 {WINED3DFMT_B8G8R8X8_UNORM, {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8x8_unorm_b8g8r8a8_unorm_color_key }},
788 {WINED3DFMT_B8G8R8A8_UNORM, {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8a8_unorm_b8g8r8a8_unorm_color_key }},
790 static const struct wined3d_color_key_conversion convert_p8 =
792 WINED3DFMT_B8G8R8A8_UNORM, convert_p8_uint_b8g8r8a8_unorm
795 if (need_alpha_ck && (texture->color_key_flags & WINEDDSD_CKSRCBLT))
797 for (i = 0; i < sizeof(color_key_info) / sizeof(*color_key_info); ++i)
799 if (color_key_info[i].src_format == format->id)
800 return &color_key_info[i].conversion;
803 FIXME("Color-keying not supported with format %s.\n", debug_d3dformat(format->id));
806 /* FIXME: This should check if the blitter backend can do P8 conversion,
807 * instead of checking for ARB_fragment_program. */
808 if (format->id == WINED3DFMT_P8_UINT
809 && !(texture->resource.device->adapter->gl_info.supported[ARB_FRAGMENT_PROGRAM]
810 && texture->swapchain && texture == texture->swapchain->front_buffer))
811 return &convert_p8;
813 return NULL;
816 /* The following formats explicitly don't have WINED3DFMT_FLAG_TEXTURE set:
818 * These are never supported on native.
819 * WINED3DFMT_B8G8R8_UNORM
820 * WINED3DFMT_B2G3R3_UNORM
821 * WINED3DFMT_L4A4_UNORM
822 * WINED3DFMT_S1_UINT_D15_UNORM
823 * WINED3DFMT_S4X4_UINT_D24_UNORM
825 * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of ddraw.
826 * Since it is not widely available, don't offer it. Further no Windows driver
827 * offers WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either.
828 * WINED3DFMT_P8_UINT
829 * WINED3DFMT_P8_UINT_A8_UNORM
831 * These formats seem to be similar to the HILO formats in
832 * GL_NV_texture_shader. NVHU is said to be GL_UNSIGNED_HILO16,
833 * NVHS GL_SIGNED_HILO16. Rumours say that D3D computes a 3rd channel
834 * similarly to D3DFMT_CxV8U8 (So NVHS could be called D3DFMT_CxV16U16). ATI
835 * refused to support formats which can easily be emulated with pixel shaders,
836 * so applications have to deal with not having NVHS and NVHU.
837 * WINED3DFMT_NVHU
838 * WINED3DFMT_NVHS */
839 static const struct wined3d_format_texture_info format_texture_info[] =
841 /* format id gl_internal gl_srgb_internal gl_rt_internal
842 gl_format gl_type conv_byte_count
843 flags
844 extension convert */
845 /* FourCC formats */
846 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
847 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
848 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
849 * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
850 * endian machine
852 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
853 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
854 WINED3DFMT_FLAG_FILTERING,
855 WINED3D_GL_EXT_NONE, NULL},
856 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
857 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 0,
858 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
859 APPLE_YCBCR_422, NULL},
860 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
861 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
862 WINED3DFMT_FLAG_FILTERING,
863 WINED3D_GL_EXT_NONE, NULL},
864 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
865 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, 0,
866 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
867 APPLE_YCBCR_422, NULL},
868 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
869 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
870 WINED3DFMT_FLAG_FILTERING,
871 WINED3D_GL_EXT_NONE, NULL},
872 {WINED3DFMT_NV12, GL_ALPHA, GL_ALPHA, 0,
873 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
874 WINED3DFMT_FLAG_FILTERING,
875 WINED3D_GL_EXT_NONE, NULL},
876 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
877 GL_RGBA, GL_UNSIGNED_BYTE, 0,
878 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
879 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
880 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
881 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
882 GL_RGBA, GL_UNSIGNED_BYTE, 0,
883 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
884 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
885 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
886 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
887 GL_RGBA, GL_UNSIGNED_BYTE, 0,
888 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
889 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
890 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
891 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
892 GL_RGBA, GL_UNSIGNED_BYTE, 0,
893 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
894 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
895 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
896 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
897 GL_RGBA, GL_UNSIGNED_BYTE, 0,
898 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
899 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
900 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
901 /* IEEE formats */
902 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
903 GL_RED, GL_FLOAT, 0,
904 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
905 ARB_TEXTURE_FLOAT, NULL},
906 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
907 GL_RED, GL_FLOAT, 0,
908 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
909 ARB_TEXTURE_RG, NULL},
910 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
911 GL_RGB, GL_FLOAT, 12,
912 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
913 ARB_TEXTURE_FLOAT, convert_r32g32_float},
914 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
915 GL_RG, GL_FLOAT, 0,
916 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
917 ARB_TEXTURE_RG, NULL},
918 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
919 GL_RGBA, GL_FLOAT, 0,
920 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
921 ARB_TEXTURE_FLOAT, NULL},
922 /* Float */
923 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
924 GL_RED, GL_HALF_FLOAT_ARB, 0,
925 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
926 ARB_TEXTURE_FLOAT, NULL},
927 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
928 GL_RED, GL_HALF_FLOAT_ARB, 0,
929 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
930 ARB_TEXTURE_RG, NULL},
931 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
932 GL_RGB, GL_HALF_FLOAT_ARB, 6,
933 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
934 ARB_TEXTURE_FLOAT, convert_r16g16},
935 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
936 GL_RG, GL_HALF_FLOAT_ARB, 0,
937 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
938 ARB_TEXTURE_RG, NULL},
939 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
940 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
941 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET
942 | WINED3DFMT_FLAG_VTF,
943 ARB_TEXTURE_FLOAT, NULL},
944 /* Palettized formats */
945 {WINED3DFMT_P8_UINT, GL_ALPHA8, GL_ALPHA8, 0,
946 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
948 0, NULL},
949 /* Standard ARGB formats */
950 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
951 GL_BGR, GL_UNSIGNED_BYTE, 0,
952 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
953 WINED3D_GL_EXT_NONE, NULL},
954 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
955 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
956 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
957 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE
958 | WINED3DFMT_FLAG_VTF,
959 WINED3D_GL_EXT_NONE, NULL},
960 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
961 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
962 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
963 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
964 WINED3D_GL_EXT_NONE, NULL},
965 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
966 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
967 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
968 | WINED3DFMT_FLAG_RENDERTARGET,
969 WINED3D_GL_EXT_NONE, NULL},
970 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
971 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
972 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
973 WINED3D_GL_EXT_NONE, NULL},
974 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
975 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
976 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
977 WINED3D_GL_EXT_NONE, NULL},
978 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
979 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
980 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
981 | WINED3DFMT_FLAG_SRGB_READ,
982 WINED3D_GL_EXT_NONE, NULL},
983 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
984 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
985 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
986 WINED3D_GL_EXT_NONE, NULL},
987 {WINED3DFMT_R8_UNORM, GL_R8, GL_R8, 0,
988 GL_RED, GL_UNSIGNED_BYTE, 0,
989 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
990 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
991 ARB_TEXTURE_RG, NULL},
992 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
993 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
994 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
995 WINED3D_GL_EXT_NONE, NULL},
996 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
997 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
998 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
999 WINED3D_GL_EXT_NONE, NULL},
1000 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
1001 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
1002 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1003 | WINED3DFMT_FLAG_RENDERTARGET,
1004 WINED3D_GL_EXT_NONE, NULL},
1005 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
1006 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
1007 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1008 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE
1009 | WINED3DFMT_FLAG_VTF,
1010 WINED3D_GL_EXT_NONE, NULL},
1011 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
1012 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
1013 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
1014 WINED3D_GL_EXT_NONE, NULL},
1015 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
1016 GL_RGB, GL_UNSIGNED_SHORT, 6,
1017 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
1018 WINED3D_GL_EXT_NONE, convert_r16g16},
1019 {WINED3DFMT_R16G16_UNORM, GL_RG16, GL_RG16, 0,
1020 GL_RG, GL_UNSIGNED_SHORT, 0,
1021 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1022 | WINED3DFMT_FLAG_RENDERTARGET,
1023 ARB_TEXTURE_RG, NULL},
1024 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
1025 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
1026 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1027 | WINED3DFMT_FLAG_RENDERTARGET,
1028 WINED3D_GL_EXT_NONE, NULL},
1029 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
1030 GL_RGBA, GL_UNSIGNED_SHORT, 0,
1031 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1032 | WINED3DFMT_FLAG_RENDERTARGET,
1033 WINED3D_GL_EXT_NONE, NULL},
1034 /* Luminance */
1035 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
1036 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
1037 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1038 | WINED3DFMT_FLAG_SRGB_READ,
1039 WINED3D_GL_EXT_NONE, NULL},
1040 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
1041 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
1042 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1043 | WINED3DFMT_FLAG_SRGB_READ,
1044 WINED3D_GL_EXT_NONE, NULL},
1045 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
1046 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
1047 WINED3DFMT_FLAG_FILTERING,
1048 WINED3D_GL_EXT_NONE, convert_l4a4_unorm},
1049 /* Bump mapping stuff */
1050 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
1051 GL_BGR, GL_UNSIGNED_BYTE, 3,
1052 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1053 | WINED3DFMT_FLAG_BUMPMAP,
1054 WINED3D_GL_EXT_NONE, convert_r8g8_snorm},
1055 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
1056 GL_DSDT_NV, GL_BYTE, 0,
1057 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1058 | WINED3DFMT_FLAG_BUMPMAP,
1059 NV_TEXTURE_SHADER, NULL},
1060 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
1061 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
1062 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1063 | WINED3DFMT_FLAG_BUMPMAP,
1064 WINED3D_GL_EXT_NONE, convert_r5g5_snorm_l6_unorm},
1065 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
1066 GL_DSDT_MAG_NV, GL_BYTE, 3,
1067 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1068 | WINED3DFMT_FLAG_BUMPMAP,
1069 NV_TEXTURE_SHADER, convert_r5g5_snorm_l6_unorm_nv},
1070 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
1071 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
1072 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1073 | WINED3DFMT_FLAG_BUMPMAP,
1074 WINED3D_GL_EXT_NONE, convert_r8g8_snorm_l8x8_unorm},
1075 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
1076 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
1077 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1078 | WINED3DFMT_FLAG_BUMPMAP,
1079 NV_TEXTURE_SHADER, convert_r8g8_snorm_l8x8_unorm_nv},
1080 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
1081 GL_BGRA, GL_UNSIGNED_BYTE, 4,
1082 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1083 | WINED3DFMT_FLAG_BUMPMAP,
1084 WINED3D_GL_EXT_NONE, convert_r8g8b8a8_snorm},
1085 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
1086 GL_RGBA, GL_BYTE, 0,
1087 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1088 | WINED3DFMT_FLAG_BUMPMAP,
1089 NV_TEXTURE_SHADER, NULL},
1090 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
1091 GL_BGR, GL_UNSIGNED_SHORT, 6,
1092 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1093 | WINED3DFMT_FLAG_BUMPMAP,
1094 WINED3D_GL_EXT_NONE, convert_r16g16_snorm},
1095 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
1096 GL_HILO_NV, GL_SHORT, 0,
1097 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1098 | WINED3DFMT_FLAG_BUMPMAP,
1099 NV_TEXTURE_SHADER, NULL},
1100 /* Depth stencil formats */
1101 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0,
1102 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
1103 WINED3DFMT_FLAG_DEPTH,
1104 WINED3D_GL_EXT_NONE, NULL},
1105 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
1106 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
1107 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
1108 ARB_DEPTH_TEXTURE, NULL},
1109 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0,
1110 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
1111 WINED3DFMT_FLAG_DEPTH,
1112 WINED3D_GL_EXT_NONE, NULL},
1113 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
1114 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
1115 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
1116 ARB_DEPTH_TEXTURE, NULL},
1117 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
1118 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
1119 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
1120 ARB_DEPTH_TEXTURE, NULL},
1121 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
1122 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
1123 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
1124 EXT_PACKED_DEPTH_STENCIL, convert_s1_uint_d15_unorm},
1125 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
1126 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
1127 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
1128 ARB_FRAMEBUFFER_OBJECT, convert_s1_uint_d15_unorm},
1129 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
1130 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
1131 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1132 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
1133 ARB_DEPTH_TEXTURE, NULL},
1134 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
1135 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
1136 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1137 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
1138 EXT_PACKED_DEPTH_STENCIL, NULL},
1139 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
1140 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
1141 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1142 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
1143 ARB_FRAMEBUFFER_OBJECT, NULL},
1144 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0,
1145 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
1146 WINED3DFMT_FLAG_DEPTH,
1147 WINED3D_GL_EXT_NONE, NULL},
1148 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
1149 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
1150 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1151 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
1152 ARB_DEPTH_TEXTURE, NULL},
1153 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
1154 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
1155 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
1156 ARB_DEPTH_TEXTURE, NULL},
1157 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
1158 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
1159 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
1160 EXT_PACKED_DEPTH_STENCIL, convert_s4x4_uint_d24_unorm},
1161 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
1162 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
1163 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
1164 ARB_FRAMEBUFFER_OBJECT, convert_s4x4_uint_d24_unorm},
1165 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0,
1166 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
1167 WINED3DFMT_FLAG_DEPTH,
1168 WINED3D_GL_EXT_NONE, NULL},
1169 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
1170 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
1171 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1172 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
1173 ARB_DEPTH_TEXTURE, NULL},
1174 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
1175 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
1176 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
1177 WINED3D_GL_EXT_NONE, NULL},
1178 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
1179 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
1180 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
1181 ARB_DEPTH_BUFFER_FLOAT, NULL},
1182 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
1183 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
1184 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
1185 ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float},
1186 /* Vendor-specific formats */
1187 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
1188 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
1189 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1190 | WINED3DFMT_FLAG_COMPRESSED,
1191 ATI_TEXTURE_COMPRESSION_3DC, NULL},
1192 {WINED3DFMT_ATI2N, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0,
1193 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
1194 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1195 | WINED3DFMT_FLAG_COMPRESSED,
1196 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
1197 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
1198 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
1199 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1200 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
1201 EXT_PACKED_DEPTH_STENCIL, NULL},
1202 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
1203 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
1204 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1205 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
1206 ARB_FRAMEBUFFER_OBJECT, NULL},
1207 {WINED3DFMT_NULL, 0, 0, 0,
1208 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
1209 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET,
1210 ARB_FRAMEBUFFER_OBJECT, NULL},
1213 static inline int getFmtIdx(enum wined3d_format_id format_id)
1215 /* First check if the format is at the position of its value.
1216 * This will catch the argb formats before the loop is entered. */
1217 if (format_id < (sizeof(formats) / sizeof(*formats))
1218 && formats[format_id].id == format_id)
1220 return format_id;
1222 else
1224 unsigned int i;
1226 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
1228 if (formats[i].id == format_id) return i;
1231 return -1;
1234 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
1236 UINT format_count = sizeof(formats) / sizeof(*formats);
1237 UINT i;
1239 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
1240 if (!gl_info->formats)
1242 ERR("Failed to allocate memory.\n");
1243 return FALSE;
1246 for (i = 0; i < format_count; ++i)
1248 struct wined3d_format *format = &gl_info->formats[i];
1249 format->id = formats[i].id;
1250 format->red_size = formats[i].red_size;
1251 format->green_size = formats[i].green_size;
1252 format->blue_size = formats[i].blue_size;
1253 format->alpha_size = formats[i].alpha_size;
1254 format->red_offset = formats[i].red_offset;
1255 format->green_offset = formats[i].green_offset;
1256 format->blue_offset = formats[i].blue_offset;
1257 format->alpha_offset = formats[i].alpha_offset;
1258 format->byte_count = formats[i].bpp;
1259 format->depth_size = formats[i].depth_size;
1260 format->stencil_size = formats[i].stencil_size;
1261 format->block_width = 1;
1262 format->block_height = 1;
1263 format->block_byte_count = formats[i].bpp;
1266 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
1268 int fmt_idx = getFmtIdx(format_base_flags[i].id);
1270 if (fmt_idx == -1)
1272 ERR("Format %s (%#x) not found.\n",
1273 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
1274 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1275 return FALSE;
1278 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
1281 return TRUE;
1284 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
1286 unsigned int i;
1288 for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i)
1290 struct wined3d_format *format;
1291 int fmt_idx = getFmtIdx(format_block_info[i].id);
1293 if (fmt_idx == -1)
1295 ERR("Format %s (%#x) not found.\n",
1296 debug_d3dformat(format_block_info[i].id), format_block_info[i].id);
1297 return FALSE;
1300 format = &gl_info->formats[fmt_idx];
1301 format->block_width = format_block_info[i].block_width;
1302 format->block_height = format_block_info[i].block_height;
1303 format->block_byte_count = format_block_info[i].block_byte_count;
1304 format->flags |= WINED3DFMT_FLAG_BLOCKS;
1305 if (!format_block_info[i].verify)
1306 format->flags |= WINED3DFMT_FLAG_BLOCKS_NO_VERIFY;
1309 return TRUE;
1312 /* Context activation is done by the caller. */
1313 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
1315 /* Check if the default internal format is supported as a frame buffer
1316 * target, otherwise fall back to the render target internal.
1318 * Try to stick to the standard format if possible, this limits precision differences. */
1319 GLenum status;
1320 GLuint tex;
1322 while (gl_info->gl_ops.gl.p_glGetError());
1323 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1325 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1326 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1328 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0,
1329 format->glFormat, format->glType, NULL);
1330 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1331 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1333 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1335 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1336 checkGLcall("Framebuffer format check");
1338 if (status == GL_FRAMEBUFFER_COMPLETE)
1340 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1341 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1342 format->rtInternal = format->glInternal;
1344 else
1346 if (!format->rtInternal)
1348 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1350 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1351 " and no fallback specified.\n", debug_d3dformat(format->id));
1352 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1354 else
1356 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1358 format->rtInternal = format->glInternal;
1360 else
1362 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1363 debug_d3dformat(format->id));
1365 while (gl_info->gl_ops.gl.p_glGetError());
1367 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1369 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0,
1370 format->glFormat, format->glType, NULL);
1371 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1372 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1374 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1376 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1377 checkGLcall("Framebuffer format check");
1379 if (status == GL_FRAMEBUFFER_COMPLETE)
1381 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1382 debug_d3dformat(format->id));
1384 else
1386 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1387 debug_d3dformat(format->id));
1388 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1393 if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1394 || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1395 && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
1396 && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA
1397 && (format->red_size || format->alpha_size))
1399 DWORD readback[16 * 16], color, r_range, a_range;
1400 BYTE r, a;
1401 BOOL match = TRUE;
1402 GLuint rb;
1404 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1405 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1407 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1408 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1409 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1410 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1411 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1412 checkGLcall("RB attachment");
1415 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1416 gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1417 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1418 if (gl_info->gl_ops.gl.p_glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1420 while (gl_info->gl_ops.gl.p_glGetError());
1421 TRACE("Format doesn't support post-pixelshader blending.\n");
1422 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1424 else
1426 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1427 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16);
1428 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1429 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1430 gl_info->gl_ops.gl.p_glLoadIdentity();
1431 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1432 gl_info->gl_ops.gl.p_glLoadIdentity();
1434 gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1436 /* Draw a full-black quad */
1437 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1438 gl_info->gl_ops.gl.p_glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
1439 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1440 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1441 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1442 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1443 gl_info->gl_ops.gl.p_glEnd();
1445 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1446 /* Draw a half-transparent red quad */
1447 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1448 gl_info->gl_ops.gl.p_glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
1449 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1450 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1451 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1452 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1453 gl_info->gl_ops.gl.p_glEnd();
1455 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1457 /* Rebinding texture to workaround a fglrx bug. */
1458 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1459 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1460 checkGLcall("Post-pixelshader blending check");
1462 color = readback[7 * 16 + 7];
1463 a = color >> 24;
1464 r = (color & 0x00ff0000) >> 16;
1466 r_range = format->red_size < 8 ? 1 << (8 - format->red_size) : 1;
1467 a_range = format->alpha_size < 8 ? 1 << (8 - format->alpha_size) : 1;
1468 if (format->red_size && (r < 0x7f - r_range || r > 0x7f + r_range))
1469 match = FALSE;
1470 else if (format->alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range))
1471 match = FALSE;
1472 if (!match)
1474 TRACE("Format doesn't support post-pixelshader blending.\n");
1475 TRACE("Color output: %#x\n", color);
1476 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1478 else
1480 TRACE("Format supports post-pixelshader blending.\n");
1481 TRACE("Color output: %#x\n", color);
1482 format->flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1486 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1487 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1489 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1490 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1491 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1492 checkGLcall("RB cleanup");
1496 if (format->glInternal != format->glGammaInternal)
1498 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0,
1499 format->glFormat, format->glType, NULL);
1500 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1502 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1503 checkGLcall("Framebuffer format check");
1505 if (status == GL_FRAMEBUFFER_COMPLETE)
1507 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1508 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1510 else
1512 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1515 else if (status == GL_FRAMEBUFFER_COMPLETE)
1516 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1518 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1521 static void query_format_flag(struct wined3d_gl_info *gl_info, struct wined3d_format *format,
1522 GLint internal, GLenum pname, DWORD flag, const char *string)
1524 GLint value;
1526 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, internal, pname, 1, &value);
1527 if (value == GL_FULL_SUPPORT)
1529 TRACE("Format %s supports %s.\n", debug_d3dformat(format->id), string);
1530 format->flags |= flag;
1532 else
1534 TRACE("Format %s doesn't support %s.\n", debug_d3dformat(format->id), string);
1535 format->flags &= ~flag;
1539 /* Context activation is done by the caller. */
1540 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1542 unsigned int i;
1543 GLuint fbo;
1545 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
1547 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1549 GLint value;
1550 struct wined3d_format *format = &gl_info->formats[i];
1552 if (!format->glInternal)
1553 continue;
1554 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1555 continue;
1557 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->glInternal,
1558 GL_FRAMEBUFFER_RENDERABLE, 1, &value);
1559 if (value == GL_FULL_SUPPORT)
1561 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1562 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1563 format->rtInternal = format->glInternal;
1565 query_format_flag(gl_info, format, format->glInternal, GL_FRAMEBUFFER_BLEND,
1566 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING, "post-pixelshader blending");
1568 else
1570 if (!format->rtInternal)
1572 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1574 WARN("Format %s with rendertarget flag is not supported as FBO color attachment"
1575 " and no fallback specified.\n", debug_d3dformat(format->id));
1576 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1578 else
1579 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1580 format->rtInternal = format->glInternal;
1582 else
1584 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->rtInternal,
1585 GL_FRAMEBUFFER_RENDERABLE, 1, &value);
1586 if (value == GL_FULL_SUPPORT)
1588 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1589 debug_d3dformat(format->id));
1591 else
1593 WARN("Format %s rtInternal format is not supported as FBO color attachment.\n",
1594 debug_d3dformat(format->id));
1595 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1600 if (format->glInternal != format->glGammaInternal)
1602 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->glGammaInternal,
1603 GL_FRAMEBUFFER_RENDERABLE, 1, &value);
1604 if (value == GL_FULL_SUPPORT)
1606 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1607 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1609 else
1611 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1614 else if (format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)
1615 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1617 return;
1620 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1622 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1623 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1624 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1625 gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0);
1628 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1630 struct wined3d_format *format = &gl_info->formats[i];
1632 if (!format->glInternal) continue;
1634 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1636 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1637 debug_d3dformat(format->id));
1638 continue;
1641 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1643 TRACE("Skipping format %s because it's a compressed format.\n",
1644 debug_d3dformat(format->id));
1645 continue;
1648 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1650 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1651 check_fbo_compat(gl_info, format);
1653 else
1655 format->rtInternal = format->glInternal;
1659 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1660 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1663 static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1665 struct fragment_caps fragment_caps;
1666 struct shader_caps shader_caps;
1667 BOOL srgb_write;
1668 unsigned int i;
1670 adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
1671 adapter->shader_backend->shader_get_caps(gl_info, &shader_caps);
1672 srgb_write = (fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_SRGB_WRITE)
1673 && (shader_caps.wined3d_caps & WINED3D_SHADER_CAP_SRGB_WRITE);
1675 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1677 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1678 struct wined3d_format *format;
1680 if (fmt_idx == -1)
1682 ERR("Format %s (%#x) not found.\n",
1683 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1684 return FALSE;
1687 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1689 format = &gl_info->formats[fmt_idx];
1691 /* ARB_texture_rg defines floating point formats, but only if
1692 * ARB_texture_float is also supported. */
1693 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1694 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1695 continue;
1697 format->glInternal = format_texture_info[i].gl_internal;
1698 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1699 format->rtInternal = format_texture_info[i].gl_rt_internal;
1700 format->glFormat = format_texture_info[i].gl_format;
1701 format->glType = format_texture_info[i].gl_type;
1702 format->color_fixup = COLOR_FIXUP_IDENTITY;
1703 format->flags |= format_texture_info[i].flags;
1704 format->height_scale.numerator = 1;
1705 format->height_scale.denominator = 1;
1707 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
1709 query_format_flag(gl_info, format, format->glInternal, GL_VERTEX_TEXTURE,
1710 WINED3DFMT_FLAG_VTF, "vertex texture usage");
1711 query_format_flag(gl_info, format, format->glInternal, GL_FILTER,
1712 WINED3DFMT_FLAG_FILTERING, "filtering");
1714 if (format->glGammaInternal != format->glInternal)
1716 query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_READ,
1717 WINED3DFMT_FLAG_SRGB_READ, "sRGB read");
1719 if (srgb_write)
1720 query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_WRITE,
1721 WINED3DFMT_FLAG_SRGB_WRITE, "sRGB write");
1722 else
1723 format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
1725 if (!(format->flags & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE)))
1726 format->glGammaInternal = format->glInternal;
1727 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1728 format->glInternal = format->glGammaInternal;
1731 else
1733 if (!gl_info->limits.vertex_samplers)
1734 format->flags &= ~WINED3DFMT_FLAG_VTF;
1736 if (!(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1737 format->flags |= WINED3DFMT_FLAG_FILTERING;
1738 else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT)
1739 format->flags &= ~WINED3DFMT_FLAG_VTF;
1741 if (format->glGammaInternal != format->glInternal)
1743 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1744 if (!gl_info->supported[EXT_TEXTURE_SRGB])
1746 format->glGammaInternal = format->glInternal;
1747 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1749 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1751 format->glInternal = format->glGammaInternal;
1755 if ((format->flags & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write)
1756 format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
1759 /* Texture conversion stuff */
1760 format->convert = format_texture_info[i].convert;
1761 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1764 return TRUE;
1767 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1769 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1770 c1 >>= 8; c2 >>= 8;
1771 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1772 c1 >>= 8; c2 >>= 8;
1773 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1774 c1 >>= 8; c2 >>= 8;
1775 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1776 return TRUE;
1779 /* A context is provided by the caller */
1780 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1782 static const DWORD data[] = {0x00000000, 0xffffffff};
1783 GLuint tex, fbo, buffer;
1784 DWORD readback[16 * 1];
1785 BOOL ret = FALSE;
1787 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1788 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1789 * falling back to software. If this changes in the future this code will get fooled and
1790 * apps might hit the software path due to incorrectly advertised caps.
1792 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1793 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1794 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1797 while (gl_info->gl_ops.gl.p_glGetError());
1799 gl_info->gl_ops.gl.p_glGenTextures(1, &buffer);
1800 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1801 memset(readback, 0x7e, sizeof(readback));
1802 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0,
1803 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1804 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1805 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1806 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1807 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1808 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1810 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1811 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1812 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0,
1813 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1814 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1815 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1816 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1817 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1818 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1819 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
1821 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1822 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1823 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1824 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1826 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1);
1827 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1828 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1829 gl_info->gl_ops.gl.p_glLoadIdentity();
1830 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1831 gl_info->gl_ops.gl.p_glLoadIdentity();
1833 gl_info->gl_ops.gl.p_glClearColor(0, 1, 0, 0);
1834 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1836 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1837 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 0.0);
1838 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, -1.0f);
1839 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 0.0);
1840 gl_info->gl_ops.gl.p_glVertex2f(1.0f, -1.0f);
1841 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 1.0);
1842 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, 1.0f);
1843 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 1.0);
1844 gl_info->gl_ops.gl.p_glVertex2f(1.0f, 1.0f);
1845 gl_info->gl_ops.gl.p_glEnd();
1847 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1848 memset(readback, 0x7f, sizeof(readback));
1849 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1850 if (color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5)
1851 || color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1853 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, assuming no filtering\n",
1854 readback[6], readback[9]);
1855 ret = FALSE;
1857 else
1859 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1860 readback[6], readback[9]);
1861 ret = TRUE;
1864 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1865 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1866 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1867 gl_info->gl_ops.gl.p_glDeleteTextures(1, &buffer);
1869 if (gl_info->gl_ops.gl.p_glGetError())
1871 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1872 ret = FALSE;
1875 return ret;
1878 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1880 struct wined3d_format *format;
1881 unsigned int fmt_idx, i;
1882 static const enum wined3d_format_id fmts16[] =
1884 WINED3DFMT_R16_FLOAT,
1885 WINED3DFMT_R16G16_FLOAT,
1886 WINED3DFMT_R16G16B16A16_FLOAT,
1888 BOOL filtered;
1890 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
1891 /* This was already handled by init_format_texture_info(). */
1892 return;
1894 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1896 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1897 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1899 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1900 filtered = TRUE;
1902 else if (gl_info->limits.glsl_varyings > 44)
1904 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1905 filtered = TRUE;
1907 else
1909 TRACE("Assuming no float16 blending\n");
1910 filtered = FALSE;
1913 if(filtered)
1915 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1917 fmt_idx = getFmtIdx(fmts16[i]);
1918 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1921 return;
1924 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1926 fmt_idx = getFmtIdx(fmts16[i]);
1927 format = &gl_info->formats[fmt_idx];
1928 if (!format->glInternal) continue; /* Not supported by GL */
1930 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1931 if(filtered)
1933 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1934 format->flags |= WINED3DFMT_FLAG_FILTERING;
1936 else
1938 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1943 static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1945 unsigned int i;
1946 int idx;
1948 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1949 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1950 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1952 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1953 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1954 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1956 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1957 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1958 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1960 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1961 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1962 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1964 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1965 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1966 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1968 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1969 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1970 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1971 * the only driver that implements it(fglrx) has a buggy implementation.
1973 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1974 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1975 * conversion for this format.
1977 if (!gl_info->supported[NV_TEXTURE_SHADER])
1979 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1980 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1981 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1982 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1983 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1984 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1986 else
1988 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1989 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1990 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1992 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1993 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1994 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1997 if (!gl_info->supported[NV_TEXTURE_SHADER])
1999 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
2000 * with each other
2002 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
2003 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
2004 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
2005 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
2006 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
2007 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
2008 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
2009 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
2010 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
2012 else
2014 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
2015 * are converted at surface loading time, but they do not need any modification in
2016 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
2017 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
2021 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
2023 idx = getFmtIdx(WINED3DFMT_ATI2N);
2024 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
2025 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
2027 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
2029 idx = getFmtIdx(WINED3DFMT_ATI2N);
2030 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
2031 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
2034 if (!gl_info->supported[APPLE_YCBCR_422])
2036 idx = getFmtIdx(WINED3DFMT_YUY2);
2037 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
2039 idx = getFmtIdx(WINED3DFMT_UYVY);
2040 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
2043 idx = getFmtIdx(WINED3DFMT_YV12);
2044 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
2045 gl_info->formats[idx].height_scale.numerator = 3;
2046 gl_info->formats[idx].height_scale.denominator = 2;
2047 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
2049 idx = getFmtIdx(WINED3DFMT_NV12);
2050 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
2051 gl_info->formats[idx].height_scale.numerator = 3;
2052 gl_info->formats[idx].height_scale.denominator = 2;
2053 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_NV12);
2055 if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
2057 idx = getFmtIdx(WINED3DFMT_P8_UINT);
2058 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
2061 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
2063 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
2064 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
2067 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
2069 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
2070 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
2071 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
2072 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
2074 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
2075 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
2078 if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
2080 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
2081 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
2083 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
2084 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
2086 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
2087 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
2090 if (gl_info->quirks & WINED3D_QUIRK_BROKEN_RGBA16)
2092 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_UNORM);
2093 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
2096 /* ATI instancing hack: Although ATI cards do not support Shader Model
2097 * 3.0, they support instancing. To query if the card supports instancing
2098 * CheckDeviceFormat() with the special format MAKEFOURCC('I','N','S','T')
2099 * is used. Should an application check for this, provide a proper return
2100 * value. We can do instancing with all shader versions, but we need
2101 * vertex shaders.
2103 * Additionally applications have to set the D3DRS_POINTSIZE render state
2104 * to MAKEFOURCC('I','N','S','T') once to enable instancing. Wined3d
2105 * doesn't need that and just ignores it.
2107 * With Shader Model 3.0 capable cards Instancing 'just works' in Windows. */
2108 /* FIXME: This should just check the shader backend caps. */
2109 if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
2111 idx = getFmtIdx(WINED3DFMT_INST);
2112 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
2115 /* Depth bound test. To query if the card supports it CheckDeviceFormat()
2116 * with the special format MAKEFOURCC('N','V','D','B') is used. It is
2117 * enabled by setting D3DRS_ADAPTIVETESS_X render state to
2118 * MAKEFOURCC('N','V','D','B') and then controlled by setting
2119 * D3DRS_ADAPTIVETESS_Z (zMin) and D3DRS_ADAPTIVETESS_W (zMax) to test
2120 * value. */
2121 if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST])
2123 idx = getFmtIdx(WINED3DFMT_NVDB);
2124 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
2127 /* RESZ aka AMD DX9-level hack for multisampled depth buffer resolve. You query for RESZ
2128 * support by checking for availability of MAKEFOURCC('R','E','S','Z') surfaces with
2129 * RENDERTARGET usage. */
2130 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
2132 idx = getFmtIdx(WINED3DFMT_RESZ);
2133 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET;
2136 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
2138 struct wined3d_format *format = &gl_info->formats[i];
2140 if (!(format->flags & WINED3DFMT_FLAG_TEXTURE))
2141 continue;
2143 if (!adapter->shader_backend->shader_color_fixup_supported(format->color_fixup)
2144 || !adapter->fragment_pipe->color_fixup_supported(format->color_fixup))
2145 format->flags &= ~WINED3DFMT_FLAG_TEXTURE;
2149 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
2151 unsigned int i;
2153 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
2155 struct wined3d_format *format;
2156 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
2158 if (fmt_idx == -1)
2160 ERR("Format %s (%#x) not found.\n",
2161 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
2162 return FALSE;
2165 format = &gl_info->formats[fmt_idx];
2166 format->emit_idx = format_vertex_info[i].emit_idx;
2167 format->component_count = format_vertex_info[i].component_count;
2168 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
2169 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
2170 format->gl_normalized = format_vertex_info[i].gl_normalized;
2171 format->component_size = format_vertex_info[i].component_size;
2174 return TRUE;
2177 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
2179 if (!init_format_base_info(gl_info)) return FALSE;
2181 if (!init_format_block_info(gl_info))
2183 HeapFree(GetProcessHeap(), 0, gl_info->formats);
2184 gl_info->formats = NULL;
2185 return FALSE;
2188 return TRUE;
2191 /* Context activation is done by the caller. */
2192 BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter)
2194 struct wined3d_gl_info *gl_info = &adapter->gl_info;
2196 if (!init_format_base_info(gl_info)) return FALSE;
2198 if (!init_format_block_info(gl_info)) goto fail;
2199 if (!init_format_texture_info(adapter, gl_info)) goto fail;
2200 if (!init_format_vertex_info(gl_info)) goto fail;
2202 apply_format_fixups(adapter, gl_info);
2203 init_format_fbo_compat_info(gl_info);
2204 init_format_filter_info(gl_info, adapter->driver_info.vendor);
2206 return TRUE;
2208 fail:
2209 HeapFree(GetProcessHeap(), 0, gl_info->formats);
2210 gl_info->formats = NULL;
2211 return FALSE;
2214 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
2215 enum wined3d_format_id format_id)
2217 int idx = getFmtIdx(format_id);
2219 if (idx == -1)
2221 FIXME("Can't find format %s (%#x) in the format lookup table\n",
2222 debug_d3dformat(format_id), format_id);
2223 /* Get the caller a valid pointer */
2224 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
2227 return &gl_info->formats[idx];
2230 UINT wined3d_format_calculate_pitch(const struct wined3d_format *format, UINT width)
2232 /* For block based formats, pitch means the amount of bytes to the next
2233 * row of blocks rather than the next row of pixels. */
2234 if (format->flags & WINED3DFMT_FLAG_BLOCKS)
2235 return format->block_byte_count * ((width + format->block_width - 1) / format->block_width);
2237 return format->byte_count * width;
2240 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment,
2241 UINT width, UINT height, UINT depth)
2243 UINT pitch = wined3d_format_calculate_pitch(format, width);
2244 UINT size;
2246 if (format->id == WINED3DFMT_UNKNOWN)
2248 size = 0;
2250 else if (format->flags & WINED3DFMT_FLAG_BLOCKS)
2252 UINT row_count = (height + format->block_height - 1) / format->block_height;
2253 size = row_count * ((pitch + alignment - 1) & ~(alignment - 1));
2255 else
2257 size = height * ((pitch + alignment - 1) & ~(alignment - 1));
2260 if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
2262 /* The D3D format requirements make sure that the resulting format is an integer again */
2263 size *= format->height_scale.numerator;
2264 size /= format->height_scale.denominator;
2267 size *= depth;
2269 return size;
2272 /*****************************************************************************
2273 * Trace formatting of useful values
2275 const char *debug_d3dformat(enum wined3d_format_id format_id)
2277 switch (format_id)
2279 #define FMT_TO_STR(format_id) case format_id: return #format_id
2280 FMT_TO_STR(WINED3DFMT_UNKNOWN);
2281 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
2282 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
2283 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
2284 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
2285 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
2286 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
2287 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
2288 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
2289 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
2290 FMT_TO_STR(WINED3DFMT_P8_UINT);
2291 FMT_TO_STR(WINED3DFMT_L8_UNORM);
2292 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
2293 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
2294 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
2295 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
2296 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
2297 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
2298 FMT_TO_STR(WINED3DFMT_UYVY);
2299 FMT_TO_STR(WINED3DFMT_YUY2);
2300 FMT_TO_STR(WINED3DFMT_YV12);
2301 FMT_TO_STR(WINED3DFMT_NV12);
2302 FMT_TO_STR(WINED3DFMT_DXT1);
2303 FMT_TO_STR(WINED3DFMT_DXT2);
2304 FMT_TO_STR(WINED3DFMT_DXT3);
2305 FMT_TO_STR(WINED3DFMT_DXT4);
2306 FMT_TO_STR(WINED3DFMT_DXT5);
2307 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
2308 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
2309 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
2310 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
2311 FMT_TO_STR(WINED3DFMT_D32_UNORM);
2312 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
2313 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
2314 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
2315 FMT_TO_STR(WINED3DFMT_L16_UNORM);
2316 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
2317 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
2318 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
2319 FMT_TO_STR(WINED3DFMT_ATI2N);
2320 FMT_TO_STR(WINED3DFMT_NVDB);
2321 FMT_TO_STR(WINED3DFMT_NVHU);
2322 FMT_TO_STR(WINED3DFMT_NVHS);
2323 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
2324 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
2325 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
2326 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
2327 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
2328 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
2329 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
2330 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
2331 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
2332 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
2333 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
2334 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
2335 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
2336 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
2337 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
2338 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
2339 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
2340 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
2341 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
2342 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
2343 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
2344 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
2345 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
2346 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
2347 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
2348 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
2349 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
2350 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
2351 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
2352 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
2353 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
2354 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
2355 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
2356 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
2357 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
2358 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
2359 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
2360 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
2361 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
2362 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
2363 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
2364 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
2365 FMT_TO_STR(WINED3DFMT_R32_UINT);
2366 FMT_TO_STR(WINED3DFMT_R32_SINT);
2367 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
2368 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
2369 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
2370 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
2371 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
2372 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
2373 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
2374 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
2375 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
2376 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
2377 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
2378 FMT_TO_STR(WINED3DFMT_D16_UNORM);
2379 FMT_TO_STR(WINED3DFMT_R16_UNORM);
2380 FMT_TO_STR(WINED3DFMT_R16_UINT);
2381 FMT_TO_STR(WINED3DFMT_R16_SNORM);
2382 FMT_TO_STR(WINED3DFMT_R16_SINT);
2383 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
2384 FMT_TO_STR(WINED3DFMT_R8_UNORM);
2385 FMT_TO_STR(WINED3DFMT_R8_UINT);
2386 FMT_TO_STR(WINED3DFMT_R8_SNORM);
2387 FMT_TO_STR(WINED3DFMT_R8_SINT);
2388 FMT_TO_STR(WINED3DFMT_A8_UNORM);
2389 FMT_TO_STR(WINED3DFMT_R1_UNORM);
2390 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
2391 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
2392 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
2393 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
2394 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
2395 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
2396 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
2397 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
2398 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
2399 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
2400 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
2401 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
2402 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
2403 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
2404 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
2405 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
2406 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
2407 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
2408 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
2409 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
2410 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
2411 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
2412 FMT_TO_STR(WINED3DFMT_INTZ);
2413 FMT_TO_STR(WINED3DFMT_RESZ);
2414 FMT_TO_STR(WINED3DFMT_NULL);
2415 FMT_TO_STR(WINED3DFMT_R16);
2416 FMT_TO_STR(WINED3DFMT_AL16);
2417 #undef FMT_TO_STR
2418 default:
2420 char fourcc[5];
2421 fourcc[0] = (char)(format_id);
2422 fourcc[1] = (char)(format_id >> 8);
2423 fourcc[2] = (char)(format_id >> 16);
2424 fourcc[3] = (char)(format_id >> 24);
2425 fourcc[4] = 0;
2426 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
2427 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
2428 else
2429 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
2431 return "unrecognized";
2435 const char *debug_d3ddevicetype(enum wined3d_device_type device_type)
2437 switch (device_type)
2439 #define DEVTYPE_TO_STR(dev) case dev: return #dev
2440 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_HAL);
2441 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_REF);
2442 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_SW);
2443 #undef DEVTYPE_TO_STR
2444 default:
2445 FIXME("Unrecognized device type %#x.\n", device_type);
2446 return "unrecognized";
2450 const char *debug_d3dusage(DWORD usage)
2452 char buf[333];
2454 buf[0] = '\0';
2455 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
2456 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
2457 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
2458 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
2459 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
2460 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
2461 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
2462 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
2463 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
2464 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
2465 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
2466 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
2467 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
2468 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
2469 #undef WINED3DUSAGE_TO_STR
2470 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
2472 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2475 const char *debug_d3dusagequery(DWORD usagequery)
2477 char buf[238];
2479 buf[0] = '\0';
2480 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
2481 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
2482 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
2483 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
2484 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
2485 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
2486 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
2487 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
2488 #undef WINED3DUSAGEQUERY_TO_STR
2489 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
2491 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2494 const char *debug_d3ddeclmethod(enum wined3d_decl_method method)
2496 switch (method)
2498 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
2499 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_DEFAULT);
2500 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_U);
2501 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_V);
2502 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_CROSS_UV);
2503 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_UV);
2504 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP);
2505 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP_PRESAMPLED);
2506 #undef WINED3DDECLMETHOD_TO_STR
2507 default:
2508 FIXME("Unrecognized declaration method %#x.\n", method);
2509 return "unrecognized";
2513 const char *debug_d3ddeclusage(enum wined3d_decl_usage usage)
2515 switch (usage)
2517 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
2518 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITION);
2519 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_WEIGHT);
2520 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_INDICES);
2521 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_NORMAL);
2522 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_PSIZE);
2523 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TEXCOORD);
2524 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TANGENT);
2525 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BINORMAL);
2526 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TESS_FACTOR);
2527 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITIONT);
2528 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_COLOR);
2529 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_FOG);
2530 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_DEPTH);
2531 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_SAMPLE);
2532 #undef WINED3DDECLUSAGE_TO_STR
2533 default:
2534 FIXME("Unrecognized %u declaration usage!\n", usage);
2535 return "unrecognized";
2539 const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
2541 switch (resource_type)
2543 #define RES_TO_STR(res) case res: return #res
2544 RES_TO_STR(WINED3D_RTYPE_SURFACE);
2545 RES_TO_STR(WINED3D_RTYPE_VOLUME);
2546 RES_TO_STR(WINED3D_RTYPE_TEXTURE);
2547 RES_TO_STR(WINED3D_RTYPE_VOLUME_TEXTURE);
2548 RES_TO_STR(WINED3D_RTYPE_CUBE_TEXTURE);
2549 RES_TO_STR(WINED3D_RTYPE_BUFFER);
2550 #undef RES_TO_STR
2551 default:
2552 FIXME("Unrecognized resource type %#x.\n", resource_type);
2553 return "unrecognized";
2557 const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type)
2559 switch (primitive_type)
2561 #define PRIM_TO_STR(prim) case prim: return #prim
2562 PRIM_TO_STR(WINED3D_PT_UNDEFINED);
2563 PRIM_TO_STR(WINED3D_PT_POINTLIST);
2564 PRIM_TO_STR(WINED3D_PT_LINELIST);
2565 PRIM_TO_STR(WINED3D_PT_LINESTRIP);
2566 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST);
2567 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP);
2568 PRIM_TO_STR(WINED3D_PT_TRIANGLEFAN);
2569 PRIM_TO_STR(WINED3D_PT_LINELIST_ADJ);
2570 PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ);
2571 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ);
2572 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ);
2573 #undef PRIM_TO_STR
2574 default:
2575 FIXME("Unrecognized %u primitive type!\n", primitive_type);
2576 return "unrecognized";
2580 const char *debug_d3drenderstate(enum wined3d_render_state state)
2582 switch (state)
2584 #define D3DSTATE_TO_STR(u) case u: return #u
2585 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIAS);
2586 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREPERSPECTIVE);
2587 D3DSTATE_TO_STR(WINED3D_RS_WRAPU);
2588 D3DSTATE_TO_STR(WINED3D_RS_WRAPV);
2589 D3DSTATE_TO_STR(WINED3D_RS_ZENABLE);
2590 D3DSTATE_TO_STR(WINED3D_RS_FILLMODE);
2591 D3DSTATE_TO_STR(WINED3D_RS_SHADEMODE);
2592 D3DSTATE_TO_STR(WINED3D_RS_LINEPATTERN);
2593 D3DSTATE_TO_STR(WINED3D_RS_MONOENABLE);
2594 D3DSTATE_TO_STR(WINED3D_RS_ROP2);
2595 D3DSTATE_TO_STR(WINED3D_RS_PLANEMASK);
2596 D3DSTATE_TO_STR(WINED3D_RS_ZWRITEENABLE);
2597 D3DSTATE_TO_STR(WINED3D_RS_ALPHATESTENABLE);
2598 D3DSTATE_TO_STR(WINED3D_RS_LASTPIXEL);
2599 D3DSTATE_TO_STR(WINED3D_RS_SRCBLEND);
2600 D3DSTATE_TO_STR(WINED3D_RS_DESTBLEND);
2601 D3DSTATE_TO_STR(WINED3D_RS_CULLMODE);
2602 D3DSTATE_TO_STR(WINED3D_RS_ZFUNC);
2603 D3DSTATE_TO_STR(WINED3D_RS_ALPHAREF);
2604 D3DSTATE_TO_STR(WINED3D_RS_ALPHAFUNC);
2605 D3DSTATE_TO_STR(WINED3D_RS_DITHERENABLE);
2606 D3DSTATE_TO_STR(WINED3D_RS_ALPHABLENDENABLE);
2607 D3DSTATE_TO_STR(WINED3D_RS_FOGENABLE);
2608 D3DSTATE_TO_STR(WINED3D_RS_SPECULARENABLE);
2609 D3DSTATE_TO_STR(WINED3D_RS_ZVISIBLE);
2610 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXEL);
2611 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXELX);
2612 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEDALPHA);
2613 D3DSTATE_TO_STR(WINED3D_RS_FOGCOLOR);
2614 D3DSTATE_TO_STR(WINED3D_RS_FOGTABLEMODE);
2615 D3DSTATE_TO_STR(WINED3D_RS_FOGSTART);
2616 D3DSTATE_TO_STR(WINED3D_RS_FOGEND);
2617 D3DSTATE_TO_STR(WINED3D_RS_FOGDENSITY);
2618 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEENABLE);
2619 D3DSTATE_TO_STR(WINED3D_RS_EDGEANTIALIAS);
2620 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYENABLE);
2621 D3DSTATE_TO_STR(WINED3D_RS_MIPMAPLODBIAS);
2622 D3DSTATE_TO_STR(WINED3D_RS_RANGEFOGENABLE);
2623 D3DSTATE_TO_STR(WINED3D_RS_ANISOTROPY);
2624 D3DSTATE_TO_STR(WINED3D_RS_FLUSHBATCH);
2625 D3DSTATE_TO_STR(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT);
2626 D3DSTATE_TO_STR(WINED3D_RS_STENCILENABLE);
2627 D3DSTATE_TO_STR(WINED3D_RS_STENCILFAIL);
2628 D3DSTATE_TO_STR(WINED3D_RS_STENCILZFAIL);
2629 D3DSTATE_TO_STR(WINED3D_RS_STENCILPASS);
2630 D3DSTATE_TO_STR(WINED3D_RS_STENCILFUNC);
2631 D3DSTATE_TO_STR(WINED3D_RS_STENCILREF);
2632 D3DSTATE_TO_STR(WINED3D_RS_STENCILMASK);
2633 D3DSTATE_TO_STR(WINED3D_RS_STENCILWRITEMASK);
2634 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREFACTOR);
2635 D3DSTATE_TO_STR(WINED3D_RS_WRAP0);
2636 D3DSTATE_TO_STR(WINED3D_RS_WRAP1);
2637 D3DSTATE_TO_STR(WINED3D_RS_WRAP2);
2638 D3DSTATE_TO_STR(WINED3D_RS_WRAP3);
2639 D3DSTATE_TO_STR(WINED3D_RS_WRAP4);
2640 D3DSTATE_TO_STR(WINED3D_RS_WRAP5);
2641 D3DSTATE_TO_STR(WINED3D_RS_WRAP6);
2642 D3DSTATE_TO_STR(WINED3D_RS_WRAP7);
2643 D3DSTATE_TO_STR(WINED3D_RS_CLIPPING);
2644 D3DSTATE_TO_STR(WINED3D_RS_LIGHTING);
2645 D3DSTATE_TO_STR(WINED3D_RS_EXTENTS);
2646 D3DSTATE_TO_STR(WINED3D_RS_AMBIENT);
2647 D3DSTATE_TO_STR(WINED3D_RS_FOGVERTEXMODE);
2648 D3DSTATE_TO_STR(WINED3D_RS_COLORVERTEX);
2649 D3DSTATE_TO_STR(WINED3D_RS_LOCALVIEWER);
2650 D3DSTATE_TO_STR(WINED3D_RS_NORMALIZENORMALS);
2651 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYBLENDENABLE);
2652 D3DSTATE_TO_STR(WINED3D_RS_DIFFUSEMATERIALSOURCE);
2653 D3DSTATE_TO_STR(WINED3D_RS_SPECULARMATERIALSOURCE);
2654 D3DSTATE_TO_STR(WINED3D_RS_AMBIENTMATERIALSOURCE);
2655 D3DSTATE_TO_STR(WINED3D_RS_EMISSIVEMATERIALSOURCE);
2656 D3DSTATE_TO_STR(WINED3D_RS_VERTEXBLEND);
2657 D3DSTATE_TO_STR(WINED3D_RS_CLIPPLANEENABLE);
2658 D3DSTATE_TO_STR(WINED3D_RS_SOFTWAREVERTEXPROCESSING);
2659 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE);
2660 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MIN);
2661 D3DSTATE_TO_STR(WINED3D_RS_POINTSPRITEENABLE);
2662 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALEENABLE);
2663 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_A);
2664 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_B);
2665 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_C);
2666 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEANTIALIAS);
2667 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEMASK);
2668 D3DSTATE_TO_STR(WINED3D_RS_PATCHEDGESTYLE);
2669 D3DSTATE_TO_STR(WINED3D_RS_PATCHSEGMENTS);
2670 D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN);
2671 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX);
2672 D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE);
2673 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
2674 D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR);
2675 D3DSTATE_TO_STR(WINED3D_RS_BLENDOP);
2676 D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE);
2677 D3DSTATE_TO_STR(WINED3D_RS_NORMALDEGREE);
2678 D3DSTATE_TO_STR(WINED3D_RS_SCISSORTESTENABLE);
2679 D3DSTATE_TO_STR(WINED3D_RS_SLOPESCALEDEPTHBIAS);
2680 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIASEDLINEENABLE);
2681 D3DSTATE_TO_STR(WINED3D_RS_MINTESSELLATIONLEVEL);
2682 D3DSTATE_TO_STR(WINED3D_RS_MAXTESSELLATIONLEVEL);
2683 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_X);
2684 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Y);
2685 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Z);
2686 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_W);
2687 D3DSTATE_TO_STR(WINED3D_RS_ENABLEADAPTIVETESSELLATION);
2688 D3DSTATE_TO_STR(WINED3D_RS_TWOSIDEDSTENCILMODE);
2689 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFAIL);
2690 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILZFAIL);
2691 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILPASS);
2692 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFUNC);
2693 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1);
2694 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2);
2695 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3);
2696 D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR);
2697 D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE);
2698 D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS);
2699 D3DSTATE_TO_STR(WINED3D_RS_WRAP8);
2700 D3DSTATE_TO_STR(WINED3D_RS_WRAP9);
2701 D3DSTATE_TO_STR(WINED3D_RS_WRAP10);
2702 D3DSTATE_TO_STR(WINED3D_RS_WRAP11);
2703 D3DSTATE_TO_STR(WINED3D_RS_WRAP12);
2704 D3DSTATE_TO_STR(WINED3D_RS_WRAP13);
2705 D3DSTATE_TO_STR(WINED3D_RS_WRAP14);
2706 D3DSTATE_TO_STR(WINED3D_RS_WRAP15);
2707 D3DSTATE_TO_STR(WINED3D_RS_SEPARATEALPHABLENDENABLE);
2708 D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
2709 D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
2710 D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
2711 #undef D3DSTATE_TO_STR
2712 default:
2713 FIXME("Unrecognized %u render state!\n", state);
2714 return "unrecognized";
2718 const char *debug_d3dsamplerstate(enum wined3d_sampler_state state)
2720 switch (state)
2722 #define D3DSTATE_TO_STR(u) case u: return #u
2723 D3DSTATE_TO_STR(WINED3D_SAMP_BORDER_COLOR);
2724 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_U);
2725 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_V);
2726 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_W);
2727 D3DSTATE_TO_STR(WINED3D_SAMP_MAG_FILTER);
2728 D3DSTATE_TO_STR(WINED3D_SAMP_MIN_FILTER);
2729 D3DSTATE_TO_STR(WINED3D_SAMP_MIP_FILTER);
2730 D3DSTATE_TO_STR(WINED3D_SAMP_MIPMAP_LOD_BIAS);
2731 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_MIP_LEVEL);
2732 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_ANISOTROPY);
2733 D3DSTATE_TO_STR(WINED3D_SAMP_SRGB_TEXTURE);
2734 D3DSTATE_TO_STR(WINED3D_SAMP_ELEMENT_INDEX);
2735 D3DSTATE_TO_STR(WINED3D_SAMP_DMAP_OFFSET);
2736 #undef D3DSTATE_TO_STR
2737 default:
2738 FIXME("Unrecognized %u sampler state!\n", state);
2739 return "unrecognized";
2743 const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type)
2745 switch (filter_type)
2747 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2748 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_NONE);
2749 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_POINT);
2750 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_LINEAR);
2751 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_ANISOTROPIC);
2752 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_FLAT_CUBIC);
2753 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_CUBIC);
2754 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_PYRAMIDAL_QUAD);
2755 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_QUAD);
2756 #undef D3DTEXTUREFILTERTYPE_TO_STR
2757 default:
2758 FIXME("Unrecognied texture filter type 0x%08x.\n", filter_type);
2759 return "unrecognized";
2763 const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state)
2765 switch (state)
2767 #define D3DSTATE_TO_STR(u) case u: return #u
2768 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_OP);
2769 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG1);
2770 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG2);
2771 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_OP);
2772 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG1);
2773 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG2);
2774 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT00);
2775 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT01);
2776 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT10);
2777 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT11);
2778 D3DSTATE_TO_STR(WINED3D_TSS_TEXCOORD_INDEX);
2779 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LSCALE);
2780 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LOFFSET);
2781 D3DSTATE_TO_STR(WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS);
2782 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG0);
2783 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG0);
2784 D3DSTATE_TO_STR(WINED3D_TSS_RESULT_ARG);
2785 D3DSTATE_TO_STR(WINED3D_TSS_CONSTANT);
2786 #undef D3DSTATE_TO_STR
2787 default:
2788 FIXME("Unrecognized %u texture state!\n", state);
2789 return "unrecognized";
2793 const char *debug_d3dtop(enum wined3d_texture_op d3dtop)
2795 switch (d3dtop)
2797 #define D3DTOP_TO_STR(u) case u: return #u
2798 D3DTOP_TO_STR(WINED3D_TOP_DISABLE);
2799 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG1);
2800 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG2);
2801 D3DTOP_TO_STR(WINED3D_TOP_MODULATE);
2802 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_2X);
2803 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_4X);
2804 D3DTOP_TO_STR(WINED3D_TOP_ADD);
2805 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED);
2806 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED_2X);
2807 D3DTOP_TO_STR(WINED3D_TOP_SUBTRACT);
2808 D3DTOP_TO_STR(WINED3D_TOP_ADD_SMOOTH);
2809 D3DTOP_TO_STR(WINED3D_TOP_BLEND_DIFFUSE_ALPHA);
2810 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA);
2811 D3DTOP_TO_STR(WINED3D_TOP_BLEND_FACTOR_ALPHA);
2812 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM);
2813 D3DTOP_TO_STR(WINED3D_TOP_BLEND_CURRENT_ALPHA);
2814 D3DTOP_TO_STR(WINED3D_TOP_PREMODULATE);
2815 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR);
2816 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA);
2817 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR);
2818 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA);
2819 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP);
2820 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP_LUMINANCE);
2821 D3DTOP_TO_STR(WINED3D_TOP_DOTPRODUCT3);
2822 D3DTOP_TO_STR(WINED3D_TOP_MULTIPLY_ADD);
2823 D3DTOP_TO_STR(WINED3D_TOP_LERP);
2824 #undef D3DTOP_TO_STR
2825 default:
2826 FIXME("Unrecognized texture op %#x.\n", d3dtop);
2827 return "unrecognized";
2831 const char *debug_d3dtstype(enum wined3d_transform_state tstype)
2833 switch (tstype)
2835 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2836 TSTYPE_TO_STR(WINED3D_TS_VIEW);
2837 TSTYPE_TO_STR(WINED3D_TS_PROJECTION);
2838 TSTYPE_TO_STR(WINED3D_TS_TEXTURE0);
2839 TSTYPE_TO_STR(WINED3D_TS_TEXTURE1);
2840 TSTYPE_TO_STR(WINED3D_TS_TEXTURE2);
2841 TSTYPE_TO_STR(WINED3D_TS_TEXTURE3);
2842 TSTYPE_TO_STR(WINED3D_TS_TEXTURE4);
2843 TSTYPE_TO_STR(WINED3D_TS_TEXTURE5);
2844 TSTYPE_TO_STR(WINED3D_TS_TEXTURE6);
2845 TSTYPE_TO_STR(WINED3D_TS_TEXTURE7);
2846 TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(0));
2847 #undef TSTYPE_TO_STR
2848 default:
2849 if (tstype > 256 && tstype < 512)
2851 FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype);
2852 return ("WINED3D_TS_WORLD_MATRIX > 0");
2854 FIXME("Unrecognized transform state %#x.\n", tstype);
2855 return "unrecognized";
2859 static const char *debug_shader_type(enum wined3d_shader_type type)
2861 switch(type)
2863 #define WINED3D_TO_STR(type) case type: return #type
2864 WINED3D_TO_STR(WINED3D_SHADER_TYPE_PIXEL);
2865 WINED3D_TO_STR(WINED3D_SHADER_TYPE_VERTEX);
2866 WINED3D_TO_STR(WINED3D_SHADER_TYPE_GEOMETRY);
2867 #undef WINED3D_TO_STR
2868 default:
2869 FIXME("Unrecognized shader type %#x.\n", type);
2870 return "unrecognized";
2874 const char *debug_d3dstate(DWORD state)
2876 if (STATE_IS_RENDER(state))
2877 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2878 if (STATE_IS_TEXTURESTAGE(state))
2880 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2881 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2882 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2883 texture_stage, debug_d3dtexturestate(texture_state));
2885 if (STATE_IS_SAMPLER(state))
2886 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2887 if (STATE_IS_SHADER(state))
2888 return wine_dbg_sprintf("STATE_SHADER(%s)", debug_shader_type(state - STATE_SHADER(0)));
2889 if (STATE_IS_CONSTANT_BUFFER(state))
2890 return wine_dbg_sprintf("STATE_CONSTANT_BUFFER(%s)", debug_shader_type(state - STATE_CONSTANT_BUFFER(0)));
2891 if (STATE_IS_TRANSFORM(state))
2892 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2893 if (STATE_IS_STREAMSRC(state))
2894 return "STATE_STREAMSRC";
2895 if (STATE_IS_INDEXBUFFER(state))
2896 return "STATE_INDEXBUFFER";
2897 if (STATE_IS_VDECL(state))
2898 return "STATE_VDECL";
2899 if (STATE_IS_VIEWPORT(state))
2900 return "STATE_VIEWPORT";
2901 if (STATE_IS_LIGHT_TYPE(state))
2902 return "STATE_LIGHT_TYPE";
2903 if (STATE_IS_ACTIVELIGHT(state))
2904 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2905 if (STATE_IS_SCISSORRECT(state))
2906 return "STATE_SCISSORRECT";
2907 if (STATE_IS_CLIPPLANE(state))
2908 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2909 if (STATE_IS_MATERIAL(state))
2910 return "STATE_MATERIAL";
2911 if (STATE_IS_FRONTFACE(state))
2912 return "STATE_FRONTFACE";
2913 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2914 return "STATE_POINTSPRITECOORDORIGIN";
2915 if (STATE_IS_BASEVERTEXINDEX(state))
2916 return "STATE_BASEVERTEXINDEX";
2917 if (STATE_IS_FRAMEBUFFER(state))
2918 return "STATE_FRAMEBUFFER";
2919 if (STATE_IS_POINT_SIZE_ENABLE(state))
2920 return "STATE_POINT_SIZE_ENABLE";
2922 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2925 const char *debug_d3dpool(enum wined3d_pool pool)
2927 switch (pool)
2929 #define POOL_TO_STR(p) case p: return #p
2930 POOL_TO_STR(WINED3D_POOL_DEFAULT);
2931 POOL_TO_STR(WINED3D_POOL_MANAGED);
2932 POOL_TO_STR(WINED3D_POOL_SYSTEM_MEM);
2933 POOL_TO_STR(WINED3D_POOL_SCRATCH);
2934 #undef POOL_TO_STR
2935 default:
2936 FIXME("Unrecognized pool %#x.\n", pool);
2937 return "unrecognized";
2941 const char *debug_fbostatus(GLenum status) {
2942 switch(status) {
2943 #define FBOSTATUS_TO_STR(u) case u: return #u
2944 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2945 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2946 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2947 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2948 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2949 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2950 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2951 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2952 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2953 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2954 #undef FBOSTATUS_TO_STR
2955 default:
2956 FIXME("Unrecognied FBO status 0x%08x\n", status);
2957 return "unrecognized";
2961 const char *debug_glerror(GLenum error) {
2962 switch(error) {
2963 #define GLERROR_TO_STR(u) case u: return #u
2964 GLERROR_TO_STR(GL_NO_ERROR);
2965 GLERROR_TO_STR(GL_INVALID_ENUM);
2966 GLERROR_TO_STR(GL_INVALID_VALUE);
2967 GLERROR_TO_STR(GL_INVALID_OPERATION);
2968 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2969 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2970 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2971 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2972 #undef GLERROR_TO_STR
2973 default:
2974 FIXME("Unrecognied GL error 0x%08x\n", error);
2975 return "unrecognized";
2979 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2981 switch(source)
2983 #define WINED3D_TO_STR(x) case x: return #x
2984 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2985 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2986 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2987 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2988 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2989 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2990 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2991 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2992 #undef WINED3D_TO_STR
2993 default:
2994 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2995 return "unrecognized";
2999 static const char *debug_complex_fixup(enum complex_fixup fixup)
3001 switch(fixup)
3003 #define WINED3D_TO_STR(x) case x: return #x
3004 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
3005 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
3006 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
3007 WINED3D_TO_STR(COMPLEX_FIXUP_NV12);
3008 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
3009 #undef WINED3D_TO_STR
3010 default:
3011 FIXME("Unrecognized complex fixup %#x\n", fixup);
3012 return "unrecognized";
3016 void dump_color_fixup_desc(struct color_fixup_desc fixup)
3018 if (is_complex_fixup(fixup))
3020 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
3021 return;
3024 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
3025 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
3026 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
3027 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
3030 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
3031 enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
3033 if (op == WINED3D_TOP_DISABLE)
3034 return FALSE;
3035 if (state->textures[stage])
3036 return FALSE;
3038 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
3039 && op != WINED3D_TOP_SELECT_ARG2)
3040 return TRUE;
3041 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
3042 && op != WINED3D_TOP_SELECT_ARG1)
3043 return TRUE;
3044 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
3045 && (op == WINED3D_TOP_MULTIPLY_ADD || op == WINED3D_TOP_LERP))
3046 return TRUE;
3048 return FALSE;
3051 /* Setup this textures matrix according to the texture flags. */
3052 /* Context activation is done by the caller (state handler). */
3053 void set_texture_matrix(const struct wined3d_gl_info *gl_info, const float *smat, DWORD flags,
3054 BOOL calculatedCoords, BOOL transformed, enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
3056 float mat[16];
3058 gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
3059 checkGLcall("glMatrixMode(GL_TEXTURE)");
3061 if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed)
3063 gl_info->gl_ops.gl.p_glLoadIdentity();
3064 checkGLcall("glLoadIdentity()");
3065 return;
3068 if (flags == (WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED))
3070 ERR("Invalid texture transform flags: WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED.\n");
3071 return;
3074 memcpy(mat, smat, 16 * sizeof(float));
3076 if (flags & WINED3D_TTFF_PROJECTED)
3078 if (!ffp_proj_control)
3080 switch (flags & ~WINED3D_TTFF_PROJECTED)
3082 case WINED3D_TTFF_COUNT2:
3083 mat[ 3] = mat[ 1];
3084 mat[ 7] = mat[ 5];
3085 mat[11] = mat[ 9];
3086 mat[15] = mat[13];
3087 mat[ 1] = mat[ 5] = mat[ 9] = mat[13] = 0.0f;
3088 break;
3089 case WINED3D_TTFF_COUNT3:
3090 mat[ 3] = mat[ 2];
3091 mat[ 7] = mat[ 6];
3092 mat[11] = mat[10];
3093 mat[15] = mat[14];
3094 mat[ 2] = mat[ 6] = mat[10] = mat[14] = 0.0f;
3095 break;
3098 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
3099 if(!calculatedCoords) {
3100 switch(vtx_fmt)
3102 case WINED3DFMT_R32_FLOAT:
3103 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
3104 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
3105 * the input value to the transformation will be 0, so the matrix value is irrelevant
3107 mat[12] = mat[4];
3108 mat[13] = mat[5];
3109 mat[14] = mat[6];
3110 mat[15] = mat[7];
3111 break;
3112 case WINED3DFMT_R32G32_FLOAT:
3113 /* See above, just 3rd and 4th coord
3115 mat[12] = mat[8];
3116 mat[13] = mat[9];
3117 mat[14] = mat[10];
3118 mat[15] = mat[11];
3119 break;
3120 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
3121 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
3123 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
3124 * into a bad place. The division elimination below will apply to make sure the
3125 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
3127 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
3128 break;
3129 default:
3130 FIXME("Unexpected fixed function texture coord input\n");
3133 if (!ffp_proj_control)
3135 switch (flags & ~WINED3D_TTFF_PROJECTED)
3137 /* case WINED3D_TTFF_COUNT1: Won't ever get here. */
3138 case WINED3D_TTFF_COUNT2:
3139 mat[2] = mat[6] = mat[10] = mat[14] = 0;
3140 /* OpenGL divides the first 3 vertex coord by the 4th by default,
3141 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
3142 * the 4th coord evaluates to 1.0 to eliminate that.
3144 * If the fixed function pipeline is used, the 4th value remains unused,
3145 * so there is no danger in doing this. With vertex shaders we have a
3146 * problem. Should an app hit that problem, the code here would have to
3147 * check for pixel shaders, and the shader has to undo the default gl divide.
3149 * A more serious problem occurs if the app passes 4 coordinates in, and the
3150 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
3151 * or a replacement shader. */
3152 default:
3153 mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
3158 gl_info->gl_ops.gl.p_glLoadMatrixf(mat);
3159 checkGLcall("glLoadMatrixf(mat)");
3162 /* This small helper function is used to convert a bitmask into the number of masked bits */
3163 unsigned int count_bits(unsigned int mask)
3165 unsigned int count;
3166 for (count = 0; mask; ++count)
3168 mask &= mask - 1;
3170 return count;
3173 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
3174 * The later function requires individual color components. */
3175 BOOL getColorBits(const struct wined3d_format *format,
3176 BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
3178 TRACE("format %s.\n", debug_d3dformat(format->id));
3180 switch (format->id)
3182 case WINED3DFMT_B10G10R10A2_UNORM:
3183 case WINED3DFMT_R10G10B10A2_UNORM:
3184 case WINED3DFMT_B8G8R8X8_UNORM:
3185 case WINED3DFMT_B8G8R8_UNORM:
3186 case WINED3DFMT_B8G8R8A8_UNORM:
3187 case WINED3DFMT_R8G8B8A8_UNORM:
3188 case WINED3DFMT_B5G5R5X1_UNORM:
3189 case WINED3DFMT_B5G5R5A1_UNORM:
3190 case WINED3DFMT_B5G6R5_UNORM:
3191 case WINED3DFMT_B4G4R4X4_UNORM:
3192 case WINED3DFMT_B4G4R4A4_UNORM:
3193 case WINED3DFMT_B2G3R3_UNORM:
3194 case WINED3DFMT_P8_UINT_A8_UNORM:
3195 case WINED3DFMT_P8_UINT:
3196 break;
3197 default:
3198 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
3199 return FALSE;
3202 *redSize = format->red_size;
3203 *greenSize = format->green_size;
3204 *blueSize = format->blue_size;
3205 *alphaSize = format->alpha_size;
3206 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
3208 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
3209 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
3210 return TRUE;
3213 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
3214 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
3216 TRACE("format %s.\n", debug_d3dformat(format->id));
3218 switch (format->id)
3220 case WINED3DFMT_D16_LOCKABLE:
3221 case WINED3DFMT_D16_UNORM:
3222 case WINED3DFMT_S1_UINT_D15_UNORM:
3223 case WINED3DFMT_X8D24_UNORM:
3224 case WINED3DFMT_S4X4_UINT_D24_UNORM:
3225 case WINED3DFMT_D24_UNORM_S8_UINT:
3226 case WINED3DFMT_S8_UINT_D24_FLOAT:
3227 case WINED3DFMT_D32_UNORM:
3228 case WINED3DFMT_D32_FLOAT:
3229 case WINED3DFMT_INTZ:
3230 break;
3231 default:
3232 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
3233 return FALSE;
3236 *depthSize = format->depth_size;
3237 *stencilSize = format->stencil_size;
3239 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
3240 *depthSize, *stencilSize, debug_d3dformat(format->id));
3241 return TRUE;
3244 /* Note: It's the caller's responsibility to ensure values can be expressed
3245 * in the requested format. UNORM formats for example can only express values
3246 * in the range 0.0f -> 1.0f. */
3247 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color)
3249 static const struct
3251 enum wined3d_format_id format_id;
3252 float r_mul;
3253 float g_mul;
3254 float b_mul;
3255 float a_mul;
3256 BYTE r_shift;
3257 BYTE g_shift;
3258 BYTE b_shift;
3259 BYTE a_shift;
3261 conv[] =
3263 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
3264 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
3265 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
3266 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
3267 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
3268 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
3269 {WINED3DFMT_R8_UNORM, 255.0f, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0},
3270 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
3271 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
3272 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
3273 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
3274 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
3275 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
3276 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
3277 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
3278 {WINED3DFMT_P8_UINT, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
3280 const struct wined3d_format *format = surface->resource.format;
3281 unsigned int i;
3283 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
3284 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
3286 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
3288 DWORD ret;
3290 if (format->id != conv[i].format_id) continue;
3292 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
3293 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
3294 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
3295 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
3297 TRACE("Returning 0x%08x.\n", ret);
3299 return ret;
3302 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
3304 return 0;
3307 /* DirectDraw stuff */
3308 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
3310 switch (depth)
3312 case 8: return WINED3DFMT_P8_UINT;
3313 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
3314 case 16: return WINED3DFMT_B5G6R5_UNORM;
3315 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
3316 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
3317 default: return WINED3DFMT_UNKNOWN;
3321 void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
3322 const struct wined3d_matrix *src2)
3324 struct wined3d_matrix temp;
3326 /* Now do the multiplication 'by hand'.
3327 I know that all this could be optimised, but this will be done later :-) */
3328 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);
3329 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);
3330 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);
3331 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);
3333 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);
3334 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);
3335 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);
3336 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);
3338 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);
3339 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);
3340 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);
3341 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);
3343 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);
3344 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);
3345 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);
3346 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);
3348 /* And copy the new matrix in the good storage.. */
3349 memcpy(dest, &temp, 16 * sizeof(float));
3352 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
3353 DWORD size = 0;
3354 int i;
3355 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
3357 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
3358 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
3359 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
3360 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
3361 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
3362 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
3363 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
3364 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
3365 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
3366 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
3367 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
3368 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
3369 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
3370 default: ERR("Unexpected position mask\n");
3372 for (i = 0; i < numTextures; i++) {
3373 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
3376 return size;
3379 void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d_state *state,
3380 struct ffp_frag_settings *settings, BOOL ignore_textype)
3382 #define ARG1 0x01
3383 #define ARG2 0x02
3384 #define ARG0 0x04
3385 static const unsigned char args[WINED3D_TOP_LERP + 1] =
3387 /* undefined */ 0,
3388 /* D3DTOP_DISABLE */ 0,
3389 /* D3DTOP_SELECTARG1 */ ARG1,
3390 /* D3DTOP_SELECTARG2 */ ARG2,
3391 /* D3DTOP_MODULATE */ ARG1 | ARG2,
3392 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
3393 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
3394 /* D3DTOP_ADD */ ARG1 | ARG2,
3395 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
3396 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
3397 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
3398 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
3399 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
3400 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
3401 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
3402 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
3403 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
3404 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
3405 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
3406 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
3407 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
3408 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
3409 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
3410 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
3411 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
3412 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
3413 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
3415 unsigned int i;
3416 DWORD ttff;
3417 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
3418 const struct wined3d_format *rt_format = state->fb->render_targets[0]->format;
3419 const struct wined3d_gl_info *gl_info = context->gl_info;
3420 const struct wined3d_d3d_info *d3d_info = context->d3d_info;
3422 for (i = 0; i < d3d_info->limits.ffp_blend_stages; ++i)
3424 const struct wined3d_texture *texture;
3426 settings->op[i].padding = 0;
3427 if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
3429 settings->op[i].cop = WINED3D_TOP_DISABLE;
3430 settings->op[i].aop = WINED3D_TOP_DISABLE;
3431 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
3432 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
3433 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
3434 settings->op[i].dst = resultreg;
3435 settings->op[i].tex_type = tex_1d;
3436 settings->op[i].projected = proj_none;
3437 i++;
3438 break;
3441 if ((texture = state->textures[i]))
3443 settings->op[i].color_fixup = texture->resource.format->color_fixup;
3444 if (ignore_textype)
3446 settings->op[i].tex_type = tex_1d;
3448 else
3450 switch (texture->target)
3452 case GL_TEXTURE_1D:
3453 settings->op[i].tex_type = tex_1d;
3454 break;
3455 case GL_TEXTURE_2D:
3456 settings->op[i].tex_type = tex_2d;
3457 break;
3458 case GL_TEXTURE_3D:
3459 settings->op[i].tex_type = tex_3d;
3460 break;
3461 case GL_TEXTURE_CUBE_MAP_ARB:
3462 settings->op[i].tex_type = tex_cube;
3463 break;
3464 case GL_TEXTURE_RECTANGLE_ARB:
3465 settings->op[i].tex_type = tex_rect;
3466 break;
3469 } else {
3470 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
3471 settings->op[i].tex_type = tex_1d;
3474 cop = state->texture_states[i][WINED3D_TSS_COLOR_OP];
3475 aop = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
3477 carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG1] : ARG_UNUSED;
3478 carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG2] : ARG_UNUSED;
3479 carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG0] : ARG_UNUSED;
3481 if (is_invalid_op(state, i, cop, carg1, carg2, carg0))
3483 carg0 = ARG_UNUSED;
3484 carg2 = ARG_UNUSED;
3485 carg1 = WINED3DTA_CURRENT;
3486 cop = WINED3D_TOP_SELECT_ARG1;
3489 if (cop == WINED3D_TOP_DOTPRODUCT3)
3491 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
3492 * the color result to the alpha component of the destination
3494 aop = cop;
3495 aarg1 = carg1;
3496 aarg2 = carg2;
3497 aarg0 = carg0;
3499 else
3501 aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] : ARG_UNUSED;
3502 aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] : ARG_UNUSED;
3503 aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] : ARG_UNUSED;
3506 if (!i && state->textures[0] && state->render_states[WINED3D_RS_COLORKEYENABLE])
3508 GLenum texture_dimensions;
3510 texture = state->textures[0];
3511 texture_dimensions = texture->target;
3513 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3515 if (texture->color_key_flags & WINEDDSD_CKSRCBLT && !texture->resource.format->alpha_size)
3517 if (aop == WINED3D_TOP_DISABLE)
3519 aarg1 = WINED3DTA_TEXTURE;
3520 aop = WINED3D_TOP_SELECT_ARG1;
3522 else if (aop == WINED3D_TOP_SELECT_ARG1 && aarg1 != WINED3DTA_TEXTURE)
3524 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3526 aarg2 = WINED3DTA_TEXTURE;
3527 aop = WINED3D_TOP_MODULATE;
3529 else aarg1 = WINED3DTA_TEXTURE;
3531 else if (aop == WINED3D_TOP_SELECT_ARG2 && aarg2 != WINED3DTA_TEXTURE)
3533 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3535 aarg1 = WINED3DTA_TEXTURE;
3536 aop = WINED3D_TOP_MODULATE;
3538 else aarg2 = WINED3DTA_TEXTURE;
3544 if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0))
3546 aarg0 = ARG_UNUSED;
3547 aarg2 = ARG_UNUSED;
3548 aarg1 = WINED3DTA_CURRENT;
3549 aop = WINED3D_TOP_SELECT_ARG1;
3552 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
3553 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
3555 ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
3556 if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3))
3557 settings->op[i].projected = proj_count3;
3558 else if (ttff & WINED3D_TTFF_PROJECTED)
3559 settings->op[i].projected = proj_count4;
3560 else
3561 settings->op[i].projected = proj_none;
3563 else
3565 settings->op[i].projected = proj_none;
3568 settings->op[i].cop = cop;
3569 settings->op[i].aop = aop;
3570 settings->op[i].carg0 = carg0;
3571 settings->op[i].carg1 = carg1;
3572 settings->op[i].carg2 = carg2;
3573 settings->op[i].aarg0 = aarg0;
3574 settings->op[i].aarg1 = aarg1;
3575 settings->op[i].aarg2 = aarg2;
3577 if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP)
3578 settings->op[i].dst = tempreg;
3579 else
3580 settings->op[i].dst = resultreg;
3583 /* Clear unsupported stages */
3584 for(; i < MAX_TEXTURES; i++) {
3585 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
3588 if (!state->render_states[WINED3D_RS_FOGENABLE])
3590 settings->fog = WINED3D_FFP_PS_FOG_OFF;
3592 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
3594 if (use_vs(state) || state->vertex_declaration->position_transformed)
3596 settings->fog = WINED3D_FFP_PS_FOG_LINEAR;
3598 else
3600 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
3602 case WINED3D_FOG_NONE:
3603 case WINED3D_FOG_LINEAR:
3604 settings->fog = WINED3D_FFP_PS_FOG_LINEAR;
3605 break;
3606 case WINED3D_FOG_EXP:
3607 settings->fog = WINED3D_FFP_PS_FOG_EXP;
3608 break;
3609 case WINED3D_FOG_EXP2:
3610 settings->fog = WINED3D_FFP_PS_FOG_EXP2;
3611 break;
3615 else
3617 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
3619 case WINED3D_FOG_LINEAR:
3620 settings->fog = WINED3D_FFP_PS_FOG_LINEAR;
3621 break;
3622 case WINED3D_FOG_EXP:
3623 settings->fog = WINED3D_FFP_PS_FOG_EXP;
3624 break;
3625 case WINED3D_FOG_EXP2:
3626 settings->fog = WINED3D_FFP_PS_FOG_EXP2;
3627 break;
3630 if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB]
3631 && state->render_states[WINED3D_RS_SRGBWRITEENABLE]
3632 && rt_format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
3634 settings->sRGB_write = 1;
3635 } else {
3636 settings->sRGB_write = 0;
3638 if (d3d_info->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
3639 || !state->render_states[WINED3D_RS_CLIPPLANEENABLE])
3641 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3642 * the fixed function vertex pipeline is used(which always supports clipplanes), or
3643 * if no clipplane is enabled
3645 settings->emul_clipplanes = 0;
3646 } else {
3647 settings->emul_clipplanes = 1;
3651 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3652 const struct ffp_frag_settings *settings)
3654 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3655 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3658 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3660 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3661 * whereas desc points to an extended structure with implementation specific parts. */
3662 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3664 ERR("Failed to insert ffp frag shader.\n");
3668 /* Activates the texture dimension according to the bound D3D texture. Does
3669 * not care for the colorop or correct gl texture unit (when using nvrc).
3670 * Requires the caller to activate the correct unit. */
3671 /* Context activation is done by the caller (state handler). */
3672 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3674 if (texture)
3676 switch (texture->target)
3678 case GL_TEXTURE_2D:
3679 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3680 checkGLcall("glDisable(GL_TEXTURE_3D)");
3681 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3683 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3684 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3686 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3688 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3689 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3691 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3692 checkGLcall("glEnable(GL_TEXTURE_2D)");
3693 break;
3694 case GL_TEXTURE_RECTANGLE_ARB:
3695 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3696 checkGLcall("glDisable(GL_TEXTURE_2D)");
3697 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3698 checkGLcall("glDisable(GL_TEXTURE_3D)");
3699 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3701 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3702 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3704 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_RECTANGLE_ARB);
3705 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3706 break;
3707 case GL_TEXTURE_3D:
3708 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3710 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3711 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3713 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3715 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3716 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3718 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3719 checkGLcall("glDisable(GL_TEXTURE_2D)");
3720 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D);
3721 checkGLcall("glEnable(GL_TEXTURE_3D)");
3722 break;
3723 case GL_TEXTURE_CUBE_MAP_ARB:
3724 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3725 checkGLcall("glDisable(GL_TEXTURE_2D)");
3726 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3727 checkGLcall("glDisable(GL_TEXTURE_3D)");
3728 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3730 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3731 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3733 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3734 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3735 break;
3738 else
3740 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3741 checkGLcall("glEnable(GL_TEXTURE_2D)");
3742 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3743 checkGLcall("glDisable(GL_TEXTURE_3D)");
3744 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3746 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3747 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3749 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3751 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3752 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3754 /* Binding textures is done by samplers. A dummy texture will be bound */
3758 /* Context activation is done by the caller (state handler). */
3759 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3761 DWORD sampler = state_id - STATE_SAMPLER(0);
3762 DWORD mapped_stage = context->tex_unit_map[sampler];
3764 /* No need to enable / disable anything here for unused samplers. The
3765 * tex_colorop handler takes care. Also no action is needed with pixel
3766 * shaders, or if tex_colorop will take care of this business. */
3767 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
3768 return;
3769 if (sampler >= context->lowest_disabled_stage)
3770 return;
3771 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)))
3772 return;
3774 texture_activate_dimensions(state->textures[sampler], context->gl_info);
3777 void *wined3d_rb_alloc(size_t size)
3779 return HeapAlloc(GetProcessHeap(), 0, size);
3782 void *wined3d_rb_realloc(void *ptr, size_t size)
3784 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3787 void wined3d_rb_free(void *ptr)
3789 HeapFree(GetProcessHeap(), 0, ptr);
3792 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3794 const struct ffp_frag_settings *ka = key;
3795 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3797 return memcmp(ka, kb, sizeof(*ka));
3800 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3802 wined3d_rb_alloc,
3803 wined3d_rb_realloc,
3804 wined3d_rb_free,
3805 ffp_frag_program_key_compare,
3808 void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct wined3d_stream_info *si,
3809 struct wined3d_ffp_vs_settings *settings)
3811 unsigned int coord_idx, i;
3813 if (si->position_transformed)
3815 memset(settings, 0, sizeof(*settings));
3817 settings->transformed = 1;
3818 settings->point_size = state->gl_primitive_type == GL_POINTS;
3819 if (!state->render_states[WINED3D_RS_FOGENABLE])
3820 settings->fog_mode = WINED3D_FFP_VS_FOG_OFF;
3821 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
3822 settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
3823 else
3824 settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD;
3826 for (i = 0; i < MAX_TEXTURES; ++i)
3828 coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
3829 if (coord_idx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
3830 settings->texcoords |= 1 << i;
3831 settings->texgen[i] = (state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT)
3832 & WINED3D_FFP_TCI_MASK;
3834 return;
3837 settings->transformed = 0;
3838 settings->clipping = state->render_states[WINED3D_RS_CLIPPING]
3839 && state->render_states[WINED3D_RS_CLIPPLANEENABLE];
3840 settings->normal = !!(si->use_map & (1 << WINED3D_FFP_NORMAL));
3841 settings->normalize = settings->normal && state->render_states[WINED3D_RS_NORMALIZENORMALS];
3842 settings->lighting = !!state->render_states[WINED3D_RS_LIGHTING];
3843 settings->localviewer = !!state->render_states[WINED3D_RS_LOCALVIEWER];
3844 settings->point_size = state->gl_primitive_type == GL_POINTS;
3846 if (state->render_states[WINED3D_RS_COLORVERTEX] && (si->use_map & (1 << WINED3D_FFP_DIFFUSE)))
3848 settings->diffuse_source = state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE];
3849 settings->emission_source = state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE];
3850 settings->ambient_source = state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE];
3851 settings->specular_source = state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE];
3853 else
3855 settings->diffuse_source = WINED3D_MCS_MATERIAL;
3856 settings->emission_source = WINED3D_MCS_MATERIAL;
3857 settings->ambient_source = WINED3D_MCS_MATERIAL;
3858 settings->specular_source = WINED3D_MCS_MATERIAL;
3861 settings->texcoords = 0;
3862 for (i = 0; i < MAX_TEXTURES; ++i)
3864 coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
3865 if (coord_idx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
3866 settings->texcoords |= 1 << i;
3867 settings->texgen[i] = (state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT)
3868 & WINED3D_FFP_TCI_MASK;
3871 settings->light_type = 0;
3872 for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i)
3874 if (state->lights[i])
3875 settings->light_type |= (state->lights[i]->OriginalParms.type
3876 & WINED3D_FFP_LIGHT_TYPE_MASK) << WINED3D_FFP_LIGHT_TYPE_SHIFT(i);
3879 settings->ortho_fog = 0;
3880 if (!state->render_states[WINED3D_RS_FOGENABLE])
3881 settings->fog_mode = WINED3D_FFP_VS_FOG_OFF;
3882 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
3884 settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
3886 if (state->transforms[WINED3D_TS_PROJECTION].u.m[0][3] == 0.0f
3887 && state->transforms[WINED3D_TS_PROJECTION].u.m[1][3] == 0.0f
3888 && state->transforms[WINED3D_TS_PROJECTION].u.m[2][3] == 0.0f
3889 && state->transforms[WINED3D_TS_PROJECTION].u.m[3][3] == 1.0f)
3890 settings->ortho_fog = 1;
3892 else if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE)
3893 settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD;
3894 else if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
3895 settings->fog_mode = WINED3D_FFP_VS_FOG_RANGE;
3896 else
3897 settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
3899 settings->padding = 0;
3902 static int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3904 const struct wined3d_ffp_vs_settings *ka = key;
3905 const struct wined3d_ffp_vs_settings *kb = &WINE_RB_ENTRY_VALUE(entry,
3906 const struct wined3d_ffp_vs_desc, entry)->settings;
3908 return memcmp(ka, kb, sizeof(*ka));
3911 const struct wine_rb_functions wined3d_ffp_vertex_program_rb_functions =
3913 wined3d_rb_alloc,
3914 wined3d_rb_realloc,
3915 wined3d_rb_free,
3916 wined3d_ffp_vertex_program_key_compare,
3919 UINT wined3d_log2i(UINT32 x)
3921 static const UINT l[] =
3923 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3924 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3925 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3926 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3927 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3928 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3929 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3930 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3931 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3932 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3933 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3934 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3935 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3936 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3937 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3938 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3940 UINT32 i;
3942 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3945 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3946 const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
3947 const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
3949 static const struct blit_shader * const blitters[] =
3951 &arbfp_blit,
3952 &ffp_blit,
3953 &cpu_blit,
3955 unsigned int i;
3957 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3959 if (blitters[i]->blit_supported(gl_info, blit_op,
3960 src_rect, src_usage, src_pool, src_format,
3961 dst_rect, dst_usage, dst_pool, dst_format))
3962 return blitters[i];
3965 return NULL;
3968 void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
3970 const struct wined3d_viewport *vp = &state->viewport;
3972 SetRect(rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
3974 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
3975 IntersectRect(rect, rect, &state->scissor_rect);
3978 const char *wined3d_debug_location(DWORD location)
3980 char buf[294];
3982 buf[0] = '\0';
3983 #define LOCATION_TO_STR(u) if (location & u) { strcat(buf, " | "#u); location &= ~u; }
3984 LOCATION_TO_STR(WINED3D_LOCATION_DISCARDED);
3985 LOCATION_TO_STR(WINED3D_LOCATION_SYSMEM);
3986 LOCATION_TO_STR(WINED3D_LOCATION_USER_MEMORY);
3987 LOCATION_TO_STR(WINED3D_LOCATION_DIB);
3988 LOCATION_TO_STR(WINED3D_LOCATION_BUFFER);
3989 LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_RGB);
3990 LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_SRGB);
3991 LOCATION_TO_STR(WINED3D_LOCATION_DRAWABLE);
3992 LOCATION_TO_STR(WINED3D_LOCATION_RB_MULTISAMPLE);
3993 LOCATION_TO_STR(WINED3D_LOCATION_RB_RESOLVED);
3994 #undef LOCATION_TO_STR
3995 if (location) FIXME("Unrecognized location flag(s) %#x.\n", location);
3997 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
4000 /* Print a floating point value with the %.8e format specifier, always using
4001 * '.' as decimal separator. */
4002 void wined3d_ftoa(float value, char *s)
4004 int idx = 1;
4006 if (copysignf(1.0f, value) < 0.0f)
4007 ++idx;
4009 /* Be sure to allocate a buffer of at least 17 characters for the result
4010 as sprintf may return a 3 digit exponent when using the MSVC runtime
4011 instead of a 2 digit exponent. */
4012 sprintf(s, "%.8e", value);
4013 if (isfinite(value))
4014 s[idx] = '.';
4017 void wined3d_release_dc(HWND window, HDC dc)
4019 /* You'd figure ReleaseDC() would fail if the DC doesn't match the window.
4020 * However, that's not what actually happens, and there are user32 tests
4021 * that confirm ReleaseDC() with the wrong window is supposed to succeed.
4022 * So explicitly check that the DC belongs to the window, since we want to
4023 * avoid releasing a DC that belongs to some other window if the original
4024 * window was already destroyed. */
4025 if (WindowFromDC(dc) != window)
4026 WARN("DC %p does not belong to window %p.\n", dc, window);
4027 else if (!ReleaseDC(window, dc))
4028 ERR("Failed to release device context %p, last error %#x.\n", dc, GetLastError());