d3d8: Get rid of the format switching code in d3d8_device_CopyRects().
[wine.git] / dlls / wined3d / utils.c
blob5db5e941c6360a634c9fda0b7eadff1b693ceb71
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 /* The following formats explicitly don't have WINED3DFMT_FLAG_TEXTURE set:
617 * These are never supported on native.
618 * WINED3DFMT_B8G8R8_UNORM
619 * WINED3DFMT_B2G3R3_UNORM
620 * WINED3DFMT_L4A4_UNORM
621 * WINED3DFMT_S1_UINT_D15_UNORM
622 * WINED3DFMT_S4X4_UINT_D24_UNORM
624 * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of ddraw.
625 * Since it is not widely available, don't offer it. Further no Windows driver
626 * offers WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either.
627 * WINED3DFMT_P8_UINT
628 * WINED3DFMT_P8_UINT_A8_UNORM
630 * These formats seem to be similar to the HILO formats in
631 * GL_NV_texture_shader. NVHU is said to be GL_UNSIGNED_HILO16,
632 * NVHS GL_SIGNED_HILO16. Rumours say that D3D computes a 3rd channel
633 * similarly to D3DFMT_CxV8U8 (So NVHS could be called D3DFMT_CxV16U16). ATI
634 * refused to support formats which can easily be emulated with pixel shaders,
635 * so applications have to deal with not having NVHS and NVHU.
636 * WINED3DFMT_NVHU
637 * WINED3DFMT_NVHS */
638 static const struct wined3d_format_texture_info format_texture_info[] =
640 /* format id gl_internal gl_srgb_internal gl_rt_internal
641 gl_format gl_type conv_byte_count
642 flags
643 extension convert */
644 /* FourCC formats */
645 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
646 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
647 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
648 * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
649 * endian machine
651 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
652 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
653 WINED3DFMT_FLAG_FILTERING,
654 WINED3D_GL_EXT_NONE, NULL},
655 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
656 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 0,
657 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
658 APPLE_YCBCR_422, NULL},
659 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
660 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
661 WINED3DFMT_FLAG_FILTERING,
662 WINED3D_GL_EXT_NONE, NULL},
663 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
664 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, 0,
665 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
666 APPLE_YCBCR_422, NULL},
667 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
668 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
669 WINED3DFMT_FLAG_FILTERING,
670 WINED3D_GL_EXT_NONE, NULL},
671 {WINED3DFMT_NV12, GL_ALPHA, GL_ALPHA, 0,
672 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
673 WINED3DFMT_FLAG_FILTERING,
674 WINED3D_GL_EXT_NONE, NULL},
675 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
676 GL_RGBA, GL_UNSIGNED_BYTE, 0,
677 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
678 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
679 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
680 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
681 GL_RGBA, GL_UNSIGNED_BYTE, 0,
682 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
683 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
684 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
685 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
686 GL_RGBA, GL_UNSIGNED_BYTE, 0,
687 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
688 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
689 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
690 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
691 GL_RGBA, GL_UNSIGNED_BYTE, 0,
692 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
693 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
694 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
695 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
696 GL_RGBA, GL_UNSIGNED_BYTE, 0,
697 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
698 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
699 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
700 /* IEEE formats */
701 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
702 GL_RED, GL_FLOAT, 0,
703 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
704 ARB_TEXTURE_FLOAT, NULL},
705 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
706 GL_RED, GL_FLOAT, 0,
707 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
708 ARB_TEXTURE_RG, NULL},
709 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
710 GL_RGB, GL_FLOAT, 12,
711 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
712 ARB_TEXTURE_FLOAT, convert_r32g32_float},
713 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
714 GL_RG, GL_FLOAT, 0,
715 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
716 ARB_TEXTURE_RG, NULL},
717 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
718 GL_RGBA, GL_FLOAT, 0,
719 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
720 ARB_TEXTURE_FLOAT, NULL},
721 /* Float */
722 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
723 GL_RED, GL_HALF_FLOAT_ARB, 0,
724 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
725 ARB_TEXTURE_FLOAT, NULL},
726 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
727 GL_RED, GL_HALF_FLOAT_ARB, 0,
728 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
729 ARB_TEXTURE_RG, NULL},
730 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
731 GL_RGB, GL_HALF_FLOAT_ARB, 6,
732 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
733 ARB_TEXTURE_FLOAT, convert_r16g16},
734 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
735 GL_RG, GL_HALF_FLOAT_ARB, 0,
736 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
737 ARB_TEXTURE_RG, NULL},
738 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
739 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
740 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET
741 | WINED3DFMT_FLAG_VTF,
742 ARB_TEXTURE_FLOAT, NULL},
743 /* Palettized formats */
744 {WINED3DFMT_P8_UINT, GL_ALPHA8, GL_ALPHA8, 0,
745 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
747 0, NULL},
748 /* Standard ARGB formats */
749 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
750 GL_BGR, GL_UNSIGNED_BYTE, 0,
751 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
752 WINED3D_GL_EXT_NONE, NULL},
753 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
754 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
755 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
756 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE
757 | WINED3DFMT_FLAG_VTF,
758 WINED3D_GL_EXT_NONE, NULL},
759 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
760 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
761 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
762 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
763 WINED3D_GL_EXT_NONE, NULL},
764 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
765 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
766 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
767 | WINED3DFMT_FLAG_RENDERTARGET,
768 WINED3D_GL_EXT_NONE, NULL},
769 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
770 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
771 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
772 WINED3D_GL_EXT_NONE, NULL},
773 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
774 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
775 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
776 WINED3D_GL_EXT_NONE, NULL},
777 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
778 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
779 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
780 | WINED3DFMT_FLAG_SRGB_READ,
781 WINED3D_GL_EXT_NONE, NULL},
782 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
783 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
784 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
785 WINED3D_GL_EXT_NONE, NULL},
786 {WINED3DFMT_R8_UNORM, GL_R8, GL_R8, 0,
787 GL_RED, GL_UNSIGNED_BYTE, 0,
788 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
789 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
790 ARB_TEXTURE_RG, NULL},
791 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
792 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
793 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
794 WINED3D_GL_EXT_NONE, NULL},
795 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
796 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
797 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
798 WINED3D_GL_EXT_NONE, NULL},
799 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
800 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
801 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
802 | WINED3DFMT_FLAG_RENDERTARGET,
803 WINED3D_GL_EXT_NONE, NULL},
804 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
805 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
806 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
807 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE
808 | WINED3DFMT_FLAG_VTF,
809 WINED3D_GL_EXT_NONE, NULL},
810 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
811 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
812 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
813 WINED3D_GL_EXT_NONE, NULL},
814 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
815 GL_RGB, GL_UNSIGNED_SHORT, 6,
816 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
817 WINED3D_GL_EXT_NONE, convert_r16g16},
818 {WINED3DFMT_R16G16_UNORM, GL_RG16, GL_RG16, 0,
819 GL_RG, GL_UNSIGNED_SHORT, 0,
820 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
821 | WINED3DFMT_FLAG_RENDERTARGET,
822 ARB_TEXTURE_RG, NULL},
823 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
824 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
825 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
826 | WINED3DFMT_FLAG_RENDERTARGET,
827 WINED3D_GL_EXT_NONE, NULL},
828 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
829 GL_RGBA, GL_UNSIGNED_SHORT, 0,
830 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
831 | WINED3DFMT_FLAG_RENDERTARGET,
832 WINED3D_GL_EXT_NONE, NULL},
833 /* Luminance */
834 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
835 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
836 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
837 | WINED3DFMT_FLAG_SRGB_READ,
838 WINED3D_GL_EXT_NONE, NULL},
839 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
840 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
841 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
842 | WINED3DFMT_FLAG_SRGB_READ,
843 WINED3D_GL_EXT_NONE, NULL},
844 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
845 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
846 WINED3DFMT_FLAG_FILTERING,
847 WINED3D_GL_EXT_NONE, convert_l4a4_unorm},
848 /* Bump mapping stuff */
849 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
850 GL_BGR, GL_UNSIGNED_BYTE, 3,
851 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
852 | WINED3DFMT_FLAG_BUMPMAP,
853 WINED3D_GL_EXT_NONE, convert_r8g8_snorm},
854 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
855 GL_DSDT_NV, GL_BYTE, 0,
856 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
857 | WINED3DFMT_FLAG_BUMPMAP,
858 NV_TEXTURE_SHADER, NULL},
859 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
860 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
861 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
862 | WINED3DFMT_FLAG_BUMPMAP,
863 WINED3D_GL_EXT_NONE, convert_r5g5_snorm_l6_unorm},
864 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
865 GL_DSDT_MAG_NV, GL_BYTE, 3,
866 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
867 | WINED3DFMT_FLAG_BUMPMAP,
868 NV_TEXTURE_SHADER, convert_r5g5_snorm_l6_unorm_nv},
869 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
870 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
871 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
872 | WINED3DFMT_FLAG_BUMPMAP,
873 WINED3D_GL_EXT_NONE, convert_r8g8_snorm_l8x8_unorm},
874 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
875 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
876 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
877 | WINED3DFMT_FLAG_BUMPMAP,
878 NV_TEXTURE_SHADER, convert_r8g8_snorm_l8x8_unorm_nv},
879 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
880 GL_BGRA, GL_UNSIGNED_BYTE, 4,
881 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
882 | WINED3DFMT_FLAG_BUMPMAP,
883 WINED3D_GL_EXT_NONE, convert_r8g8b8a8_snorm},
884 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
885 GL_RGBA, GL_BYTE, 0,
886 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
887 | WINED3DFMT_FLAG_BUMPMAP,
888 NV_TEXTURE_SHADER, NULL},
889 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
890 GL_BGR, GL_UNSIGNED_SHORT, 6,
891 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
892 | WINED3DFMT_FLAG_BUMPMAP,
893 WINED3D_GL_EXT_NONE, convert_r16g16_snorm},
894 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
895 GL_HILO_NV, GL_SHORT, 0,
896 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
897 | WINED3DFMT_FLAG_BUMPMAP,
898 NV_TEXTURE_SHADER, NULL},
899 /* Depth stencil formats */
900 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0,
901 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
902 WINED3DFMT_FLAG_DEPTH,
903 WINED3D_GL_EXT_NONE, NULL},
904 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
905 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
906 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
907 ARB_DEPTH_TEXTURE, NULL},
908 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0,
909 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
910 WINED3DFMT_FLAG_DEPTH,
911 WINED3D_GL_EXT_NONE, NULL},
912 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
913 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
914 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
915 ARB_DEPTH_TEXTURE, NULL},
916 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
917 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
918 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
919 ARB_DEPTH_TEXTURE, NULL},
920 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
921 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
922 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
923 EXT_PACKED_DEPTH_STENCIL, convert_s1_uint_d15_unorm},
924 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
925 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
926 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
927 ARB_FRAMEBUFFER_OBJECT, convert_s1_uint_d15_unorm},
928 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
929 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
930 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
931 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
932 ARB_DEPTH_TEXTURE, NULL},
933 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
934 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
935 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
936 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
937 EXT_PACKED_DEPTH_STENCIL, NULL},
938 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
939 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
940 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
941 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
942 ARB_FRAMEBUFFER_OBJECT, NULL},
943 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0,
944 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
945 WINED3DFMT_FLAG_DEPTH,
946 WINED3D_GL_EXT_NONE, NULL},
947 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
948 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
949 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
950 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
951 ARB_DEPTH_TEXTURE, NULL},
952 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
953 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
954 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
955 ARB_DEPTH_TEXTURE, NULL},
956 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
957 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
958 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
959 EXT_PACKED_DEPTH_STENCIL, convert_s4x4_uint_d24_unorm},
960 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
961 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
962 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
963 ARB_FRAMEBUFFER_OBJECT, convert_s4x4_uint_d24_unorm},
964 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0,
965 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
966 WINED3DFMT_FLAG_DEPTH,
967 WINED3D_GL_EXT_NONE, NULL},
968 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
969 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
970 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
971 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
972 ARB_DEPTH_TEXTURE, NULL},
973 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
974 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
975 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
976 WINED3D_GL_EXT_NONE, NULL},
977 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
978 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
979 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
980 ARB_DEPTH_BUFFER_FLOAT, NULL},
981 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
982 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
983 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
984 ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float},
985 /* Vendor-specific formats */
986 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
987 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
988 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
989 | WINED3DFMT_FLAG_COMPRESSED,
990 ATI_TEXTURE_COMPRESSION_3DC, NULL},
991 {WINED3DFMT_ATI2N, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0,
992 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
993 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
994 | WINED3DFMT_FLAG_COMPRESSED,
995 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
996 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
997 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
998 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
999 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
1000 EXT_PACKED_DEPTH_STENCIL, NULL},
1001 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
1002 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
1003 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
1004 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
1005 ARB_FRAMEBUFFER_OBJECT, NULL},
1006 {WINED3DFMT_NULL, 0, 0, 0,
1007 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
1008 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET,
1009 ARB_FRAMEBUFFER_OBJECT, NULL},
1012 static inline int getFmtIdx(enum wined3d_format_id format_id)
1014 /* First check if the format is at the position of its value.
1015 * This will catch the argb formats before the loop is entered. */
1016 if (format_id < (sizeof(formats) / sizeof(*formats))
1017 && formats[format_id].id == format_id)
1019 return format_id;
1021 else
1023 unsigned int i;
1025 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
1027 if (formats[i].id == format_id) return i;
1030 return -1;
1033 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
1035 UINT format_count = sizeof(formats) / sizeof(*formats);
1036 UINT i;
1038 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
1039 if (!gl_info->formats)
1041 ERR("Failed to allocate memory.\n");
1042 return FALSE;
1045 for (i = 0; i < format_count; ++i)
1047 struct wined3d_format *format = &gl_info->formats[i];
1048 format->id = formats[i].id;
1049 format->red_size = formats[i].red_size;
1050 format->green_size = formats[i].green_size;
1051 format->blue_size = formats[i].blue_size;
1052 format->alpha_size = formats[i].alpha_size;
1053 format->red_offset = formats[i].red_offset;
1054 format->green_offset = formats[i].green_offset;
1055 format->blue_offset = formats[i].blue_offset;
1056 format->alpha_offset = formats[i].alpha_offset;
1057 format->byte_count = formats[i].bpp;
1058 format->depth_size = formats[i].depth_size;
1059 format->stencil_size = formats[i].stencil_size;
1060 format->block_width = 1;
1061 format->block_height = 1;
1062 format->block_byte_count = formats[i].bpp;
1065 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
1067 int fmt_idx = getFmtIdx(format_base_flags[i].id);
1069 if (fmt_idx == -1)
1071 ERR("Format %s (%#x) not found.\n",
1072 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
1073 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1074 return FALSE;
1077 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
1080 return TRUE;
1083 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
1085 unsigned int i;
1087 for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i)
1089 struct wined3d_format *format;
1090 int fmt_idx = getFmtIdx(format_block_info[i].id);
1092 if (fmt_idx == -1)
1094 ERR("Format %s (%#x) not found.\n",
1095 debug_d3dformat(format_block_info[i].id), format_block_info[i].id);
1096 return FALSE;
1099 format = &gl_info->formats[fmt_idx];
1100 format->block_width = format_block_info[i].block_width;
1101 format->block_height = format_block_info[i].block_height;
1102 format->block_byte_count = format_block_info[i].block_byte_count;
1103 format->flags |= WINED3DFMT_FLAG_BLOCKS;
1104 if (!format_block_info[i].verify)
1105 format->flags |= WINED3DFMT_FLAG_BLOCKS_NO_VERIFY;
1108 return TRUE;
1111 /* Context activation is done by the caller. */
1112 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
1114 /* Check if the default internal format is supported as a frame buffer
1115 * target, otherwise fall back to the render target internal.
1117 * Try to stick to the standard format if possible, this limits precision differences. */
1118 GLenum status;
1119 GLuint tex;
1121 while (gl_info->gl_ops.gl.p_glGetError());
1122 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1124 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1125 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1127 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0,
1128 format->glFormat, format->glType, NULL);
1129 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1130 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1132 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1134 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1135 checkGLcall("Framebuffer format check");
1137 if (status == GL_FRAMEBUFFER_COMPLETE)
1139 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1140 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1141 format->rtInternal = format->glInternal;
1143 else
1145 if (!format->rtInternal)
1147 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1149 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1150 " and no fallback specified.\n", debug_d3dformat(format->id));
1151 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1153 else
1155 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1157 format->rtInternal = format->glInternal;
1159 else
1161 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1162 debug_d3dformat(format->id));
1164 while (gl_info->gl_ops.gl.p_glGetError());
1166 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1168 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0,
1169 format->glFormat, format->glType, NULL);
1170 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1171 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1173 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1175 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1176 checkGLcall("Framebuffer format check");
1178 if (status == GL_FRAMEBUFFER_COMPLETE)
1180 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1181 debug_d3dformat(format->id));
1183 else
1185 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1186 debug_d3dformat(format->id));
1187 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1192 if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1193 || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1194 && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
1195 && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA
1196 && (format->red_size || format->alpha_size))
1198 DWORD readback[16 * 16], color, r_range, a_range;
1199 BYTE r, a;
1200 BOOL match = TRUE;
1201 GLuint rb;
1203 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1204 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1206 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1207 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1208 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1209 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1210 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1211 checkGLcall("RB attachment");
1214 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1215 gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1216 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1217 if (gl_info->gl_ops.gl.p_glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1219 while (gl_info->gl_ops.gl.p_glGetError());
1220 TRACE("Format doesn't support post-pixelshader blending.\n");
1221 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1223 else
1225 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1226 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16);
1227 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1228 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1229 gl_info->gl_ops.gl.p_glLoadIdentity();
1230 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1231 gl_info->gl_ops.gl.p_glLoadIdentity();
1233 gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1235 /* Draw a full-black quad */
1236 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1237 gl_info->gl_ops.gl.p_glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
1238 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1239 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1240 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1241 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1242 gl_info->gl_ops.gl.p_glEnd();
1244 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1245 /* Draw a half-transparent red quad */
1246 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1247 gl_info->gl_ops.gl.p_glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
1248 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1249 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1250 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1251 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1252 gl_info->gl_ops.gl.p_glEnd();
1254 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1256 /* Rebinding texture to workaround a fglrx bug. */
1257 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1258 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1259 checkGLcall("Post-pixelshader blending check");
1261 color = readback[7 * 16 + 7];
1262 a = color >> 24;
1263 r = (color & 0x00ff0000) >> 16;
1265 r_range = format->red_size < 8 ? 1 << (8 - format->red_size) : 1;
1266 a_range = format->alpha_size < 8 ? 1 << (8 - format->alpha_size) : 1;
1267 if (format->red_size && (r < 0x7f - r_range || r > 0x7f + r_range))
1268 match = FALSE;
1269 else if (format->alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range))
1270 match = FALSE;
1271 if (!match)
1273 TRACE("Format doesn't support post-pixelshader blending.\n");
1274 TRACE("Color output: %#x\n", color);
1275 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1277 else
1279 TRACE("Format supports post-pixelshader blending.\n");
1280 TRACE("Color output: %#x\n", color);
1281 format->flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1285 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1286 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1288 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1289 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1290 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1291 checkGLcall("RB cleanup");
1295 if (format->glInternal != format->glGammaInternal)
1297 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0,
1298 format->glFormat, format->glType, NULL);
1299 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1301 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1302 checkGLcall("Framebuffer format check");
1304 if (status == GL_FRAMEBUFFER_COMPLETE)
1306 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1307 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1309 else
1311 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1314 else if (status == GL_FRAMEBUFFER_COMPLETE)
1315 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1317 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1320 static void query_format_flag(struct wined3d_gl_info *gl_info, struct wined3d_format *format,
1321 GLint internal, GLenum pname, DWORD flag, const char *string)
1323 GLint value;
1325 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, internal, pname, 1, &value);
1326 if (value == GL_FULL_SUPPORT)
1328 TRACE("Format %s supports %s.\n", debug_d3dformat(format->id), string);
1329 format->flags |= flag;
1331 else
1333 TRACE("Format %s doesn't support %s.\n", debug_d3dformat(format->id), string);
1334 format->flags &= ~flag;
1338 /* Context activation is done by the caller. */
1339 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1341 unsigned int i;
1342 GLuint fbo;
1344 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
1346 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1348 GLint value;
1349 struct wined3d_format *format = &gl_info->formats[i];
1351 if (!format->glInternal)
1352 continue;
1353 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1354 continue;
1356 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->glInternal,
1357 GL_FRAMEBUFFER_RENDERABLE, 1, &value);
1358 if (value == GL_FULL_SUPPORT)
1360 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1361 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1362 format->rtInternal = format->glInternal;
1364 query_format_flag(gl_info, format, format->glInternal, GL_FRAMEBUFFER_BLEND,
1365 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING, "post-pixelshader blending");
1367 else
1369 if (!format->rtInternal)
1371 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1373 WARN("Format %s with rendertarget flag is not supported as FBO color attachment"
1374 " and no fallback specified.\n", debug_d3dformat(format->id));
1375 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1377 else
1378 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1379 format->rtInternal = format->glInternal;
1381 else
1383 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->rtInternal,
1384 GL_FRAMEBUFFER_RENDERABLE, 1, &value);
1385 if (value == GL_FULL_SUPPORT)
1387 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1388 debug_d3dformat(format->id));
1390 else
1392 WARN("Format %s rtInternal format is not supported as FBO color attachment.\n",
1393 debug_d3dformat(format->id));
1394 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1399 if (format->glInternal != format->glGammaInternal)
1401 gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->glGammaInternal,
1402 GL_FRAMEBUFFER_RENDERABLE, 1, &value);
1403 if (value == GL_FULL_SUPPORT)
1405 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1406 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1408 else
1410 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1413 else if (format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)
1414 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1416 return;
1419 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1421 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1422 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1423 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1424 gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0);
1427 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1429 struct wined3d_format *format = &gl_info->formats[i];
1431 if (!format->glInternal) continue;
1433 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1435 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1436 debug_d3dformat(format->id));
1437 continue;
1440 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1442 TRACE("Skipping format %s because it's a compressed format.\n",
1443 debug_d3dformat(format->id));
1444 continue;
1447 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1449 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1450 check_fbo_compat(gl_info, format);
1452 else
1454 format->rtInternal = format->glInternal;
1458 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1459 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1462 static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1464 struct fragment_caps fragment_caps;
1465 struct shader_caps shader_caps;
1466 BOOL srgb_write;
1467 unsigned int i;
1469 adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
1470 adapter->shader_backend->shader_get_caps(gl_info, &shader_caps);
1471 srgb_write = (fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_SRGB_WRITE)
1472 && (shader_caps.wined3d_caps & WINED3D_SHADER_CAP_SRGB_WRITE);
1474 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1476 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1477 struct wined3d_format *format;
1479 if (fmt_idx == -1)
1481 ERR("Format %s (%#x) not found.\n",
1482 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1483 return FALSE;
1486 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1488 format = &gl_info->formats[fmt_idx];
1490 /* ARB_texture_rg defines floating point formats, but only if
1491 * ARB_texture_float is also supported. */
1492 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1493 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1494 continue;
1496 format->glInternal = format_texture_info[i].gl_internal;
1497 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1498 format->rtInternal = format_texture_info[i].gl_rt_internal;
1499 format->glFormat = format_texture_info[i].gl_format;
1500 format->glType = format_texture_info[i].gl_type;
1501 format->color_fixup = COLOR_FIXUP_IDENTITY;
1502 format->flags |= format_texture_info[i].flags;
1503 format->height_scale.numerator = 1;
1504 format->height_scale.denominator = 1;
1506 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
1508 query_format_flag(gl_info, format, format->glInternal, GL_VERTEX_TEXTURE,
1509 WINED3DFMT_FLAG_VTF, "vertex texture usage");
1510 query_format_flag(gl_info, format, format->glInternal, GL_FILTER,
1511 WINED3DFMT_FLAG_FILTERING, "filtering");
1513 if (format->glGammaInternal != format->glInternal)
1515 query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_READ,
1516 WINED3DFMT_FLAG_SRGB_READ, "sRGB read");
1518 if (srgb_write)
1519 query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_WRITE,
1520 WINED3DFMT_FLAG_SRGB_WRITE, "sRGB write");
1521 else
1522 format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
1524 if (!(format->flags & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE)))
1525 format->glGammaInternal = format->glInternal;
1526 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1527 format->glInternal = format->glGammaInternal;
1530 else
1532 if (!gl_info->limits.vertex_samplers)
1533 format->flags &= ~WINED3DFMT_FLAG_VTF;
1535 if (!(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1536 format->flags |= WINED3DFMT_FLAG_FILTERING;
1537 else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT)
1538 format->flags &= ~WINED3DFMT_FLAG_VTF;
1540 if (format->glGammaInternal != format->glInternal)
1542 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1543 if (!gl_info->supported[EXT_TEXTURE_SRGB])
1545 format->glGammaInternal = format->glInternal;
1546 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1548 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1550 format->glInternal = format->glGammaInternal;
1554 if ((format->flags & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write)
1555 format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
1558 /* Texture conversion stuff */
1559 format->convert = format_texture_info[i].convert;
1560 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1563 return TRUE;
1566 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1568 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1569 c1 >>= 8; c2 >>= 8;
1570 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1571 c1 >>= 8; c2 >>= 8;
1572 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1573 c1 >>= 8; c2 >>= 8;
1574 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1575 return TRUE;
1578 /* A context is provided by the caller */
1579 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1581 static const DWORD data[] = {0x00000000, 0xffffffff};
1582 GLuint tex, fbo, buffer;
1583 DWORD readback[16 * 1];
1584 BOOL ret = FALSE;
1586 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1587 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1588 * falling back to software. If this changes in the future this code will get fooled and
1589 * apps might hit the software path due to incorrectly advertised caps.
1591 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1592 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1593 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1596 while (gl_info->gl_ops.gl.p_glGetError());
1598 gl_info->gl_ops.gl.p_glGenTextures(1, &buffer);
1599 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1600 memset(readback, 0x7e, sizeof(readback));
1601 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0,
1602 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1603 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1604 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1605 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1606 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1607 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1609 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1610 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1611 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0,
1612 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1613 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1614 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1615 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1616 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1617 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1618 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
1620 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1621 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1622 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1623 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1625 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1);
1626 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1627 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1628 gl_info->gl_ops.gl.p_glLoadIdentity();
1629 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1630 gl_info->gl_ops.gl.p_glLoadIdentity();
1632 gl_info->gl_ops.gl.p_glClearColor(0, 1, 0, 0);
1633 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1635 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1636 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 0.0);
1637 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, -1.0f);
1638 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 0.0);
1639 gl_info->gl_ops.gl.p_glVertex2f(1.0f, -1.0f);
1640 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 1.0);
1641 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, 1.0f);
1642 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 1.0);
1643 gl_info->gl_ops.gl.p_glVertex2f(1.0f, 1.0f);
1644 gl_info->gl_ops.gl.p_glEnd();
1646 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1647 memset(readback, 0x7f, sizeof(readback));
1648 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1649 if (color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5)
1650 || color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1652 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, assuming no filtering\n",
1653 readback[6], readback[9]);
1654 ret = FALSE;
1656 else
1658 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1659 readback[6], readback[9]);
1660 ret = TRUE;
1663 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1664 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1665 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1666 gl_info->gl_ops.gl.p_glDeleteTextures(1, &buffer);
1668 if (gl_info->gl_ops.gl.p_glGetError())
1670 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1671 ret = FALSE;
1674 return ret;
1677 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1679 struct wined3d_format *format;
1680 unsigned int fmt_idx, i;
1681 static const enum wined3d_format_id fmts16[] =
1683 WINED3DFMT_R16_FLOAT,
1684 WINED3DFMT_R16G16_FLOAT,
1685 WINED3DFMT_R16G16B16A16_FLOAT,
1687 BOOL filtered;
1689 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
1690 /* This was already handled by init_format_texture_info(). */
1691 return;
1693 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1695 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1696 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1698 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1699 filtered = TRUE;
1701 else if (gl_info->limits.glsl_varyings > 44)
1703 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1704 filtered = TRUE;
1706 else
1708 TRACE("Assuming no float16 blending\n");
1709 filtered = FALSE;
1712 if(filtered)
1714 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1716 fmt_idx = getFmtIdx(fmts16[i]);
1717 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1720 return;
1723 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1725 fmt_idx = getFmtIdx(fmts16[i]);
1726 format = &gl_info->formats[fmt_idx];
1727 if (!format->glInternal) continue; /* Not supported by GL */
1729 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1730 if(filtered)
1732 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1733 format->flags |= WINED3DFMT_FLAG_FILTERING;
1735 else
1737 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1742 static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
1744 unsigned int i;
1745 int idx;
1747 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1748 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1749 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1751 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1752 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1753 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1755 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1756 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1757 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1759 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1760 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1761 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1763 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1764 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1765 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1767 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1768 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1769 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1770 * the only driver that implements it(fglrx) has a buggy implementation.
1772 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1773 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1774 * conversion for this format.
1776 if (!gl_info->supported[NV_TEXTURE_SHADER])
1778 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1779 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1780 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1781 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1782 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1783 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1785 else
1787 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1788 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1789 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1791 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1792 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1793 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1796 if (!gl_info->supported[NV_TEXTURE_SHADER])
1798 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1799 * with each other
1801 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1802 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1803 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1804 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1805 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1806 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1807 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1808 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1809 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1811 else
1813 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1814 * are converted at surface loading time, but they do not need any modification in
1815 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1816 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1820 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1822 idx = getFmtIdx(WINED3DFMT_ATI2N);
1823 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1824 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1826 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1828 idx = getFmtIdx(WINED3DFMT_ATI2N);
1829 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1830 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1833 if (!gl_info->supported[APPLE_YCBCR_422])
1835 idx = getFmtIdx(WINED3DFMT_YUY2);
1836 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1838 idx = getFmtIdx(WINED3DFMT_UYVY);
1839 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1842 idx = getFmtIdx(WINED3DFMT_YV12);
1843 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
1844 gl_info->formats[idx].height_scale.numerator = 3;
1845 gl_info->formats[idx].height_scale.denominator = 2;
1846 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1848 idx = getFmtIdx(WINED3DFMT_NV12);
1849 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
1850 gl_info->formats[idx].height_scale.numerator = 3;
1851 gl_info->formats[idx].height_scale.denominator = 2;
1852 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_NV12);
1854 if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
1856 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1857 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1860 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1862 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1863 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1866 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1868 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1869 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1870 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1871 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1873 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1874 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1877 if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
1879 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1880 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1882 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1883 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1885 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1886 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1889 if (gl_info->quirks & WINED3D_QUIRK_BROKEN_RGBA16)
1891 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_UNORM);
1892 gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
1895 /* ATI instancing hack: Although ATI cards do not support Shader Model
1896 * 3.0, they support instancing. To query if the card supports instancing
1897 * CheckDeviceFormat() with the special format MAKEFOURCC('I','N','S','T')
1898 * is used. Should an application check for this, provide a proper return
1899 * value. We can do instancing with all shader versions, but we need
1900 * vertex shaders.
1902 * Additionally applications have to set the D3DRS_POINTSIZE render state
1903 * to MAKEFOURCC('I','N','S','T') once to enable instancing. Wined3d
1904 * doesn't need that and just ignores it.
1906 * With Shader Model 3.0 capable cards Instancing 'just works' in Windows. */
1907 /* FIXME: This should just check the shader backend caps. */
1908 if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
1910 idx = getFmtIdx(WINED3DFMT_INST);
1911 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
1914 /* Depth bound test. To query if the card supports it CheckDeviceFormat()
1915 * with the special format MAKEFOURCC('N','V','D','B') is used. It is
1916 * enabled by setting D3DRS_ADAPTIVETESS_X render state to
1917 * MAKEFOURCC('N','V','D','B') and then controlled by setting
1918 * D3DRS_ADAPTIVETESS_Z (zMin) and D3DRS_ADAPTIVETESS_W (zMax) to test
1919 * value. */
1920 if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST])
1922 idx = getFmtIdx(WINED3DFMT_NVDB);
1923 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
1926 /* RESZ aka AMD DX9-level hack for multisampled depth buffer resolve. You query for RESZ
1927 * support by checking for availability of MAKEFOURCC('R','E','S','Z') surfaces with
1928 * RENDERTARGET usage. */
1929 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
1931 idx = getFmtIdx(WINED3DFMT_RESZ);
1932 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET;
1935 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1937 struct wined3d_format *format = &gl_info->formats[i];
1939 if (!(format->flags & WINED3DFMT_FLAG_TEXTURE))
1940 continue;
1942 if (!adapter->shader_backend->shader_color_fixup_supported(format->color_fixup)
1943 || !adapter->fragment_pipe->color_fixup_supported(format->color_fixup))
1944 format->flags &= ~WINED3DFMT_FLAG_TEXTURE;
1948 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1950 unsigned int i;
1952 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1954 struct wined3d_format *format;
1955 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1957 if (fmt_idx == -1)
1959 ERR("Format %s (%#x) not found.\n",
1960 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1961 return FALSE;
1964 format = &gl_info->formats[fmt_idx];
1965 format->emit_idx = format_vertex_info[i].emit_idx;
1966 format->component_count = format_vertex_info[i].component_count;
1967 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1968 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1969 format->gl_normalized = format_vertex_info[i].gl_normalized;
1970 format->component_size = format_vertex_info[i].component_size;
1973 return TRUE;
1976 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1978 if (!init_format_base_info(gl_info)) return FALSE;
1980 if (!init_format_block_info(gl_info))
1982 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1983 gl_info->formats = NULL;
1984 return FALSE;
1987 return TRUE;
1990 /* Context activation is done by the caller. */
1991 BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter)
1993 struct wined3d_gl_info *gl_info = &adapter->gl_info;
1995 if (!init_format_base_info(gl_info)) return FALSE;
1997 if (!init_format_block_info(gl_info)) goto fail;
1998 if (!init_format_texture_info(adapter, gl_info)) goto fail;
1999 if (!init_format_vertex_info(gl_info)) goto fail;
2001 apply_format_fixups(adapter, gl_info);
2002 init_format_fbo_compat_info(gl_info);
2003 init_format_filter_info(gl_info, adapter->driver_info.vendor);
2005 return TRUE;
2007 fail:
2008 HeapFree(GetProcessHeap(), 0, gl_info->formats);
2009 gl_info->formats = NULL;
2010 return FALSE;
2013 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
2014 enum wined3d_format_id format_id)
2016 int idx = getFmtIdx(format_id);
2018 if (idx == -1)
2020 FIXME("Can't find format %s (%#x) in the format lookup table\n",
2021 debug_d3dformat(format_id), format_id);
2022 /* Get the caller a valid pointer */
2023 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
2026 return &gl_info->formats[idx];
2029 UINT wined3d_format_calculate_pitch(const struct wined3d_format *format, UINT width)
2031 /* For block based formats, pitch means the amount of bytes to the next
2032 * row of blocks rather than the next row of pixels. */
2033 if (format->flags & WINED3DFMT_FLAG_BLOCKS)
2034 return format->block_byte_count * ((width + format->block_width - 1) / format->block_width);
2036 return format->byte_count * width;
2039 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment,
2040 UINT width, UINT height, UINT depth)
2042 UINT pitch = wined3d_format_calculate_pitch(format, width);
2043 UINT size;
2045 if (format->id == WINED3DFMT_UNKNOWN)
2047 size = 0;
2049 else if (format->flags & WINED3DFMT_FLAG_BLOCKS)
2051 UINT row_count = (height + format->block_height - 1) / format->block_height;
2052 size = row_count * ((pitch + alignment - 1) & ~(alignment - 1));
2054 else
2056 size = height * ((pitch + alignment - 1) & ~(alignment - 1));
2059 if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
2061 /* The D3D format requirements make sure that the resulting format is an integer again */
2062 size *= format->height_scale.numerator;
2063 size /= format->height_scale.denominator;
2066 size *= depth;
2068 return size;
2071 /*****************************************************************************
2072 * Trace formatting of useful values
2074 const char *debug_d3dformat(enum wined3d_format_id format_id)
2076 switch (format_id)
2078 #define FMT_TO_STR(format_id) case format_id: return #format_id
2079 FMT_TO_STR(WINED3DFMT_UNKNOWN);
2080 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
2081 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
2082 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
2083 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
2084 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
2085 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
2086 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
2087 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
2088 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
2089 FMT_TO_STR(WINED3DFMT_P8_UINT);
2090 FMT_TO_STR(WINED3DFMT_L8_UNORM);
2091 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
2092 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
2093 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
2094 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
2095 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
2096 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
2097 FMT_TO_STR(WINED3DFMT_UYVY);
2098 FMT_TO_STR(WINED3DFMT_YUY2);
2099 FMT_TO_STR(WINED3DFMT_YV12);
2100 FMT_TO_STR(WINED3DFMT_NV12);
2101 FMT_TO_STR(WINED3DFMT_DXT1);
2102 FMT_TO_STR(WINED3DFMT_DXT2);
2103 FMT_TO_STR(WINED3DFMT_DXT3);
2104 FMT_TO_STR(WINED3DFMT_DXT4);
2105 FMT_TO_STR(WINED3DFMT_DXT5);
2106 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
2107 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
2108 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
2109 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
2110 FMT_TO_STR(WINED3DFMT_D32_UNORM);
2111 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
2112 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
2113 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
2114 FMT_TO_STR(WINED3DFMT_L16_UNORM);
2115 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
2116 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
2117 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
2118 FMT_TO_STR(WINED3DFMT_ATI2N);
2119 FMT_TO_STR(WINED3DFMT_NVDB);
2120 FMT_TO_STR(WINED3DFMT_NVHU);
2121 FMT_TO_STR(WINED3DFMT_NVHS);
2122 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
2123 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
2124 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
2125 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
2126 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
2127 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
2128 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
2129 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
2130 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
2131 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
2132 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
2133 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
2134 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
2135 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
2136 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
2137 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
2138 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
2139 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
2140 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
2141 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
2142 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
2143 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
2144 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
2145 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
2146 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
2147 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
2148 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
2149 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
2150 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
2151 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
2152 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
2153 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
2154 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
2155 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
2156 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
2157 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
2158 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
2159 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
2160 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
2161 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
2162 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
2163 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
2164 FMT_TO_STR(WINED3DFMT_R32_UINT);
2165 FMT_TO_STR(WINED3DFMT_R32_SINT);
2166 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
2167 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
2168 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
2169 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
2170 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
2171 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
2172 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
2173 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
2174 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
2175 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
2176 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
2177 FMT_TO_STR(WINED3DFMT_D16_UNORM);
2178 FMT_TO_STR(WINED3DFMT_R16_UNORM);
2179 FMT_TO_STR(WINED3DFMT_R16_UINT);
2180 FMT_TO_STR(WINED3DFMT_R16_SNORM);
2181 FMT_TO_STR(WINED3DFMT_R16_SINT);
2182 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
2183 FMT_TO_STR(WINED3DFMT_R8_UNORM);
2184 FMT_TO_STR(WINED3DFMT_R8_UINT);
2185 FMT_TO_STR(WINED3DFMT_R8_SNORM);
2186 FMT_TO_STR(WINED3DFMT_R8_SINT);
2187 FMT_TO_STR(WINED3DFMT_A8_UNORM);
2188 FMT_TO_STR(WINED3DFMT_R1_UNORM);
2189 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
2190 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
2191 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
2192 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
2193 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
2194 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
2195 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
2196 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
2197 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
2198 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
2199 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
2200 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
2201 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
2202 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
2203 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
2204 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
2205 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
2206 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
2207 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
2208 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
2209 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
2210 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
2211 FMT_TO_STR(WINED3DFMT_INTZ);
2212 FMT_TO_STR(WINED3DFMT_RESZ);
2213 FMT_TO_STR(WINED3DFMT_NULL);
2214 FMT_TO_STR(WINED3DFMT_R16);
2215 FMT_TO_STR(WINED3DFMT_AL16);
2216 #undef FMT_TO_STR
2217 default:
2219 char fourcc[5];
2220 fourcc[0] = (char)(format_id);
2221 fourcc[1] = (char)(format_id >> 8);
2222 fourcc[2] = (char)(format_id >> 16);
2223 fourcc[3] = (char)(format_id >> 24);
2224 fourcc[4] = 0;
2225 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
2226 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
2227 else
2228 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
2230 return "unrecognized";
2234 const char *debug_d3ddevicetype(enum wined3d_device_type device_type)
2236 switch (device_type)
2238 #define DEVTYPE_TO_STR(dev) case dev: return #dev
2239 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_HAL);
2240 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_REF);
2241 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_SW);
2242 #undef DEVTYPE_TO_STR
2243 default:
2244 FIXME("Unrecognized device type %#x.\n", device_type);
2245 return "unrecognized";
2249 const char *debug_d3dusage(DWORD usage)
2251 char buf[333];
2253 buf[0] = '\0';
2254 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
2255 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
2256 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
2257 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
2258 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
2259 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
2260 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
2261 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
2262 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
2263 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
2264 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
2265 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
2266 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
2267 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
2268 #undef WINED3DUSAGE_TO_STR
2269 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
2271 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2274 const char *debug_d3dusagequery(DWORD usagequery)
2276 char buf[238];
2278 buf[0] = '\0';
2279 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
2280 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
2281 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
2282 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
2283 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
2284 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
2285 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
2286 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
2287 #undef WINED3DUSAGEQUERY_TO_STR
2288 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
2290 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
2293 const char *debug_d3ddeclmethod(enum wined3d_decl_method method)
2295 switch (method)
2297 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
2298 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_DEFAULT);
2299 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_U);
2300 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_V);
2301 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_CROSS_UV);
2302 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_UV);
2303 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP);
2304 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP_PRESAMPLED);
2305 #undef WINED3DDECLMETHOD_TO_STR
2306 default:
2307 FIXME("Unrecognized declaration method %#x.\n", method);
2308 return "unrecognized";
2312 const char *debug_d3ddeclusage(enum wined3d_decl_usage usage)
2314 switch (usage)
2316 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
2317 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITION);
2318 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_WEIGHT);
2319 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_INDICES);
2320 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_NORMAL);
2321 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_PSIZE);
2322 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TEXCOORD);
2323 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TANGENT);
2324 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BINORMAL);
2325 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TESS_FACTOR);
2326 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITIONT);
2327 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_COLOR);
2328 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_FOG);
2329 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_DEPTH);
2330 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_SAMPLE);
2331 #undef WINED3DDECLUSAGE_TO_STR
2332 default:
2333 FIXME("Unrecognized %u declaration usage!\n", usage);
2334 return "unrecognized";
2338 const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
2340 switch (resource_type)
2342 #define RES_TO_STR(res) case res: return #res
2343 RES_TO_STR(WINED3D_RTYPE_SURFACE);
2344 RES_TO_STR(WINED3D_RTYPE_VOLUME);
2345 RES_TO_STR(WINED3D_RTYPE_TEXTURE);
2346 RES_TO_STR(WINED3D_RTYPE_VOLUME_TEXTURE);
2347 RES_TO_STR(WINED3D_RTYPE_CUBE_TEXTURE);
2348 RES_TO_STR(WINED3D_RTYPE_BUFFER);
2349 #undef RES_TO_STR
2350 default:
2351 FIXME("Unrecognized resource type %#x.\n", resource_type);
2352 return "unrecognized";
2356 const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type)
2358 switch (primitive_type)
2360 #define PRIM_TO_STR(prim) case prim: return #prim
2361 PRIM_TO_STR(WINED3D_PT_UNDEFINED);
2362 PRIM_TO_STR(WINED3D_PT_POINTLIST);
2363 PRIM_TO_STR(WINED3D_PT_LINELIST);
2364 PRIM_TO_STR(WINED3D_PT_LINESTRIP);
2365 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST);
2366 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP);
2367 PRIM_TO_STR(WINED3D_PT_TRIANGLEFAN);
2368 PRIM_TO_STR(WINED3D_PT_LINELIST_ADJ);
2369 PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ);
2370 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ);
2371 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ);
2372 #undef PRIM_TO_STR
2373 default:
2374 FIXME("Unrecognized %u primitive type!\n", primitive_type);
2375 return "unrecognized";
2379 const char *debug_d3drenderstate(enum wined3d_render_state state)
2381 switch (state)
2383 #define D3DSTATE_TO_STR(u) case u: return #u
2384 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIAS);
2385 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREPERSPECTIVE);
2386 D3DSTATE_TO_STR(WINED3D_RS_WRAPU);
2387 D3DSTATE_TO_STR(WINED3D_RS_WRAPV);
2388 D3DSTATE_TO_STR(WINED3D_RS_ZENABLE);
2389 D3DSTATE_TO_STR(WINED3D_RS_FILLMODE);
2390 D3DSTATE_TO_STR(WINED3D_RS_SHADEMODE);
2391 D3DSTATE_TO_STR(WINED3D_RS_LINEPATTERN);
2392 D3DSTATE_TO_STR(WINED3D_RS_MONOENABLE);
2393 D3DSTATE_TO_STR(WINED3D_RS_ROP2);
2394 D3DSTATE_TO_STR(WINED3D_RS_PLANEMASK);
2395 D3DSTATE_TO_STR(WINED3D_RS_ZWRITEENABLE);
2396 D3DSTATE_TO_STR(WINED3D_RS_ALPHATESTENABLE);
2397 D3DSTATE_TO_STR(WINED3D_RS_LASTPIXEL);
2398 D3DSTATE_TO_STR(WINED3D_RS_SRCBLEND);
2399 D3DSTATE_TO_STR(WINED3D_RS_DESTBLEND);
2400 D3DSTATE_TO_STR(WINED3D_RS_CULLMODE);
2401 D3DSTATE_TO_STR(WINED3D_RS_ZFUNC);
2402 D3DSTATE_TO_STR(WINED3D_RS_ALPHAREF);
2403 D3DSTATE_TO_STR(WINED3D_RS_ALPHAFUNC);
2404 D3DSTATE_TO_STR(WINED3D_RS_DITHERENABLE);
2405 D3DSTATE_TO_STR(WINED3D_RS_ALPHABLENDENABLE);
2406 D3DSTATE_TO_STR(WINED3D_RS_FOGENABLE);
2407 D3DSTATE_TO_STR(WINED3D_RS_SPECULARENABLE);
2408 D3DSTATE_TO_STR(WINED3D_RS_ZVISIBLE);
2409 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXEL);
2410 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXELX);
2411 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEDALPHA);
2412 D3DSTATE_TO_STR(WINED3D_RS_FOGCOLOR);
2413 D3DSTATE_TO_STR(WINED3D_RS_FOGTABLEMODE);
2414 D3DSTATE_TO_STR(WINED3D_RS_FOGSTART);
2415 D3DSTATE_TO_STR(WINED3D_RS_FOGEND);
2416 D3DSTATE_TO_STR(WINED3D_RS_FOGDENSITY);
2417 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEENABLE);
2418 D3DSTATE_TO_STR(WINED3D_RS_EDGEANTIALIAS);
2419 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYENABLE);
2420 D3DSTATE_TO_STR(WINED3D_RS_MIPMAPLODBIAS);
2421 D3DSTATE_TO_STR(WINED3D_RS_RANGEFOGENABLE);
2422 D3DSTATE_TO_STR(WINED3D_RS_ANISOTROPY);
2423 D3DSTATE_TO_STR(WINED3D_RS_FLUSHBATCH);
2424 D3DSTATE_TO_STR(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT);
2425 D3DSTATE_TO_STR(WINED3D_RS_STENCILENABLE);
2426 D3DSTATE_TO_STR(WINED3D_RS_STENCILFAIL);
2427 D3DSTATE_TO_STR(WINED3D_RS_STENCILZFAIL);
2428 D3DSTATE_TO_STR(WINED3D_RS_STENCILPASS);
2429 D3DSTATE_TO_STR(WINED3D_RS_STENCILFUNC);
2430 D3DSTATE_TO_STR(WINED3D_RS_STENCILREF);
2431 D3DSTATE_TO_STR(WINED3D_RS_STENCILMASK);
2432 D3DSTATE_TO_STR(WINED3D_RS_STENCILWRITEMASK);
2433 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREFACTOR);
2434 D3DSTATE_TO_STR(WINED3D_RS_WRAP0);
2435 D3DSTATE_TO_STR(WINED3D_RS_WRAP1);
2436 D3DSTATE_TO_STR(WINED3D_RS_WRAP2);
2437 D3DSTATE_TO_STR(WINED3D_RS_WRAP3);
2438 D3DSTATE_TO_STR(WINED3D_RS_WRAP4);
2439 D3DSTATE_TO_STR(WINED3D_RS_WRAP5);
2440 D3DSTATE_TO_STR(WINED3D_RS_WRAP6);
2441 D3DSTATE_TO_STR(WINED3D_RS_WRAP7);
2442 D3DSTATE_TO_STR(WINED3D_RS_CLIPPING);
2443 D3DSTATE_TO_STR(WINED3D_RS_LIGHTING);
2444 D3DSTATE_TO_STR(WINED3D_RS_EXTENTS);
2445 D3DSTATE_TO_STR(WINED3D_RS_AMBIENT);
2446 D3DSTATE_TO_STR(WINED3D_RS_FOGVERTEXMODE);
2447 D3DSTATE_TO_STR(WINED3D_RS_COLORVERTEX);
2448 D3DSTATE_TO_STR(WINED3D_RS_LOCALVIEWER);
2449 D3DSTATE_TO_STR(WINED3D_RS_NORMALIZENORMALS);
2450 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYBLENDENABLE);
2451 D3DSTATE_TO_STR(WINED3D_RS_DIFFUSEMATERIALSOURCE);
2452 D3DSTATE_TO_STR(WINED3D_RS_SPECULARMATERIALSOURCE);
2453 D3DSTATE_TO_STR(WINED3D_RS_AMBIENTMATERIALSOURCE);
2454 D3DSTATE_TO_STR(WINED3D_RS_EMISSIVEMATERIALSOURCE);
2455 D3DSTATE_TO_STR(WINED3D_RS_VERTEXBLEND);
2456 D3DSTATE_TO_STR(WINED3D_RS_CLIPPLANEENABLE);
2457 D3DSTATE_TO_STR(WINED3D_RS_SOFTWAREVERTEXPROCESSING);
2458 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE);
2459 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MIN);
2460 D3DSTATE_TO_STR(WINED3D_RS_POINTSPRITEENABLE);
2461 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALEENABLE);
2462 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_A);
2463 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_B);
2464 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_C);
2465 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEANTIALIAS);
2466 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEMASK);
2467 D3DSTATE_TO_STR(WINED3D_RS_PATCHEDGESTYLE);
2468 D3DSTATE_TO_STR(WINED3D_RS_PATCHSEGMENTS);
2469 D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN);
2470 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX);
2471 D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE);
2472 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
2473 D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR);
2474 D3DSTATE_TO_STR(WINED3D_RS_BLENDOP);
2475 D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE);
2476 D3DSTATE_TO_STR(WINED3D_RS_NORMALDEGREE);
2477 D3DSTATE_TO_STR(WINED3D_RS_SCISSORTESTENABLE);
2478 D3DSTATE_TO_STR(WINED3D_RS_SLOPESCALEDEPTHBIAS);
2479 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIASEDLINEENABLE);
2480 D3DSTATE_TO_STR(WINED3D_RS_MINTESSELLATIONLEVEL);
2481 D3DSTATE_TO_STR(WINED3D_RS_MAXTESSELLATIONLEVEL);
2482 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_X);
2483 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Y);
2484 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Z);
2485 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_W);
2486 D3DSTATE_TO_STR(WINED3D_RS_ENABLEADAPTIVETESSELLATION);
2487 D3DSTATE_TO_STR(WINED3D_RS_TWOSIDEDSTENCILMODE);
2488 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFAIL);
2489 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILZFAIL);
2490 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILPASS);
2491 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFUNC);
2492 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1);
2493 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2);
2494 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3);
2495 D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR);
2496 D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE);
2497 D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS);
2498 D3DSTATE_TO_STR(WINED3D_RS_WRAP8);
2499 D3DSTATE_TO_STR(WINED3D_RS_WRAP9);
2500 D3DSTATE_TO_STR(WINED3D_RS_WRAP10);
2501 D3DSTATE_TO_STR(WINED3D_RS_WRAP11);
2502 D3DSTATE_TO_STR(WINED3D_RS_WRAP12);
2503 D3DSTATE_TO_STR(WINED3D_RS_WRAP13);
2504 D3DSTATE_TO_STR(WINED3D_RS_WRAP14);
2505 D3DSTATE_TO_STR(WINED3D_RS_WRAP15);
2506 D3DSTATE_TO_STR(WINED3D_RS_SEPARATEALPHABLENDENABLE);
2507 D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
2508 D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
2509 D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
2510 #undef D3DSTATE_TO_STR
2511 default:
2512 FIXME("Unrecognized %u render state!\n", state);
2513 return "unrecognized";
2517 const char *debug_d3dsamplerstate(enum wined3d_sampler_state state)
2519 switch (state)
2521 #define D3DSTATE_TO_STR(u) case u: return #u
2522 D3DSTATE_TO_STR(WINED3D_SAMP_BORDER_COLOR);
2523 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_U);
2524 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_V);
2525 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_W);
2526 D3DSTATE_TO_STR(WINED3D_SAMP_MAG_FILTER);
2527 D3DSTATE_TO_STR(WINED3D_SAMP_MIN_FILTER);
2528 D3DSTATE_TO_STR(WINED3D_SAMP_MIP_FILTER);
2529 D3DSTATE_TO_STR(WINED3D_SAMP_MIPMAP_LOD_BIAS);
2530 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_MIP_LEVEL);
2531 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_ANISOTROPY);
2532 D3DSTATE_TO_STR(WINED3D_SAMP_SRGB_TEXTURE);
2533 D3DSTATE_TO_STR(WINED3D_SAMP_ELEMENT_INDEX);
2534 D3DSTATE_TO_STR(WINED3D_SAMP_DMAP_OFFSET);
2535 #undef D3DSTATE_TO_STR
2536 default:
2537 FIXME("Unrecognized %u sampler state!\n", state);
2538 return "unrecognized";
2542 const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type)
2544 switch (filter_type)
2546 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2547 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_NONE);
2548 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_POINT);
2549 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_LINEAR);
2550 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_ANISOTROPIC);
2551 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_FLAT_CUBIC);
2552 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_CUBIC);
2553 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_PYRAMIDAL_QUAD);
2554 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_QUAD);
2555 #undef D3DTEXTUREFILTERTYPE_TO_STR
2556 default:
2557 FIXME("Unrecognied texture filter type 0x%08x.\n", filter_type);
2558 return "unrecognized";
2562 const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state)
2564 switch (state)
2566 #define D3DSTATE_TO_STR(u) case u: return #u
2567 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_OP);
2568 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG1);
2569 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG2);
2570 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_OP);
2571 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG1);
2572 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG2);
2573 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT00);
2574 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT01);
2575 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT10);
2576 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT11);
2577 D3DSTATE_TO_STR(WINED3D_TSS_TEXCOORD_INDEX);
2578 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LSCALE);
2579 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LOFFSET);
2580 D3DSTATE_TO_STR(WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS);
2581 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG0);
2582 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG0);
2583 D3DSTATE_TO_STR(WINED3D_TSS_RESULT_ARG);
2584 D3DSTATE_TO_STR(WINED3D_TSS_CONSTANT);
2585 #undef D3DSTATE_TO_STR
2586 default:
2587 FIXME("Unrecognized %u texture state!\n", state);
2588 return "unrecognized";
2592 const char *debug_d3dtop(enum wined3d_texture_op d3dtop)
2594 switch (d3dtop)
2596 #define D3DTOP_TO_STR(u) case u: return #u
2597 D3DTOP_TO_STR(WINED3D_TOP_DISABLE);
2598 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG1);
2599 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG2);
2600 D3DTOP_TO_STR(WINED3D_TOP_MODULATE);
2601 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_2X);
2602 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_4X);
2603 D3DTOP_TO_STR(WINED3D_TOP_ADD);
2604 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED);
2605 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED_2X);
2606 D3DTOP_TO_STR(WINED3D_TOP_SUBTRACT);
2607 D3DTOP_TO_STR(WINED3D_TOP_ADD_SMOOTH);
2608 D3DTOP_TO_STR(WINED3D_TOP_BLEND_DIFFUSE_ALPHA);
2609 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA);
2610 D3DTOP_TO_STR(WINED3D_TOP_BLEND_FACTOR_ALPHA);
2611 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM);
2612 D3DTOP_TO_STR(WINED3D_TOP_BLEND_CURRENT_ALPHA);
2613 D3DTOP_TO_STR(WINED3D_TOP_PREMODULATE);
2614 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR);
2615 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA);
2616 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR);
2617 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA);
2618 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP);
2619 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP_LUMINANCE);
2620 D3DTOP_TO_STR(WINED3D_TOP_DOTPRODUCT3);
2621 D3DTOP_TO_STR(WINED3D_TOP_MULTIPLY_ADD);
2622 D3DTOP_TO_STR(WINED3D_TOP_LERP);
2623 #undef D3DTOP_TO_STR
2624 default:
2625 FIXME("Unrecognized texture op %#x.\n", d3dtop);
2626 return "unrecognized";
2630 const char *debug_d3dtstype(enum wined3d_transform_state tstype)
2632 switch (tstype)
2634 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2635 TSTYPE_TO_STR(WINED3D_TS_VIEW);
2636 TSTYPE_TO_STR(WINED3D_TS_PROJECTION);
2637 TSTYPE_TO_STR(WINED3D_TS_TEXTURE0);
2638 TSTYPE_TO_STR(WINED3D_TS_TEXTURE1);
2639 TSTYPE_TO_STR(WINED3D_TS_TEXTURE2);
2640 TSTYPE_TO_STR(WINED3D_TS_TEXTURE3);
2641 TSTYPE_TO_STR(WINED3D_TS_TEXTURE4);
2642 TSTYPE_TO_STR(WINED3D_TS_TEXTURE5);
2643 TSTYPE_TO_STR(WINED3D_TS_TEXTURE6);
2644 TSTYPE_TO_STR(WINED3D_TS_TEXTURE7);
2645 TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(0));
2646 #undef TSTYPE_TO_STR
2647 default:
2648 if (tstype > 256 && tstype < 512)
2650 FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype);
2651 return ("WINED3D_TS_WORLD_MATRIX > 0");
2653 FIXME("Unrecognized transform state %#x.\n", tstype);
2654 return "unrecognized";
2658 static const char *debug_shader_type(enum wined3d_shader_type type)
2660 switch(type)
2662 #define WINED3D_TO_STR(type) case type: return #type
2663 WINED3D_TO_STR(WINED3D_SHADER_TYPE_PIXEL);
2664 WINED3D_TO_STR(WINED3D_SHADER_TYPE_VERTEX);
2665 WINED3D_TO_STR(WINED3D_SHADER_TYPE_GEOMETRY);
2666 #undef WINED3D_TO_STR
2667 default:
2668 FIXME("Unrecognized shader type %#x.\n", type);
2669 return "unrecognized";
2673 const char *debug_d3dstate(DWORD state)
2675 if (STATE_IS_RENDER(state))
2676 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2677 if (STATE_IS_TEXTURESTAGE(state))
2679 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2680 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2681 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2682 texture_stage, debug_d3dtexturestate(texture_state));
2684 if (STATE_IS_SAMPLER(state))
2685 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2686 if (STATE_IS_SHADER(state))
2687 return wine_dbg_sprintf("STATE_SHADER(%s)", debug_shader_type(state - STATE_SHADER(0)));
2688 if (STATE_IS_CONSTANT_BUFFER(state))
2689 return wine_dbg_sprintf("STATE_CONSTANT_BUFFER(%s)", debug_shader_type(state - STATE_CONSTANT_BUFFER(0)));
2690 if (STATE_IS_TRANSFORM(state))
2691 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2692 if (STATE_IS_STREAMSRC(state))
2693 return "STATE_STREAMSRC";
2694 if (STATE_IS_INDEXBUFFER(state))
2695 return "STATE_INDEXBUFFER";
2696 if (STATE_IS_VDECL(state))
2697 return "STATE_VDECL";
2698 if (STATE_IS_VIEWPORT(state))
2699 return "STATE_VIEWPORT";
2700 if (STATE_IS_LIGHT_TYPE(state))
2701 return "STATE_LIGHT_TYPE";
2702 if (STATE_IS_ACTIVELIGHT(state))
2703 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2704 if (STATE_IS_SCISSORRECT(state))
2705 return "STATE_SCISSORRECT";
2706 if (STATE_IS_CLIPPLANE(state))
2707 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2708 if (STATE_IS_MATERIAL(state))
2709 return "STATE_MATERIAL";
2710 if (STATE_IS_FRONTFACE(state))
2711 return "STATE_FRONTFACE";
2712 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2713 return "STATE_POINTSPRITECOORDORIGIN";
2714 if (STATE_IS_BASEVERTEXINDEX(state))
2715 return "STATE_BASEVERTEXINDEX";
2716 if (STATE_IS_FRAMEBUFFER(state))
2717 return "STATE_FRAMEBUFFER";
2718 if (STATE_IS_POINT_SIZE_ENABLE(state))
2719 return "STATE_POINT_SIZE_ENABLE";
2721 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2724 const char *debug_d3dpool(enum wined3d_pool pool)
2726 switch (pool)
2728 #define POOL_TO_STR(p) case p: return #p
2729 POOL_TO_STR(WINED3D_POOL_DEFAULT);
2730 POOL_TO_STR(WINED3D_POOL_MANAGED);
2731 POOL_TO_STR(WINED3D_POOL_SYSTEM_MEM);
2732 POOL_TO_STR(WINED3D_POOL_SCRATCH);
2733 #undef POOL_TO_STR
2734 default:
2735 FIXME("Unrecognized pool %#x.\n", pool);
2736 return "unrecognized";
2740 const char *debug_fbostatus(GLenum status) {
2741 switch(status) {
2742 #define FBOSTATUS_TO_STR(u) case u: return #u
2743 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2744 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2745 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2746 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2747 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2748 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2749 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2750 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2751 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2752 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2753 #undef FBOSTATUS_TO_STR
2754 default:
2755 FIXME("Unrecognied FBO status 0x%08x\n", status);
2756 return "unrecognized";
2760 const char *debug_glerror(GLenum error) {
2761 switch(error) {
2762 #define GLERROR_TO_STR(u) case u: return #u
2763 GLERROR_TO_STR(GL_NO_ERROR);
2764 GLERROR_TO_STR(GL_INVALID_ENUM);
2765 GLERROR_TO_STR(GL_INVALID_VALUE);
2766 GLERROR_TO_STR(GL_INVALID_OPERATION);
2767 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2768 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2769 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2770 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2771 #undef GLERROR_TO_STR
2772 default:
2773 FIXME("Unrecognied GL error 0x%08x\n", error);
2774 return "unrecognized";
2778 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2780 switch(source)
2782 #define WINED3D_TO_STR(x) case x: return #x
2783 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2784 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2785 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2786 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2787 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2788 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2789 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2790 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2791 #undef WINED3D_TO_STR
2792 default:
2793 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2794 return "unrecognized";
2798 static const char *debug_complex_fixup(enum complex_fixup fixup)
2800 switch(fixup)
2802 #define WINED3D_TO_STR(x) case x: return #x
2803 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2804 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2805 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2806 WINED3D_TO_STR(COMPLEX_FIXUP_NV12);
2807 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2808 #undef WINED3D_TO_STR
2809 default:
2810 FIXME("Unrecognized complex fixup %#x\n", fixup);
2811 return "unrecognized";
2815 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2817 if (is_complex_fixup(fixup))
2819 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2820 return;
2823 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2824 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2825 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2826 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2829 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2830 enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2832 if (op == WINED3D_TOP_DISABLE)
2833 return FALSE;
2834 if (state->textures[stage])
2835 return FALSE;
2837 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2838 && op != WINED3D_TOP_SELECT_ARG2)
2839 return TRUE;
2840 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2841 && op != WINED3D_TOP_SELECT_ARG1)
2842 return TRUE;
2843 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2844 && (op == WINED3D_TOP_MULTIPLY_ADD || op == WINED3D_TOP_LERP))
2845 return TRUE;
2847 return FALSE;
2850 /* Setup this textures matrix according to the texture flags. */
2851 /* Context activation is done by the caller (state handler). */
2852 void set_texture_matrix(const struct wined3d_gl_info *gl_info, const float *smat, DWORD flags,
2853 BOOL calculatedCoords, BOOL transformed, enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2855 float mat[16];
2857 gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
2858 checkGLcall("glMatrixMode(GL_TEXTURE)");
2860 if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed)
2862 gl_info->gl_ops.gl.p_glLoadIdentity();
2863 checkGLcall("glLoadIdentity()");
2864 return;
2867 if (flags == (WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED))
2869 ERR("Invalid texture transform flags: WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED.\n");
2870 return;
2873 memcpy(mat, smat, 16 * sizeof(float));
2875 if (flags & WINED3D_TTFF_PROJECTED)
2877 if (!ffp_proj_control)
2879 switch (flags & ~WINED3D_TTFF_PROJECTED)
2881 case WINED3D_TTFF_COUNT2:
2882 mat[ 3] = mat[ 1];
2883 mat[ 7] = mat[ 5];
2884 mat[11] = mat[ 9];
2885 mat[15] = mat[13];
2886 mat[ 1] = mat[ 5] = mat[ 9] = mat[13] = 0.0f;
2887 break;
2888 case WINED3D_TTFF_COUNT3:
2889 mat[ 3] = mat[ 2];
2890 mat[ 7] = mat[ 6];
2891 mat[11] = mat[10];
2892 mat[15] = mat[14];
2893 mat[ 2] = mat[ 6] = mat[10] = mat[14] = 0.0f;
2894 break;
2897 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2898 if(!calculatedCoords) {
2899 switch(vtx_fmt)
2901 case WINED3DFMT_R32_FLOAT:
2902 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2903 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2904 * the input value to the transformation will be 0, so the matrix value is irrelevant
2906 mat[12] = mat[4];
2907 mat[13] = mat[5];
2908 mat[14] = mat[6];
2909 mat[15] = mat[7];
2910 break;
2911 case WINED3DFMT_R32G32_FLOAT:
2912 /* See above, just 3rd and 4th coord
2914 mat[12] = mat[8];
2915 mat[13] = mat[9];
2916 mat[14] = mat[10];
2917 mat[15] = mat[11];
2918 break;
2919 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2920 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2922 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2923 * into a bad place. The division elimination below will apply to make sure the
2924 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2926 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2927 break;
2928 default:
2929 FIXME("Unexpected fixed function texture coord input\n");
2932 if (!ffp_proj_control)
2934 switch (flags & ~WINED3D_TTFF_PROJECTED)
2936 /* case WINED3D_TTFF_COUNT1: Won't ever get here. */
2937 case WINED3D_TTFF_COUNT2:
2938 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2939 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2940 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2941 * the 4th coord evaluates to 1.0 to eliminate that.
2943 * If the fixed function pipeline is used, the 4th value remains unused,
2944 * so there is no danger in doing this. With vertex shaders we have a
2945 * problem. Should an app hit that problem, the code here would have to
2946 * check for pixel shaders, and the shader has to undo the default gl divide.
2948 * A more serious problem occurs if the app passes 4 coordinates in, and the
2949 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2950 * or a replacement shader. */
2951 default:
2952 mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2957 gl_info->gl_ops.gl.p_glLoadMatrixf(mat);
2958 checkGLcall("glLoadMatrixf(mat)");
2961 /* This small helper function is used to convert a bitmask into the number of masked bits */
2962 unsigned int count_bits(unsigned int mask)
2964 unsigned int count;
2965 for (count = 0; mask; ++count)
2967 mask &= mask - 1;
2969 return count;
2972 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2973 * The later function requires individual color components. */
2974 BOOL getColorBits(const struct wined3d_format *format,
2975 BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2977 TRACE("format %s.\n", debug_d3dformat(format->id));
2979 switch (format->id)
2981 case WINED3DFMT_B10G10R10A2_UNORM:
2982 case WINED3DFMT_R10G10B10A2_UNORM:
2983 case WINED3DFMT_B8G8R8X8_UNORM:
2984 case WINED3DFMT_B8G8R8_UNORM:
2985 case WINED3DFMT_B8G8R8A8_UNORM:
2986 case WINED3DFMT_R8G8B8A8_UNORM:
2987 case WINED3DFMT_B5G5R5X1_UNORM:
2988 case WINED3DFMT_B5G5R5A1_UNORM:
2989 case WINED3DFMT_B5G6R5_UNORM:
2990 case WINED3DFMT_B4G4R4X4_UNORM:
2991 case WINED3DFMT_B4G4R4A4_UNORM:
2992 case WINED3DFMT_B2G3R3_UNORM:
2993 case WINED3DFMT_P8_UINT_A8_UNORM:
2994 case WINED3DFMT_P8_UINT:
2995 break;
2996 default:
2997 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2998 return FALSE;
3001 *redSize = format->red_size;
3002 *greenSize = format->green_size;
3003 *blueSize = format->blue_size;
3004 *alphaSize = format->alpha_size;
3005 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
3007 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
3008 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
3009 return TRUE;
3012 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
3013 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
3015 TRACE("format %s.\n", debug_d3dformat(format->id));
3017 switch (format->id)
3019 case WINED3DFMT_D16_LOCKABLE:
3020 case WINED3DFMT_D16_UNORM:
3021 case WINED3DFMT_S1_UINT_D15_UNORM:
3022 case WINED3DFMT_X8D24_UNORM:
3023 case WINED3DFMT_S4X4_UINT_D24_UNORM:
3024 case WINED3DFMT_D24_UNORM_S8_UINT:
3025 case WINED3DFMT_S8_UINT_D24_FLOAT:
3026 case WINED3DFMT_D32_UNORM:
3027 case WINED3DFMT_D32_FLOAT:
3028 case WINED3DFMT_INTZ:
3029 break;
3030 default:
3031 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
3032 return FALSE;
3035 *depthSize = format->depth_size;
3036 *stencilSize = format->stencil_size;
3038 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
3039 *depthSize, *stencilSize, debug_d3dformat(format->id));
3040 return TRUE;
3043 /* Note: It's the caller's responsibility to ensure values can be expressed
3044 * in the requested format. UNORM formats for example can only express values
3045 * in the range 0.0f -> 1.0f. */
3046 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color)
3048 static const struct
3050 enum wined3d_format_id format_id;
3051 float r_mul;
3052 float g_mul;
3053 float b_mul;
3054 float a_mul;
3055 BYTE r_shift;
3056 BYTE g_shift;
3057 BYTE b_shift;
3058 BYTE a_shift;
3060 conv[] =
3062 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
3063 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
3064 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
3065 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
3066 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
3067 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
3068 {WINED3DFMT_R8_UNORM, 255.0f, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0},
3069 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
3070 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
3071 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
3072 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
3073 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
3074 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
3075 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
3076 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
3077 {WINED3DFMT_P8_UINT, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
3079 const struct wined3d_format *format = surface->resource.format;
3080 unsigned int i;
3082 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
3083 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
3085 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
3087 DWORD ret;
3089 if (format->id != conv[i].format_id) continue;
3091 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
3092 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
3093 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
3094 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
3096 TRACE("Returning 0x%08x.\n", ret);
3098 return ret;
3101 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
3103 return 0;
3106 /* DirectDraw stuff */
3107 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
3109 switch (depth)
3111 case 8: return WINED3DFMT_P8_UINT;
3112 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
3113 case 16: return WINED3DFMT_B5G6R5_UNORM;
3114 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
3115 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
3116 default: return WINED3DFMT_UNKNOWN;
3120 void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
3121 const struct wined3d_matrix *src2)
3123 struct wined3d_matrix temp;
3125 /* Now do the multiplication 'by hand'.
3126 I know that all this could be optimised, but this will be done later :-) */
3127 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);
3128 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);
3129 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);
3130 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);
3132 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);
3133 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);
3134 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);
3135 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);
3137 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);
3138 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);
3139 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);
3140 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);
3142 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);
3143 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);
3144 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);
3145 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);
3147 /* And copy the new matrix in the good storage.. */
3148 memcpy(dest, &temp, 16 * sizeof(float));
3151 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
3152 DWORD size = 0;
3153 int i;
3154 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
3156 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
3157 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
3158 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
3159 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
3160 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
3161 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
3162 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
3163 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
3164 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
3165 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
3166 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
3167 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
3168 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
3169 default: ERR("Unexpected position mask\n");
3171 for (i = 0; i < numTextures; i++) {
3172 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
3175 return size;
3178 void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d_state *state,
3179 struct ffp_frag_settings *settings, BOOL ignore_textype)
3181 #define ARG1 0x01
3182 #define ARG2 0x02
3183 #define ARG0 0x04
3184 static const unsigned char args[WINED3D_TOP_LERP + 1] =
3186 /* undefined */ 0,
3187 /* D3DTOP_DISABLE */ 0,
3188 /* D3DTOP_SELECTARG1 */ ARG1,
3189 /* D3DTOP_SELECTARG2 */ ARG2,
3190 /* D3DTOP_MODULATE */ ARG1 | ARG2,
3191 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
3192 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
3193 /* D3DTOP_ADD */ ARG1 | ARG2,
3194 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
3195 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
3196 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
3197 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
3198 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
3199 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
3200 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
3201 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
3202 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
3203 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
3204 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
3205 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
3206 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
3207 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
3208 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
3209 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
3210 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
3211 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
3212 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
3214 unsigned int i;
3215 DWORD ttff;
3216 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
3217 const struct wined3d_format *rt_format = state->fb->render_targets[0]->format;
3218 const struct wined3d_gl_info *gl_info = context->gl_info;
3219 const struct wined3d_d3d_info *d3d_info = context->d3d_info;
3221 for (i = 0; i < d3d_info->limits.ffp_blend_stages; ++i)
3223 const struct wined3d_texture *texture;
3225 settings->op[i].padding = 0;
3226 if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
3228 settings->op[i].cop = WINED3D_TOP_DISABLE;
3229 settings->op[i].aop = WINED3D_TOP_DISABLE;
3230 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
3231 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
3232 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
3233 settings->op[i].dst = resultreg;
3234 settings->op[i].tex_type = tex_1d;
3235 settings->op[i].projected = proj_none;
3236 i++;
3237 break;
3240 if ((texture = state->textures[i]))
3242 settings->op[i].color_fixup = texture->resource.format->color_fixup;
3243 if (ignore_textype)
3245 settings->op[i].tex_type = tex_1d;
3247 else
3249 switch (texture->target)
3251 case GL_TEXTURE_1D:
3252 settings->op[i].tex_type = tex_1d;
3253 break;
3254 case GL_TEXTURE_2D:
3255 settings->op[i].tex_type = tex_2d;
3256 break;
3257 case GL_TEXTURE_3D:
3258 settings->op[i].tex_type = tex_3d;
3259 break;
3260 case GL_TEXTURE_CUBE_MAP_ARB:
3261 settings->op[i].tex_type = tex_cube;
3262 break;
3263 case GL_TEXTURE_RECTANGLE_ARB:
3264 settings->op[i].tex_type = tex_rect;
3265 break;
3268 } else {
3269 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
3270 settings->op[i].tex_type = tex_1d;
3273 cop = state->texture_states[i][WINED3D_TSS_COLOR_OP];
3274 aop = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
3276 carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG1] : ARG_UNUSED;
3277 carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG2] : ARG_UNUSED;
3278 carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG0] : ARG_UNUSED;
3280 if (is_invalid_op(state, i, cop, carg1, carg2, carg0))
3282 carg0 = ARG_UNUSED;
3283 carg2 = ARG_UNUSED;
3284 carg1 = WINED3DTA_CURRENT;
3285 cop = WINED3D_TOP_SELECT_ARG1;
3288 if (cop == WINED3D_TOP_DOTPRODUCT3)
3290 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
3291 * the color result to the alpha component of the destination
3293 aop = cop;
3294 aarg1 = carg1;
3295 aarg2 = carg2;
3296 aarg0 = carg0;
3298 else
3300 aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] : ARG_UNUSED;
3301 aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] : ARG_UNUSED;
3302 aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] : ARG_UNUSED;
3305 if (!i && state->textures[0] && state->render_states[WINED3D_RS_COLORKEYENABLE])
3307 GLenum texture_dimensions;
3309 texture = state->textures[0];
3310 texture_dimensions = texture->target;
3312 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3314 if (texture->color_key_flags & WINEDDSD_CKSRCBLT && !texture->resource.format->alpha_size)
3316 if (aop == WINED3D_TOP_DISABLE)
3318 aarg1 = WINED3DTA_TEXTURE;
3319 aop = WINED3D_TOP_SELECT_ARG1;
3321 else if (aop == WINED3D_TOP_SELECT_ARG1 && aarg1 != WINED3DTA_TEXTURE)
3323 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3325 aarg2 = WINED3DTA_TEXTURE;
3326 aop = WINED3D_TOP_MODULATE;
3328 else aarg1 = WINED3DTA_TEXTURE;
3330 else if (aop == WINED3D_TOP_SELECT_ARG2 && aarg2 != WINED3DTA_TEXTURE)
3332 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3334 aarg1 = WINED3DTA_TEXTURE;
3335 aop = WINED3D_TOP_MODULATE;
3337 else aarg2 = WINED3DTA_TEXTURE;
3343 if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0))
3345 aarg0 = ARG_UNUSED;
3346 aarg2 = ARG_UNUSED;
3347 aarg1 = WINED3DTA_CURRENT;
3348 aop = WINED3D_TOP_SELECT_ARG1;
3351 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
3352 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
3354 ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
3355 if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3))
3356 settings->op[i].projected = proj_count3;
3357 else if (ttff & WINED3D_TTFF_PROJECTED)
3358 settings->op[i].projected = proj_count4;
3359 else
3360 settings->op[i].projected = proj_none;
3362 else
3364 settings->op[i].projected = proj_none;
3367 settings->op[i].cop = cop;
3368 settings->op[i].aop = aop;
3369 settings->op[i].carg0 = carg0;
3370 settings->op[i].carg1 = carg1;
3371 settings->op[i].carg2 = carg2;
3372 settings->op[i].aarg0 = aarg0;
3373 settings->op[i].aarg1 = aarg1;
3374 settings->op[i].aarg2 = aarg2;
3376 if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP)
3377 settings->op[i].dst = tempreg;
3378 else
3379 settings->op[i].dst = resultreg;
3382 /* Clear unsupported stages */
3383 for(; i < MAX_TEXTURES; i++) {
3384 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
3387 if (!state->render_states[WINED3D_RS_FOGENABLE])
3389 settings->fog = WINED3D_FFP_PS_FOG_OFF;
3391 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
3393 if (use_vs(state) || state->vertex_declaration->position_transformed)
3395 settings->fog = WINED3D_FFP_PS_FOG_LINEAR;
3397 else
3399 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
3401 case WINED3D_FOG_NONE:
3402 case WINED3D_FOG_LINEAR:
3403 settings->fog = WINED3D_FFP_PS_FOG_LINEAR;
3404 break;
3405 case WINED3D_FOG_EXP:
3406 settings->fog = WINED3D_FFP_PS_FOG_EXP;
3407 break;
3408 case WINED3D_FOG_EXP2:
3409 settings->fog = WINED3D_FFP_PS_FOG_EXP2;
3410 break;
3414 else
3416 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
3418 case WINED3D_FOG_LINEAR:
3419 settings->fog = WINED3D_FFP_PS_FOG_LINEAR;
3420 break;
3421 case WINED3D_FOG_EXP:
3422 settings->fog = WINED3D_FFP_PS_FOG_EXP;
3423 break;
3424 case WINED3D_FOG_EXP2:
3425 settings->fog = WINED3D_FFP_PS_FOG_EXP2;
3426 break;
3429 if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB]
3430 && state->render_states[WINED3D_RS_SRGBWRITEENABLE]
3431 && rt_format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
3433 settings->sRGB_write = 1;
3434 } else {
3435 settings->sRGB_write = 0;
3437 if (d3d_info->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
3438 || !state->render_states[WINED3D_RS_CLIPPLANEENABLE])
3440 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3441 * the fixed function vertex pipeline is used(which always supports clipplanes), or
3442 * if no clipplane is enabled
3444 settings->emul_clipplanes = 0;
3445 } else {
3446 settings->emul_clipplanes = 1;
3450 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3451 const struct ffp_frag_settings *settings)
3453 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3454 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3457 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3459 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3460 * whereas desc points to an extended structure with implementation specific parts. */
3461 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3463 ERR("Failed to insert ffp frag shader.\n");
3467 /* Activates the texture dimension according to the bound D3D texture. Does
3468 * not care for the colorop or correct gl texture unit (when using nvrc).
3469 * Requires the caller to activate the correct unit. */
3470 /* Context activation is done by the caller (state handler). */
3471 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3473 if (texture)
3475 switch (texture->target)
3477 case GL_TEXTURE_2D:
3478 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3479 checkGLcall("glDisable(GL_TEXTURE_3D)");
3480 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3482 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3483 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3485 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3487 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3488 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3490 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3491 checkGLcall("glEnable(GL_TEXTURE_2D)");
3492 break;
3493 case GL_TEXTURE_RECTANGLE_ARB:
3494 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3495 checkGLcall("glDisable(GL_TEXTURE_2D)");
3496 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3497 checkGLcall("glDisable(GL_TEXTURE_3D)");
3498 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3500 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3501 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3503 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_RECTANGLE_ARB);
3504 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3505 break;
3506 case GL_TEXTURE_3D:
3507 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3509 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3510 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3512 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3514 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3515 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3517 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3518 checkGLcall("glDisable(GL_TEXTURE_2D)");
3519 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D);
3520 checkGLcall("glEnable(GL_TEXTURE_3D)");
3521 break;
3522 case GL_TEXTURE_CUBE_MAP_ARB:
3523 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3524 checkGLcall("glDisable(GL_TEXTURE_2D)");
3525 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3526 checkGLcall("glDisable(GL_TEXTURE_3D)");
3527 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3529 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3530 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3532 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3533 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3534 break;
3537 else
3539 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3540 checkGLcall("glEnable(GL_TEXTURE_2D)");
3541 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3542 checkGLcall("glDisable(GL_TEXTURE_3D)");
3543 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3545 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3546 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3548 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3550 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3551 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3553 /* Binding textures is done by samplers. A dummy texture will be bound */
3557 /* Context activation is done by the caller (state handler). */
3558 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3560 DWORD sampler = state_id - STATE_SAMPLER(0);
3561 DWORD mapped_stage = context->tex_unit_map[sampler];
3563 /* No need to enable / disable anything here for unused samplers. The
3564 * tex_colorop handler takes care. Also no action is needed with pixel
3565 * shaders, or if tex_colorop will take care of this business. */
3566 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
3567 return;
3568 if (sampler >= context->lowest_disabled_stage)
3569 return;
3570 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)))
3571 return;
3573 texture_activate_dimensions(state->textures[sampler], context->gl_info);
3576 void *wined3d_rb_alloc(size_t size)
3578 return HeapAlloc(GetProcessHeap(), 0, size);
3581 void *wined3d_rb_realloc(void *ptr, size_t size)
3583 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3586 void wined3d_rb_free(void *ptr)
3588 HeapFree(GetProcessHeap(), 0, ptr);
3591 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3593 const struct ffp_frag_settings *ka = key;
3594 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3596 return memcmp(ka, kb, sizeof(*ka));
3599 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3601 wined3d_rb_alloc,
3602 wined3d_rb_realloc,
3603 wined3d_rb_free,
3604 ffp_frag_program_key_compare,
3607 void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct wined3d_stream_info *si,
3608 struct wined3d_ffp_vs_settings *settings)
3610 unsigned int coord_idx, i;
3612 if (si->position_transformed)
3614 memset(settings, 0, sizeof(*settings));
3616 settings->transformed = 1;
3617 settings->point_size = state->gl_primitive_type == GL_POINTS;
3618 if (!state->render_states[WINED3D_RS_FOGENABLE])
3619 settings->fog_mode = WINED3D_FFP_VS_FOG_OFF;
3620 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
3621 settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
3622 else
3623 settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD;
3625 for (i = 0; i < MAX_TEXTURES; ++i)
3627 coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
3628 if (coord_idx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
3629 settings->texcoords |= 1 << i;
3630 settings->texgen[i] = (state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT)
3631 & WINED3D_FFP_TCI_MASK;
3633 return;
3636 settings->transformed = 0;
3637 settings->clipping = state->render_states[WINED3D_RS_CLIPPING]
3638 && state->render_states[WINED3D_RS_CLIPPLANEENABLE];
3639 settings->normal = !!(si->use_map & (1 << WINED3D_FFP_NORMAL));
3640 settings->normalize = settings->normal && state->render_states[WINED3D_RS_NORMALIZENORMALS];
3641 settings->lighting = !!state->render_states[WINED3D_RS_LIGHTING];
3642 settings->localviewer = !!state->render_states[WINED3D_RS_LOCALVIEWER];
3643 settings->point_size = state->gl_primitive_type == GL_POINTS;
3645 if (state->render_states[WINED3D_RS_COLORVERTEX] && (si->use_map & (1 << WINED3D_FFP_DIFFUSE)))
3647 settings->diffuse_source = state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE];
3648 settings->emission_source = state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE];
3649 settings->ambient_source = state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE];
3650 settings->specular_source = state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE];
3652 else
3654 settings->diffuse_source = WINED3D_MCS_MATERIAL;
3655 settings->emission_source = WINED3D_MCS_MATERIAL;
3656 settings->ambient_source = WINED3D_MCS_MATERIAL;
3657 settings->specular_source = WINED3D_MCS_MATERIAL;
3660 settings->texcoords = 0;
3661 for (i = 0; i < MAX_TEXTURES; ++i)
3663 coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
3664 if (coord_idx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
3665 settings->texcoords |= 1 << i;
3666 settings->texgen[i] = (state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT)
3667 & WINED3D_FFP_TCI_MASK;
3670 settings->light_type = 0;
3671 for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i)
3673 if (state->lights[i])
3674 settings->light_type |= (state->lights[i]->OriginalParms.type
3675 & WINED3D_FFP_LIGHT_TYPE_MASK) << WINED3D_FFP_LIGHT_TYPE_SHIFT(i);
3678 settings->ortho_fog = 0;
3679 if (!state->render_states[WINED3D_RS_FOGENABLE])
3680 settings->fog_mode = WINED3D_FFP_VS_FOG_OFF;
3681 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
3683 settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
3685 if (state->transforms[WINED3D_TS_PROJECTION].u.m[0][3] == 0.0f
3686 && state->transforms[WINED3D_TS_PROJECTION].u.m[1][3] == 0.0f
3687 && state->transforms[WINED3D_TS_PROJECTION].u.m[2][3] == 0.0f
3688 && state->transforms[WINED3D_TS_PROJECTION].u.m[3][3] == 1.0f)
3689 settings->ortho_fog = 1;
3691 else if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE)
3692 settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD;
3693 else if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
3694 settings->fog_mode = WINED3D_FFP_VS_FOG_RANGE;
3695 else
3696 settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
3698 settings->padding = 0;
3701 static int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3703 const struct wined3d_ffp_vs_settings *ka = key;
3704 const struct wined3d_ffp_vs_settings *kb = &WINE_RB_ENTRY_VALUE(entry,
3705 const struct wined3d_ffp_vs_desc, entry)->settings;
3707 return memcmp(ka, kb, sizeof(*ka));
3710 const struct wine_rb_functions wined3d_ffp_vertex_program_rb_functions =
3712 wined3d_rb_alloc,
3713 wined3d_rb_realloc,
3714 wined3d_rb_free,
3715 wined3d_ffp_vertex_program_key_compare,
3718 UINT wined3d_log2i(UINT32 x)
3720 static const UINT l[] =
3722 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3723 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3724 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3725 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3726 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3727 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3728 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3729 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3730 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3731 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3732 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3733 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3734 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3735 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3736 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3737 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3739 UINT32 i;
3741 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3744 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3745 const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
3746 const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
3748 static const struct blit_shader * const blitters[] =
3750 &arbfp_blit,
3751 &ffp_blit,
3752 &cpu_blit,
3754 unsigned int i;
3756 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3758 if (blitters[i]->blit_supported(gl_info, blit_op,
3759 src_rect, src_usage, src_pool, src_format,
3760 dst_rect, dst_usage, dst_pool, dst_format))
3761 return blitters[i];
3764 return NULL;
3767 void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
3769 const struct wined3d_viewport *vp = &state->viewport;
3771 SetRect(rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
3773 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
3774 IntersectRect(rect, rect, &state->scissor_rect);
3777 const char *wined3d_debug_location(DWORD location)
3779 char buf[294];
3781 buf[0] = '\0';
3782 #define LOCATION_TO_STR(u) if (location & u) { strcat(buf, " | "#u); location &= ~u; }
3783 LOCATION_TO_STR(WINED3D_LOCATION_DISCARDED);
3784 LOCATION_TO_STR(WINED3D_LOCATION_SYSMEM);
3785 LOCATION_TO_STR(WINED3D_LOCATION_USER_MEMORY);
3786 LOCATION_TO_STR(WINED3D_LOCATION_DIB);
3787 LOCATION_TO_STR(WINED3D_LOCATION_BUFFER);
3788 LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_RGB);
3789 LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_SRGB);
3790 LOCATION_TO_STR(WINED3D_LOCATION_DRAWABLE);
3791 LOCATION_TO_STR(WINED3D_LOCATION_RB_MULTISAMPLE);
3792 LOCATION_TO_STR(WINED3D_LOCATION_RB_RESOLVED);
3793 #undef LOCATION_TO_STR
3794 if (location) FIXME("Unrecognized location flag(s) %#x.\n", location);
3796 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
3799 /* Print a floating point value with the %.8e format specifier, always using
3800 * '.' as decimal separator. */
3801 void wined3d_ftoa(float value, char *s)
3803 int idx = 1;
3805 if (copysignf(1.0f, value) < 0.0f)
3806 ++idx;
3808 /* Be sure to allocate a buffer of at least 17 characters for the result
3809 as sprintf may return a 3 digit exponent when using the MSVC runtime
3810 instead of a 2 digit exponent. */
3811 sprintf(s, "%.8e", value);
3812 if (isfinite(value))
3813 s[idx] = '.';
3816 void wined3d_release_dc(HWND window, HDC dc)
3818 /* You'd figure ReleaseDC() would fail if the DC doesn't match the window.
3819 * However, that's not what actually happens, and there are user32 tests
3820 * that confirm ReleaseDC() with the wrong window is supposed to succeed.
3821 * So explicitly check that the DC belongs to the window, since we want to
3822 * avoid releasing a DC that belongs to some other window if the original
3823 * window was already destroyed. */
3824 if (WindowFromDC(dc) != window)
3825 WARN("DC %p does not belong to window %p.\n", dc, window);
3826 else if (!ReleaseDC(window, dc))
3827 ERR("Failed to release device context %p, last error %#x.\n", dc, GetLastError());