msvcrt: Add validity checks for _mbstrlen_l.
[wine/multimedia.git] / dlls / wined3d / utils.c
blob34a944724f27c20a617e4cfa0c2f6434f17db8f2
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 "wined3d_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
32 struct StaticPixelFormatDesc
34 enum wined3d_format_id id;
35 DWORD alphaMask, redMask, greenMask, blueMask;
36 UINT bpp;
37 BYTE depthSize, stencilSize;
40 /*****************************************************************************
41 * Pixel format array
43 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
44 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
45 * high masks do not fit into the 32 bit values needed for ddraw. It is only
46 * used for ddraw mostly, and to figure out if the format has alpha at all, so
47 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
48 * formats are not usable in 2D rendering because ddraw doesn't support them.
50 static const struct StaticPixelFormatDesc formats[] =
52 /* format id alphamask redmask greenmask bluemask bpp depth stencil */
53 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
54 /* FourCC formats */
55 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
56 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
57 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
58 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
59 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
60 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
61 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
62 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
63 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
64 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
65 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
66 /* IEEE formats */
67 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
68 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
69 {WINED3DFMT_R32G32B32_FLOAT, 0x0, 0x0, 0x0, 0x0, 12, 0, 0},
70 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0},
71 /* Hmm? */
72 {WINED3DFMT_R8G8_SNORM_Cx, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
73 /* Float */
74 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
75 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
76 {WINED3DFMT_R16G16_SINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
77 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
78 {WINED3DFMT_R16G16B16A16_SINT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
79 /* Palettized formats */
80 {WINED3DFMT_P8_UINT_A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
81 {WINED3DFMT_P8_UINT, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
82 /* Standard ARGB formats. */
83 {WINED3DFMT_B8G8R8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0},
84 {WINED3DFMT_B8G8R8A8_UNORM, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
85 {WINED3DFMT_B8G8R8X8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
86 {WINED3DFMT_B5G6R5_UNORM, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0},
87 {WINED3DFMT_B5G5R5X1_UNORM, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
88 {WINED3DFMT_B5G5R5A1_UNORM, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
89 {WINED3DFMT_B4G4R4A4_UNORM, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
90 {WINED3DFMT_B2G3R3_UNORM, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0},
91 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0},
92 {WINED3DFMT_B2G3R3A8_UNORM, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0},
93 {WINED3DFMT_B4G4R4X4_UNORM, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
94 {WINED3DFMT_R10G10B10A2_UNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
95 {WINED3DFMT_R10G10B10A2_UINT, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
96 {WINED3DFMT_R10G10B10A2_SNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
97 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
98 {WINED3DFMT_R8G8B8A8_UINT, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
99 {WINED3DFMT_R8G8B8X8_UNORM, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
100 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0},
101 {WINED3DFMT_B10G10R10A2_UNORM, 0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0},
102 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0},
103 /* Luminance */
104 {WINED3DFMT_L8_UNORM, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
105 {WINED3DFMT_L8A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
106 {WINED3DFMT_L4A4_UNORM, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0},
107 {WINED3DFMT_L16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
108 /* Bump mapping stuff */
109 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
110 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
111 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
112 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
113 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
114 {WINED3DFMT_R10G11B11_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
115 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0},
116 /* Depth stencil formats */
117 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
118 {WINED3DFMT_D32_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
119 {WINED3DFMT_S1_UINT_D15_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 15, 1},
120 {WINED3DFMT_D24_UNORM_S8_UINT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
121 {WINED3DFMT_X8D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 0},
122 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 4},
123 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
124 {WINED3DFMT_D32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
125 {WINED3DFMT_S8_UINT_D24_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
126 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
127 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
128 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
129 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
130 /* Vendor-specific formats */
131 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
132 {WINED3DFMT_NVDB, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
133 {WINED3DFMT_INTZ, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
134 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
135 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
136 {WINED3DFMT_NULL, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
137 /* Unsure about them, could not find a Windows driver that supports them */
138 {WINED3DFMT_R16, 0x0, 0x0000ffff, 0x0, 0x0, 2, 0, 0},
139 {WINED3DFMT_AL16, 0xffff0000, 0x0, 0x0, 0x0, 4, 0, 0},
142 struct wined3d_format_base_flags
144 enum wined3d_format_id id;
145 DWORD flags;
148 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
149 * still needs to use the correct block based calculation for e.g. the
150 * resource size. */
151 static const struct wined3d_format_base_flags format_base_flags[] =
153 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
154 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
155 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
156 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
157 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
158 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
159 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
160 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
161 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
162 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
163 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
164 {WINED3DFMT_INTZ, WINED3DFMT_FLAG_FOURCC},
165 {WINED3DFMT_NULL, WINED3DFMT_FLAG_FOURCC},
166 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
167 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
168 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
171 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
172 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
173 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
174 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
175 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
176 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
177 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
178 {WINED3DFMT_NVDB, WINED3DFMT_FLAG_FOURCC},
179 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
180 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
181 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
182 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
183 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
184 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
185 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
186 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
187 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
188 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
189 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
192 struct wined3d_format_block_info
194 enum wined3d_format_id id;
195 UINT block_width;
196 UINT block_height;
197 UINT block_byte_count;
200 static const struct wined3d_format_block_info format_block_info[] =
202 {WINED3DFMT_DXT1, 4, 4, 8},
203 {WINED3DFMT_DXT2, 4, 4, 16},
204 {WINED3DFMT_DXT3, 4, 4, 16},
205 {WINED3DFMT_DXT4, 4, 4, 16},
206 {WINED3DFMT_DXT5, 4, 4, 16},
207 {WINED3DFMT_ATI2N, 4, 4, 16},
208 {WINED3DFMT_YUY2, 2, 1, 4},
209 {WINED3DFMT_UYVY, 2, 1, 4},
212 struct wined3d_format_vertex_info
214 enum wined3d_format_id id;
215 enum wined3d_ffp_emit_idx emit_idx;
216 GLint component_count;
217 GLenum gl_vtx_type;
218 GLint gl_vtx_format;
219 GLboolean gl_normalized;
220 unsigned int component_size;
223 static const struct wined3d_format_vertex_info format_vertex_info[] =
225 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
226 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
227 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
228 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
229 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
230 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
231 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
232 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
233 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
234 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
235 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
236 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
237 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
238 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
239 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
240 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
241 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
244 struct wined3d_format_texture_info
246 enum wined3d_format_id id;
247 GLint gl_internal;
248 GLint gl_srgb_internal;
249 GLint gl_rt_internal;
250 GLint gl_format;
251 GLint gl_type;
252 unsigned int conv_byte_count;
253 unsigned int flags;
254 enum wined3d_gl_extension extension;
255 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
258 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
260 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
261 * format+type combination to load it. Thus convert it to A8L8, then load it
262 * with A4L4 internal, but A8L8 format+type
264 unsigned int x, y;
265 const unsigned char *Source;
266 unsigned char *Dest;
267 UINT outpitch = pitch * 2;
269 for(y = 0; y < height; y++) {
270 Source = src + y * pitch;
271 Dest = dst + y * outpitch;
272 for (x = 0; x < width; x++ ) {
273 unsigned char color = (*Source++);
274 /* A */ Dest[1] = (color & 0xf0) << 0;
275 /* L */ Dest[0] = (color & 0x0f) << 4;
276 Dest += 2;
281 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
283 unsigned int x, y;
284 const WORD *Source;
286 for(y = 0; y < height; y++)
288 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
289 Source = (const WORD *)(src + y * pitch);
290 for (x = 0; x < width; x++ )
292 short color = (*Source++);
293 unsigned char l = ((color >> 10) & 0xfc);
294 short v = ((color >> 5) & 0x3e);
295 short u = ((color ) & 0x1f);
296 short v_conv = v + 16;
297 short u_conv = u + 16;
299 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
300 Dest_s += 1;
305 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
307 unsigned int x, y;
308 const WORD *Source;
309 unsigned char *Dest;
310 UINT outpitch = (pitch * 3)/2;
312 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
313 * fixed function and shaders without further conversion once the surface is
314 * loaded
316 for(y = 0; y < height; y++) {
317 Source = (const WORD *)(src + y * pitch);
318 Dest = dst + y * outpitch;
319 for (x = 0; x < width; x++ ) {
320 short color = (*Source++);
321 unsigned char l = ((color >> 10) & 0xfc);
322 char v = ((color >> 5) & 0x3e);
323 char u = ((color ) & 0x1f);
325 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
326 * and doubles the positive range. Thus shift left only once, gl does the 2nd
327 * shift. GL reads a signed value and converts it into an unsigned value.
329 /* M */ Dest[2] = l << 1;
331 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
332 * from 5 bit values to 8 bit values.
334 /* V */ Dest[1] = v << 3;
335 /* U */ Dest[0] = u << 3;
336 Dest += 3;
341 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
343 unsigned int x, y;
344 const short *Source;
345 unsigned char *Dest;
346 UINT outpitch = (pitch * 3)/2;
348 for(y = 0; y < height; y++)
350 Source = (const short *)(src + y * pitch);
351 Dest = dst + y * outpitch;
352 for (x = 0; x < width; x++ )
354 const short color = (*Source++);
355 /* B */ Dest[0] = 0xff;
356 /* G */ Dest[1] = (color >> 8) + 128; /* V */
357 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
358 Dest += 3;
363 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
365 unsigned int x, y;
366 const DWORD *Source;
367 unsigned char *Dest;
369 /* Doesn't work correctly with the fixed function pipeline, but can work in
370 * shaders if the shader is adjusted. (There's no use for this format in gl's
371 * standard fixed function pipeline anyway).
373 for(y = 0; y < height; y++)
375 Source = (const DWORD *)(src + y * pitch);
376 Dest = dst + y * pitch;
377 for (x = 0; x < width; x++ )
379 LONG color = (*Source++);
380 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
381 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
382 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
383 Dest += 4;
388 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
390 unsigned int x, y;
391 const DWORD *Source;
392 unsigned char *Dest;
394 /* This implementation works with the fixed function pipeline and shaders
395 * without further modification after converting the surface.
397 for(y = 0; y < height; y++)
399 Source = (const DWORD *)(src + y * pitch);
400 Dest = dst + y * pitch;
401 for (x = 0; x < width; x++ )
403 LONG color = (*Source++);
404 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
405 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
406 /* U */ Dest[0] = (color & 0xff); /* U */
407 /* I */ Dest[3] = 255; /* X */
408 Dest += 4;
413 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
415 unsigned int x, y;
416 const DWORD *Source;
417 unsigned char *Dest;
419 for(y = 0; y < height; y++)
421 Source = (const DWORD *)(src + y * pitch);
422 Dest = dst + y * pitch;
423 for (x = 0; x < width; x++ )
425 LONG color = (*Source++);
426 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
427 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
428 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
429 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
430 Dest += 4;
435 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
437 unsigned int x, y;
438 const DWORD *Source;
439 unsigned short *Dest;
440 UINT outpitch = (pitch * 3)/2;
442 for(y = 0; y < height; y++)
444 Source = (const DWORD *)(src + y * pitch);
445 Dest = (unsigned short *) (dst + y * outpitch);
446 for (x = 0; x < width; x++ )
448 const DWORD color = (*Source++);
449 /* B */ Dest[0] = 0xffff;
450 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
451 /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */
452 Dest += 3;
457 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
459 unsigned int x, y;
460 const WORD *Source;
461 WORD *Dest;
462 UINT outpitch = (pitch * 3)/2;
464 for(y = 0; y < height; y++)
466 Source = (const WORD *)(src + y * pitch);
467 Dest = (WORD *) (dst + y * outpitch);
468 for (x = 0; x < width; x++ )
470 WORD green = (*Source++);
471 WORD red = (*Source++);
472 Dest[0] = green;
473 Dest[1] = red;
474 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
475 * shader overwrites it anyway
477 Dest[2] = 0xffff;
478 Dest += 3;
483 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
485 unsigned int x, y;
486 const float *Source;
487 float *Dest;
488 UINT outpitch = (pitch * 3)/2;
490 for(y = 0; y < height; y++)
492 Source = (const float *)(src + y * pitch);
493 Dest = (float *) (dst + y * outpitch);
494 for (x = 0; x < width; x++ )
496 float green = (*Source++);
497 float red = (*Source++);
498 Dest[0] = green;
499 Dest[1] = red;
500 Dest[2] = 1.0f;
501 Dest += 3;
506 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
508 unsigned int x, y;
509 UINT outpitch = pitch * 2;
511 for (y = 0; y < height; ++y)
513 const WORD *source = (const WORD *)(src + y * pitch);
514 DWORD *dest = (DWORD *)(dst + y * outpitch);
516 for (x = 0; x < width; ++x)
518 /* The depth data is normalized, so needs to be scaled,
519 * the stencil data isn't. Scale depth data by
520 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
521 WORD d15 = source[x] >> 1;
522 DWORD d24 = (d15 << 9) + (d15 >> 6);
523 dest[x] = (d24 << 8) | (source[x] & 0x1);
528 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
530 unsigned int x, y;
532 for (y = 0; y < height; ++y)
534 const DWORD *source = (const DWORD *)(src + y * pitch);
535 DWORD *dest = (DWORD *)(dst + y * pitch);
537 for (x = 0; x < width; ++x)
539 /* Just need to clear out the X4 part. */
540 dest[x] = source[x] & ~0xf0;
545 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
547 unsigned int x, y;
548 UINT outpitch = pitch * 2;
550 for (y = 0; y < height; ++y)
552 const DWORD *source = (const DWORD *)(src + y * pitch);
553 float *dest_f = (float *)(dst + y * outpitch);
554 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
556 for (x = 0; x < width; ++x)
558 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
559 dest_s[x * 2 + 1] = source[x] & 0xff;
564 static const struct wined3d_format_texture_info format_texture_info[] =
566 /* format id internal srgbInternal rtInternal
567 format type
568 flags
569 extension */
570 /* FourCC formats */
571 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
572 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
573 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
574 * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
575 * endian machine
577 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
578 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
579 WINED3DFMT_FLAG_FILTERING,
580 WINED3D_GL_EXT_NONE, NULL},
581 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
582 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
583 WINED3DFMT_FLAG_FILTERING,
584 APPLE_YCBCR_422, NULL},
585 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
586 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
587 WINED3DFMT_FLAG_FILTERING,
588 WINED3D_GL_EXT_NONE, NULL},
589 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
590 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
591 WINED3DFMT_FLAG_FILTERING,
592 APPLE_YCBCR_422, NULL},
593 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
594 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
595 WINED3DFMT_FLAG_FILTERING,
596 WINED3D_GL_EXT_NONE, NULL},
597 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
598 GL_RGBA, GL_UNSIGNED_BYTE, 0,
599 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
600 | WINED3DFMT_FLAG_COMPRESSED,
601 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
602 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
603 GL_RGBA, GL_UNSIGNED_BYTE, 0,
604 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
605 | WINED3DFMT_FLAG_COMPRESSED,
606 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
607 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
608 GL_RGBA, GL_UNSIGNED_BYTE, 0,
609 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
610 | WINED3DFMT_FLAG_COMPRESSED,
611 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
612 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
613 GL_RGBA, GL_UNSIGNED_BYTE, 0,
614 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
615 | WINED3DFMT_FLAG_COMPRESSED,
616 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
617 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
618 GL_RGBA, GL_UNSIGNED_BYTE, 0,
619 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
620 | WINED3DFMT_FLAG_COMPRESSED,
621 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
622 /* IEEE formats */
623 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
624 GL_RED, GL_FLOAT, 0,
625 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
626 ARB_TEXTURE_FLOAT, NULL},
627 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
628 GL_RED, GL_FLOAT, 0,
629 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
630 ARB_TEXTURE_RG, NULL},
631 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
632 GL_RGB, GL_FLOAT, 12,
633 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
634 ARB_TEXTURE_FLOAT, convert_r32g32_float},
635 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
636 GL_RG, GL_FLOAT, 0,
637 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
638 ARB_TEXTURE_RG, NULL},
639 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
640 GL_RGBA, GL_FLOAT, 0,
641 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
642 ARB_TEXTURE_FLOAT, NULL},
643 /* Float */
644 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
645 GL_RED, GL_HALF_FLOAT_ARB, 0,
646 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
647 ARB_TEXTURE_FLOAT, NULL},
648 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
649 GL_RED, GL_HALF_FLOAT_ARB, 0,
650 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
651 ARB_TEXTURE_RG, NULL},
652 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
653 GL_RGB, GL_HALF_FLOAT_ARB, 6,
654 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
655 ARB_TEXTURE_FLOAT, convert_r16g16},
656 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
657 GL_RG, GL_HALF_FLOAT_ARB, 0,
658 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
659 ARB_TEXTURE_RG, NULL},
660 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
661 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
662 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
663 ARB_TEXTURE_FLOAT, NULL},
664 /* Palettized formats */
665 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
666 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
668 ARB_FRAGMENT_PROGRAM, NULL},
669 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
670 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
672 EXT_PALETTED_TEXTURE, NULL},
673 /* Standard ARGB formats */
674 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
675 GL_BGR, GL_UNSIGNED_BYTE, 0,
676 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
677 WINED3D_GL_EXT_NONE, NULL},
678 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
679 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
680 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
681 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE | WINED3DFMT_FLAG_VTF,
682 WINED3D_GL_EXT_NONE, NULL},
683 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
684 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
685 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
686 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
687 WINED3D_GL_EXT_NONE, NULL},
688 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
689 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
690 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
691 WINED3D_GL_EXT_NONE, NULL},
692 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
693 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
694 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
695 WINED3D_GL_EXT_NONE, NULL},
696 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
697 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
698 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
699 WINED3D_GL_EXT_NONE, NULL},
700 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
701 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
702 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
703 WINED3D_GL_EXT_NONE, NULL},
704 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
705 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
706 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
707 WINED3D_GL_EXT_NONE, NULL},
708 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
709 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
710 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
711 WINED3D_GL_EXT_NONE, NULL},
712 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
713 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
714 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
715 WINED3D_GL_EXT_NONE, NULL},
716 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
717 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
718 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
719 WINED3D_GL_EXT_NONE, NULL},
720 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
721 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
722 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
723 WINED3D_GL_EXT_NONE, NULL},
724 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
725 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
726 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
727 WINED3D_GL_EXT_NONE, NULL},
728 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
729 GL_RGB, GL_UNSIGNED_SHORT, 6,
730 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
731 WINED3D_GL_EXT_NONE, convert_r16g16},
732 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
733 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
734 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
735 WINED3D_GL_EXT_NONE, NULL},
736 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
737 GL_RGBA, GL_UNSIGNED_SHORT, 0,
738 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
739 WINED3D_GL_EXT_NONE, NULL},
740 /* Luminance */
741 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
742 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
743 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
744 WINED3D_GL_EXT_NONE, NULL},
745 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
746 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
747 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
748 WINED3D_GL_EXT_NONE, NULL},
749 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
750 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
751 WINED3DFMT_FLAG_FILTERING,
752 WINED3D_GL_EXT_NONE, convert_l4a4_unorm},
753 /* Bump mapping stuff */
754 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
755 GL_BGR, GL_UNSIGNED_BYTE, 3,
756 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
757 WINED3D_GL_EXT_NONE, convert_r8g8_snorm},
758 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
759 GL_DSDT_NV, GL_BYTE, 0,
760 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
761 NV_TEXTURE_SHADER, NULL},
762 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
763 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
764 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
765 WINED3D_GL_EXT_NONE, convert_r5g5_snorm_l6_unorm},
766 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
767 GL_DSDT_MAG_NV, GL_BYTE, 3,
768 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
769 NV_TEXTURE_SHADER, convert_r5g5_snorm_l6_unorm_nv},
770 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
771 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
772 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
773 WINED3D_GL_EXT_NONE, convert_r8g8_snorm_l8x8_unorm},
774 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
775 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
776 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
777 NV_TEXTURE_SHADER, convert_r8g8_snorm_l8x8_unorm_nv},
778 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
779 GL_BGRA, GL_UNSIGNED_BYTE, 4,
780 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
781 WINED3D_GL_EXT_NONE, convert_r8g8b8a8_snorm},
782 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
783 GL_RGBA, GL_BYTE, 0,
784 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
785 NV_TEXTURE_SHADER, NULL},
786 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
787 GL_BGR, GL_UNSIGNED_SHORT, 6,
788 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
789 WINED3D_GL_EXT_NONE, convert_r16g16_snorm},
790 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
791 GL_HILO_NV, GL_SHORT, 0,
792 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
793 NV_TEXTURE_SHADER, NULL},
794 /* Depth stencil formats */
795 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
796 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
797 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
798 ARB_DEPTH_TEXTURE, NULL},
799 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
800 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
801 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
802 ARB_DEPTH_TEXTURE, NULL},
803 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
804 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
805 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
806 ARB_DEPTH_TEXTURE, NULL},
807 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
808 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
809 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
810 EXT_PACKED_DEPTH_STENCIL, convert_s1_uint_d15_unorm},
811 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
812 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
813 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
814 ARB_FRAMEBUFFER_OBJECT, convert_s1_uint_d15_unorm},
815 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
816 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
817 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
818 | WINED3DFMT_FLAG_SHADOW,
819 ARB_DEPTH_TEXTURE, NULL},
820 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
821 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
822 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
823 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
824 EXT_PACKED_DEPTH_STENCIL, NULL},
825 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
826 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
827 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
828 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
829 ARB_FRAMEBUFFER_OBJECT, NULL},
830 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
831 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
832 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
833 | WINED3DFMT_FLAG_SHADOW,
834 ARB_DEPTH_TEXTURE, NULL},
835 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
836 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
837 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
838 ARB_DEPTH_TEXTURE, NULL},
839 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
840 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
841 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
842 EXT_PACKED_DEPTH_STENCIL, convert_s4x4_uint_d24_unorm},
843 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
844 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
845 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
846 ARB_FRAMEBUFFER_OBJECT, convert_s4x4_uint_d24_unorm},
847 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
848 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
849 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
850 | WINED3DFMT_FLAG_SHADOW,
851 ARB_DEPTH_TEXTURE, NULL},
852 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
853 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
854 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
855 WINED3D_GL_EXT_NONE, NULL},
856 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
857 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
858 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
859 ARB_DEPTH_BUFFER_FLOAT, NULL},
860 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
861 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
862 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
863 ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float},
864 /* Vendor-specific formats */
865 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
866 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
867 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_COMPRESSED,
868 ATI_TEXTURE_COMPRESSION_3DC, NULL},
869 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2, GL_COMPRESSED_RED_GREEN_RGTC2, 0,
870 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
871 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_COMPRESSED,
872 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
873 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
874 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
875 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
876 | WINED3DFMT_FLAG_STENCIL,
877 EXT_PACKED_DEPTH_STENCIL, NULL},
878 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
879 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
880 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
881 | WINED3DFMT_FLAG_STENCIL,
882 ARB_FRAMEBUFFER_OBJECT, NULL},
883 {WINED3DFMT_NULL, GL_RGBA8, GL_RGBA8, 0,
884 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
885 WINED3DFMT_FLAG_RENDERTARGET,
886 ARB_FRAMEBUFFER_OBJECT, NULL},
889 static inline int getFmtIdx(enum wined3d_format_id format_id)
891 /* First check if the format is at the position of its value.
892 * This will catch the argb formats before the loop is entered. */
893 if (format_id < (sizeof(formats) / sizeof(*formats))
894 && formats[format_id].id == format_id)
896 return format_id;
898 else
900 unsigned int i;
902 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
904 if (formats[i].id == format_id) return i;
907 return -1;
910 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
912 UINT format_count = sizeof(formats) / sizeof(*formats);
913 UINT i;
915 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
916 if (!gl_info->formats)
918 ERR("Failed to allocate memory.\n");
919 return FALSE;
922 for (i = 0; i < format_count; ++i)
924 struct wined3d_format *format = &gl_info->formats[i];
925 format->id = formats[i].id;
926 format->red_mask = formats[i].redMask;
927 format->green_mask = formats[i].greenMask;
928 format->blue_mask = formats[i].blueMask;
929 format->alpha_mask = formats[i].alphaMask;
930 format->byte_count = formats[i].bpp;
931 format->depth_size = formats[i].depthSize;
932 format->stencil_size = formats[i].stencilSize;
933 format->block_width = 1;
934 format->block_height = 1;
935 format->block_byte_count = formats[i].bpp;
938 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
940 int fmt_idx = getFmtIdx(format_base_flags[i].id);
942 if (fmt_idx == -1)
944 ERR("Format %s (%#x) not found.\n",
945 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
946 HeapFree(GetProcessHeap(), 0, gl_info->formats);
947 return FALSE;
950 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
953 return TRUE;
956 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
958 unsigned int i;
960 for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i)
962 struct wined3d_format *format;
963 int fmt_idx = getFmtIdx(format_block_info[i].id);
965 if (fmt_idx == -1)
967 ERR("Format %s (%#x) not found.\n",
968 debug_d3dformat(format_block_info[i].id), format_block_info[i].id);
969 return FALSE;
972 format = &gl_info->formats[fmt_idx];
973 format->block_width = format_block_info[i].block_width;
974 format->block_height = format_block_info[i].block_height;
975 format->block_byte_count = format_block_info[i].block_byte_count;
976 format->flags |= WINED3DFMT_FLAG_BLOCKS;
979 return TRUE;
982 /* Context activation is done by the caller. */
983 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
985 /* Check if the default internal format is supported as a frame buffer
986 * target, otherwise fall back to the render target internal.
988 * Try to stick to the standard format if possible, this limits precision differences. */
989 GLenum status;
990 GLuint tex;
992 ENTER_GL();
994 while(glGetError());
995 glDisable(GL_BLEND);
997 glGenTextures(1, &tex);
998 glBindTexture(GL_TEXTURE_2D, tex);
1000 glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1001 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1002 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1004 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1006 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1007 checkGLcall("Framebuffer format check");
1009 if (status == GL_FRAMEBUFFER_COMPLETE)
1011 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1012 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1013 format->rtInternal = format->glInternal;
1015 else
1017 if (!format->rtInternal)
1019 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1021 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1022 " and no fallback specified.\n", debug_d3dformat(format->id));
1023 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1025 else
1027 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1029 format->rtInternal = format->glInternal;
1031 else
1033 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1034 debug_d3dformat(format->id));
1036 while(glGetError());
1038 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1040 glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
1041 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1042 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1044 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1046 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1047 checkGLcall("Framebuffer format check");
1049 if (status == GL_FRAMEBUFFER_COMPLETE)
1051 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1052 debug_d3dformat(format->id));
1054 else
1056 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1057 debug_d3dformat(format->id));
1058 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1063 if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1064 || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1065 && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
1066 && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA)
1068 GLuint rb, tex2;
1069 DWORD readback[16 * 16], color;
1070 BYTE r, a;
1071 BOOL match = TRUE;
1073 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1074 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1076 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1077 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1078 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1079 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1080 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1081 checkGLcall("RB attachment");
1084 glEnable(GL_BLEND);
1085 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1086 glClear(GL_COLOR_BUFFER_BIT);
1087 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1089 while(glGetError());
1090 TRACE("Format doesn't support post-pixelshader blending.\n");
1091 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1093 else
1095 glViewport(0, 0, 16, 16);
1096 glDisable(GL_LIGHTING);
1097 glMatrixMode(GL_MODELVIEW);
1098 glLoadIdentity();
1099 glMatrixMode(GL_PROJECTION);
1100 glLoadIdentity();
1102 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1104 /* Draw a full-black quad */
1105 glBegin(GL_TRIANGLE_STRIP);
1106 glColor4ub(0x00, 0x00, 0x00, 0xff);
1107 glVertex3f(-1.0f, -1.0f, 0.0f);
1108 glColor4ub(0x00, 0x00, 0x00, 0xff);
1109 glVertex3f(1.0f, -1.0f, 0.0f);
1110 glColor4ub(0x00, 0x00, 0x00, 0xff);
1111 glVertex3f(-1.0f, 1.0f, 0.0f);
1112 glColor4ub(0x00, 0x00, 0x00, 0xff);
1113 glVertex3f(1.0f, 1.0f, 0.0f);
1114 glEnd();
1116 /* Draw a half-transparent red quad */
1117 glBegin(GL_TRIANGLE_STRIP);
1118 glColor4ub(0xff, 0x00, 0x00, 0x80);
1119 glVertex3f(-1.0f, -1.0f, 0.0f);
1120 glColor4ub(0xff, 0x00, 0x00, 0x80);
1121 glVertex3f(1.0f, -1.0f, 0.0f);
1122 glColor4ub(0xff, 0x00, 0x00, 0x80);
1123 glVertex3f(-1.0f, 1.0f, 0.0f);
1124 glColor4ub(0xff, 0x00, 0x00, 0x80);
1125 glVertex3f(1.0f, 1.0f, 0.0f);
1126 glEnd();
1128 glGenTextures(1, &tex2);
1129 glBindTexture(GL_TEXTURE_2D, tex2);
1131 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, 16, 16, 0);
1132 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1133 checkGLcall("Post-pixelshader blending check");
1135 color = readback[7 * 16 + 7];
1136 a = color >> 24;
1137 r = (color & 0x00ff0000) >> 16;
1139 if (format->red_mask && (r < 0x7b || r > 0x84))
1140 match = FALSE;
1141 /* If the alpha component is more than 1 bit */
1142 else if ((format->alpha_mask & (format->alpha_mask - 1)) && (a < 0x9f || a > 0xdf))
1143 match = FALSE;
1144 if (!match)
1146 TRACE("Format doesn't support post-pixelshader blending.\n");
1147 TRACE("Color output: %#x\n", color);
1148 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1150 else
1152 TRACE("Format supports post-pixelshader blending.\n");
1153 format->flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1156 glBindTexture(GL_TEXTURE_2D, tex);
1157 glDeleteTextures(1, &tex2);
1160 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1161 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1163 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1164 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1165 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1166 checkGLcall("RB cleanup");
1170 if (format->glInternal != format->glGammaInternal)
1172 glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
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's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1181 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1183 else
1185 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1188 else if (status == GL_FRAMEBUFFER_COMPLETE)
1189 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1191 glDeleteTextures(1, &tex);
1193 LEAVE_GL();
1196 /* Context activation is done by the caller. */
1197 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1199 unsigned int i;
1200 GLuint fbo;
1202 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1204 ENTER_GL();
1206 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1207 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1208 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1209 glReadBuffer(GL_COLOR_ATTACHMENT0);
1211 LEAVE_GL();
1214 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1216 struct wined3d_format *format = &gl_info->formats[i];
1218 if (!format->glInternal) continue;
1220 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1222 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1223 debug_d3dformat(format->id));
1224 continue;
1227 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1229 TRACE("Skipping format %s because it's a compressed format.\n",
1230 debug_d3dformat(format->id));
1231 continue;
1234 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1236 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1237 check_fbo_compat(gl_info, format);
1239 else
1241 format->rtInternal = format->glInternal;
1245 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1247 ENTER_GL();
1249 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1251 LEAVE_GL();
1255 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1257 unsigned int i;
1259 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1261 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1262 struct wined3d_format *format;
1264 if (fmt_idx == -1)
1266 ERR("Format %s (%#x) not found.\n",
1267 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1268 return FALSE;
1271 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1273 format = &gl_info->formats[fmt_idx];
1275 /* ARB_texture_rg defines floating point formats, but only if
1276 * ARB_texture_float is also supported. */
1277 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1278 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1279 continue;
1281 format->glInternal = format_texture_info[i].gl_internal;
1282 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1283 format->rtInternal = format_texture_info[i].gl_rt_internal;
1284 format->glFormat = format_texture_info[i].gl_format;
1285 format->glType = format_texture_info[i].gl_type;
1286 format->color_fixup = COLOR_FIXUP_IDENTITY;
1287 format->flags |= format_texture_info[i].flags;
1288 format->heightscale = 1.0f;
1290 if (format->glGammaInternal != format->glInternal)
1292 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1293 if (!gl_info->supported[EXT_TEXTURE_SRGB])
1295 format->glGammaInternal = format->glInternal;
1296 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1298 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1300 format->glInternal = format->glGammaInternal;
1304 /* Texture conversion stuff */
1305 format->convert = format_texture_info[i].convert;
1306 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1309 return TRUE;
1312 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1314 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1315 c1 >>= 8; c2 >>= 8;
1316 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1317 c1 >>= 8; c2 >>= 8;
1318 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1319 c1 >>= 8; c2 >>= 8;
1320 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1321 return TRUE;
1324 /* A context is provided by the caller */
1325 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1327 static const DWORD data[] = {0x00000000, 0xffffffff};
1328 GLuint tex, fbo, buffer;
1329 DWORD readback[16 * 1];
1330 BOOL ret = FALSE;
1332 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1333 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1334 * falling back to software. If this changes in the future this code will get fooled and
1335 * apps might hit the software path due to incorrectly advertised caps.
1337 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1338 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1339 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1342 ENTER_GL();
1343 while(glGetError());
1345 glGenTextures(1, &buffer);
1346 glBindTexture(GL_TEXTURE_2D, buffer);
1347 memset(readback, 0x7e, sizeof(readback));
1348 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1349 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1350 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1351 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1352 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1353 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1355 glGenTextures(1, &tex);
1356 glBindTexture(GL_TEXTURE_2D, tex);
1357 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1358 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1359 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1360 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1361 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1362 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1363 glEnable(GL_TEXTURE_2D);
1365 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1366 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1367 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1368 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1370 glViewport(0, 0, 16, 1);
1371 glDisable(GL_LIGHTING);
1372 glMatrixMode(GL_MODELVIEW);
1373 glLoadIdentity();
1374 glMatrixMode(GL_PROJECTION);
1375 glLoadIdentity();
1377 glClearColor(0, 1, 0, 0);
1378 glClear(GL_COLOR_BUFFER_BIT);
1380 glBegin(GL_TRIANGLE_STRIP);
1381 glTexCoord2f(0.0, 0.0);
1382 glVertex2f(-1.0f, -1.0f);
1383 glTexCoord2f(1.0, 0.0);
1384 glVertex2f(1.0f, -1.0f);
1385 glTexCoord2f(0.0, 1.0);
1386 glVertex2f(-1.0f, 1.0f);
1387 glTexCoord2f(1.0, 1.0);
1388 glVertex2f(1.0f, 1.0f);
1389 glEnd();
1391 glBindTexture(GL_TEXTURE_2D, buffer);
1392 memset(readback, 0x7f, sizeof(readback));
1393 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1394 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
1395 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1397 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1398 readback[6], readback[9]);
1399 ret = FALSE;
1401 else
1403 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1404 readback[6], readback[9]);
1405 ret = TRUE;
1408 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1409 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1410 glDeleteTextures(1, &tex);
1411 glDeleteTextures(1, &buffer);
1413 if(glGetError())
1415 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1416 ret = FALSE;
1418 LEAVE_GL();
1419 return ret;
1422 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1424 struct wined3d_format *format;
1425 unsigned int fmt_idx, i;
1426 static const enum wined3d_format_id fmts16[] =
1428 WINED3DFMT_R16_FLOAT,
1429 WINED3DFMT_R16G16_FLOAT,
1430 WINED3DFMT_R16G16B16A16_FLOAT,
1432 BOOL filtered;
1434 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1436 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1437 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1439 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1440 filtered = TRUE;
1442 else if (gl_info->limits.glsl_varyings > 44)
1444 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1445 filtered = TRUE;
1447 else
1449 TRACE("Assuming no float16 blending\n");
1450 filtered = FALSE;
1453 if(filtered)
1455 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1457 fmt_idx = getFmtIdx(fmts16[i]);
1458 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1461 return;
1464 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1466 fmt_idx = getFmtIdx(fmts16[i]);
1467 format = &gl_info->formats[fmt_idx];
1468 if (!format->glInternal) continue; /* Not supported by GL */
1470 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1471 if(filtered)
1473 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1474 format->flags |= WINED3DFMT_FLAG_FILTERING;
1476 else
1478 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1483 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1485 int idx;
1487 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1488 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1489 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1491 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1492 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1493 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1495 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1496 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1497 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1499 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1500 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1501 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1503 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1504 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1505 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1507 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1508 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1509 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1510 * the only driver that implements it(fglrx) has a buggy implementation.
1512 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1513 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1514 * conversion for this format.
1516 if (!gl_info->supported[NV_TEXTURE_SHADER])
1518 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1519 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1520 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1521 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1522 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1523 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1525 else
1527 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1528 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1529 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1531 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1532 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1533 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1536 if (!gl_info->supported[NV_TEXTURE_SHADER])
1538 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1539 * with each other
1541 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1542 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1543 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1544 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1545 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1546 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1547 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1548 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1549 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1551 else
1553 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1554 * are converted at surface loading time, but they do not need any modification in
1555 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1556 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1560 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1562 idx = getFmtIdx(WINED3DFMT_ATI2N);
1563 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1564 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1566 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1568 idx = getFmtIdx(WINED3DFMT_ATI2N);
1569 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1570 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1573 if (!gl_info->supported[APPLE_YCBCR_422])
1575 idx = getFmtIdx(WINED3DFMT_YUY2);
1576 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1578 idx = getFmtIdx(WINED3DFMT_UYVY);
1579 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1582 idx = getFmtIdx(WINED3DFMT_YV12);
1583 gl_info->formats[idx].heightscale = 1.5f;
1584 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1586 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1588 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1589 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1592 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1594 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1595 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1598 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1600 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1601 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1602 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1603 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1605 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1606 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1610 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1612 unsigned int i;
1614 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1616 struct wined3d_format *format;
1617 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1619 if (fmt_idx == -1)
1621 ERR("Format %s (%#x) not found.\n",
1622 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1623 return FALSE;
1626 format = &gl_info->formats[fmt_idx];
1627 format->emit_idx = format_vertex_info[i].emit_idx;
1628 format->component_count = format_vertex_info[i].component_count;
1629 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1630 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1631 format->gl_normalized = format_vertex_info[i].gl_normalized;
1632 format->component_size = format_vertex_info[i].component_size;
1635 return TRUE;
1638 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1640 if (!init_format_base_info(gl_info)) return FALSE;
1642 if (!init_format_block_info(gl_info))
1644 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1645 gl_info->formats = NULL;
1646 return FALSE;
1649 return TRUE;
1652 /* Context activation is done by the caller. */
1653 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1655 if (!init_format_base_info(gl_info)) return FALSE;
1657 if (!init_format_block_info(gl_info)) goto fail;
1658 if (!init_format_texture_info(gl_info)) goto fail;
1659 if (!init_format_vertex_info(gl_info)) goto fail;
1661 apply_format_fixups(gl_info);
1662 init_format_fbo_compat_info(gl_info);
1663 init_format_filter_info(gl_info, vendor);
1665 return TRUE;
1667 fail:
1668 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1669 gl_info->formats = NULL;
1670 return FALSE;
1673 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1674 enum wined3d_format_id format_id)
1676 int idx = getFmtIdx(format_id);
1678 if (idx == -1)
1680 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1681 debug_d3dformat(format_id), format_id);
1682 /* Get the caller a valid pointer */
1683 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1686 return &gl_info->formats[idx];
1689 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1691 UINT size;
1693 if (format->id == WINED3DFMT_UNKNOWN)
1695 size = 0;
1697 else if (format->flags & WINED3DFMT_FLAG_BLOCKS)
1699 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1700 UINT row_count = (height + format->block_height - 1) / format->block_height;
1701 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1703 else
1705 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1708 if (format->heightscale != 0.0f)
1710 /* The D3D format requirements make sure that the resulting format is an integer again */
1711 size = (UINT) (size * format->heightscale);
1714 return size;
1717 /*****************************************************************************
1718 * Trace formatting of useful values
1720 const char *debug_d3dformat(enum wined3d_format_id format_id)
1722 switch (format_id)
1724 #define FMT_TO_STR(format_id) case format_id: return #format_id
1725 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1726 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1727 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1728 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1729 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1730 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1731 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1732 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1733 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1734 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1735 FMT_TO_STR(WINED3DFMT_P8_UINT);
1736 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1737 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1738 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1739 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1740 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1741 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1742 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1743 FMT_TO_STR(WINED3DFMT_UYVY);
1744 FMT_TO_STR(WINED3DFMT_YUY2);
1745 FMT_TO_STR(WINED3DFMT_YV12);
1746 FMT_TO_STR(WINED3DFMT_DXT1);
1747 FMT_TO_STR(WINED3DFMT_DXT2);
1748 FMT_TO_STR(WINED3DFMT_DXT3);
1749 FMT_TO_STR(WINED3DFMT_DXT4);
1750 FMT_TO_STR(WINED3DFMT_DXT5);
1751 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1752 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1753 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1754 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1755 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1756 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1757 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1758 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1759 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1760 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1761 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1762 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1763 FMT_TO_STR(WINED3DFMT_ATI2N);
1764 FMT_TO_STR(WINED3DFMT_NVDB);
1765 FMT_TO_STR(WINED3DFMT_NVHU);
1766 FMT_TO_STR(WINED3DFMT_NVHS);
1767 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1768 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1769 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1770 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1771 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1772 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1773 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1774 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1775 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1776 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1777 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1778 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1779 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1780 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1781 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1782 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1783 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1784 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1785 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1786 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1787 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1788 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1789 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1790 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1791 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1792 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1793 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1794 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1795 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1796 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1797 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1798 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1799 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1800 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1801 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1802 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1803 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1804 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1805 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1806 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1807 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1808 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1809 FMT_TO_STR(WINED3DFMT_R32_UINT);
1810 FMT_TO_STR(WINED3DFMT_R32_SINT);
1811 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1812 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1813 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1814 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1815 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1816 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1817 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1818 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1819 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1820 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1821 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1822 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1823 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1824 FMT_TO_STR(WINED3DFMT_R16_UINT);
1825 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1826 FMT_TO_STR(WINED3DFMT_R16_SINT);
1827 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1828 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1829 FMT_TO_STR(WINED3DFMT_R8_UINT);
1830 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1831 FMT_TO_STR(WINED3DFMT_R8_SINT);
1832 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1833 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1834 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1835 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1836 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1837 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1838 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1839 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1840 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1841 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1842 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1843 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1844 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1845 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1846 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1847 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1848 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1849 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1850 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1851 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1852 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1853 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1854 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1855 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1856 FMT_TO_STR(WINED3DFMT_INTZ);
1857 FMT_TO_STR(WINED3DFMT_NULL);
1858 FMT_TO_STR(WINED3DFMT_R16);
1859 FMT_TO_STR(WINED3DFMT_AL16);
1860 #undef FMT_TO_STR
1861 default:
1863 char fourcc[5];
1864 fourcc[0] = (char)(format_id);
1865 fourcc[1] = (char)(format_id >> 8);
1866 fourcc[2] = (char)(format_id >> 16);
1867 fourcc[3] = (char)(format_id >> 24);
1868 fourcc[4] = 0;
1869 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1870 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1871 else
1872 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1874 return "unrecognized";
1878 const char *debug_d3ddevicetype(WINED3DDEVTYPE devtype)
1880 switch (devtype)
1882 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1883 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
1884 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
1885 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
1886 #undef DEVTYPE_TO_STR
1887 default:
1888 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
1889 return "unrecognized";
1893 const char *debug_d3dusage(DWORD usage)
1895 char buf[333];
1897 buf[0] = '\0';
1898 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1899 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1900 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1901 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1902 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1903 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1904 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1905 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1906 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1907 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1908 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1909 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1910 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1911 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1912 #undef WINED3DUSAGE_TO_STR
1913 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1915 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1918 const char *debug_d3dusagequery(DWORD usagequery)
1920 char buf[238];
1922 buf[0] = '\0';
1923 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1924 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1925 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1926 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1927 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1928 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1929 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1930 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1931 #undef WINED3DUSAGEQUERY_TO_STR
1932 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1934 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1937 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
1938 switch (method) {
1939 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1940 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
1941 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
1942 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
1943 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
1944 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
1945 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
1946 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
1947 #undef WINED3DDECLMETHOD_TO_STR
1948 default:
1949 FIXME("Unrecognized %u declaration method!\n", method);
1950 return "unrecognized";
1954 const char* debug_d3ddeclusage(BYTE usage) {
1955 switch (usage) {
1956 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1957 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
1958 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
1959 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
1960 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
1961 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
1962 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
1963 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
1964 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
1965 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
1966 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
1967 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
1968 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
1969 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
1970 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
1971 #undef WINED3DDECLUSAGE_TO_STR
1972 default:
1973 FIXME("Unrecognized %u declaration usage!\n", usage);
1974 return "unrecognized";
1978 const char *debug_d3dresourcetype(WINED3DRESOURCETYPE res)
1980 switch (res)
1982 #define RES_TO_STR(res) case res: return #res
1983 RES_TO_STR(WINED3DRTYPE_SURFACE);
1984 RES_TO_STR(WINED3DRTYPE_VOLUME);
1985 RES_TO_STR(WINED3DRTYPE_TEXTURE);
1986 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
1987 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
1988 RES_TO_STR(WINED3DRTYPE_BUFFER);
1989 #undef RES_TO_STR
1990 default:
1991 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
1992 return "unrecognized";
1996 const char *debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType)
1998 switch (PrimitiveType)
2000 #define PRIM_TO_STR(prim) case prim: return #prim
2001 PRIM_TO_STR(WINED3DPT_UNDEFINED);
2002 PRIM_TO_STR(WINED3DPT_POINTLIST);
2003 PRIM_TO_STR(WINED3DPT_LINELIST);
2004 PRIM_TO_STR(WINED3DPT_LINESTRIP);
2005 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
2006 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
2007 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
2008 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ);
2009 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ);
2010 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ);
2011 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ);
2012 #undef PRIM_TO_STR
2013 default:
2014 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
2015 return "unrecognized";
2019 const char *debug_d3drenderstate(WINED3DRENDERSTATETYPE state)
2021 switch (state)
2023 #define D3DSTATE_TO_STR(u) case u: return #u
2024 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS);
2025 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE);
2026 D3DSTATE_TO_STR(WINED3DRS_WRAPU);
2027 D3DSTATE_TO_STR(WINED3DRS_WRAPV);
2028 D3DSTATE_TO_STR(WINED3DRS_ZENABLE);
2029 D3DSTATE_TO_STR(WINED3DRS_FILLMODE);
2030 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE);
2031 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN);
2032 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE);
2033 D3DSTATE_TO_STR(WINED3DRS_ROP2);
2034 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK);
2035 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE);
2036 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE);
2037 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL);
2038 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND);
2039 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND);
2040 D3DSTATE_TO_STR(WINED3DRS_CULLMODE);
2041 D3DSTATE_TO_STR(WINED3DRS_ZFUNC);
2042 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF);
2043 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC);
2044 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE);
2045 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE);
2046 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE);
2047 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE);
2048 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE);
2049 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL);
2050 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX);
2051 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA);
2052 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR);
2053 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE);
2054 D3DSTATE_TO_STR(WINED3DRS_FOGSTART);
2055 D3DSTATE_TO_STR(WINED3DRS_FOGEND);
2056 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY);
2057 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE);
2058 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS);
2059 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE);
2060 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS);
2061 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE);
2062 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY);
2063 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH);
2064 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
2065 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE);
2066 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL);
2067 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL);
2068 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS);
2069 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC);
2070 D3DSTATE_TO_STR(WINED3DRS_STENCILREF);
2071 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK);
2072 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK);
2073 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR);
2074 D3DSTATE_TO_STR(WINED3DRS_WRAP0);
2075 D3DSTATE_TO_STR(WINED3DRS_WRAP1);
2076 D3DSTATE_TO_STR(WINED3DRS_WRAP2);
2077 D3DSTATE_TO_STR(WINED3DRS_WRAP3);
2078 D3DSTATE_TO_STR(WINED3DRS_WRAP4);
2079 D3DSTATE_TO_STR(WINED3DRS_WRAP5);
2080 D3DSTATE_TO_STR(WINED3DRS_WRAP6);
2081 D3DSTATE_TO_STR(WINED3DRS_WRAP7);
2082 D3DSTATE_TO_STR(WINED3DRS_CLIPPING);
2083 D3DSTATE_TO_STR(WINED3DRS_LIGHTING);
2084 D3DSTATE_TO_STR(WINED3DRS_EXTENTS);
2085 D3DSTATE_TO_STR(WINED3DRS_AMBIENT);
2086 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE);
2087 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX);
2088 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER);
2089 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS);
2090 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE);
2091 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE);
2092 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE);
2093 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE);
2094 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE);
2095 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND);
2096 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE);
2097 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING);
2098 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE);
2099 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN);
2100 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE);
2101 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE);
2102 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A);
2103 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B);
2104 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C);
2105 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS);
2106 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK);
2107 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE);
2108 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS);
2109 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN);
2110 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX);
2111 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE);
2112 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE);
2113 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR);
2114 D3DSTATE_TO_STR(WINED3DRS_BLENDOP);
2115 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE);
2116 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE);
2117 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE);
2118 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS);
2119 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE);
2120 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL);
2121 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL);
2122 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X);
2123 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y);
2124 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z);
2125 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W);
2126 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
2127 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE);
2128 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL);
2129 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL);
2130 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS);
2131 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC);
2132 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1);
2133 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2);
2134 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3);
2135 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR);
2136 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE);
2137 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS);
2138 D3DSTATE_TO_STR(WINED3DRS_WRAP8);
2139 D3DSTATE_TO_STR(WINED3DRS_WRAP9);
2140 D3DSTATE_TO_STR(WINED3DRS_WRAP10);
2141 D3DSTATE_TO_STR(WINED3DRS_WRAP11);
2142 D3DSTATE_TO_STR(WINED3DRS_WRAP12);
2143 D3DSTATE_TO_STR(WINED3DRS_WRAP13);
2144 D3DSTATE_TO_STR(WINED3DRS_WRAP14);
2145 D3DSTATE_TO_STR(WINED3DRS_WRAP15);
2146 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE);
2147 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA);
2148 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA);
2149 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA);
2150 #undef D3DSTATE_TO_STR
2151 default:
2152 FIXME("Unrecognized %u render state!\n", state);
2153 return "unrecognized";
2157 const char *debug_d3dsamplerstate(DWORD state)
2159 switch (state)
2161 #define D3DSTATE_TO_STR(u) case u: return #u
2162 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR);
2163 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU);
2164 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV);
2165 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW);
2166 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER);
2167 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER);
2168 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER);
2169 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
2170 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL);
2171 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
2172 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE);
2173 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX);
2174 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET);
2175 #undef D3DSTATE_TO_STR
2176 default:
2177 FIXME("Unrecognized %u sampler state!\n", state);
2178 return "unrecognized";
2182 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
2183 switch (filter_type) {
2184 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2185 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
2186 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
2187 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
2188 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
2189 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
2190 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
2191 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
2192 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
2193 #undef D3DTEXTUREFILTERTYPE_TO_STR
2194 default:
2195 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
2196 return "unrecognized";
2200 const char *debug_d3dtexturestate(DWORD state)
2202 switch (state)
2204 #define D3DSTATE_TO_STR(u) case u: return #u
2205 D3DSTATE_TO_STR(WINED3DTSS_COLOROP);
2206 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1);
2207 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2);
2208 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP);
2209 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1);
2210 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2);
2211 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00);
2212 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01);
2213 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10);
2214 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11);
2215 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX);
2216 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE);
2217 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET);
2218 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS);
2219 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0);
2220 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0);
2221 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG);
2222 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT);
2223 #undef D3DSTATE_TO_STR
2224 default:
2225 FIXME("Unrecognized %u texture state!\n", state);
2226 return "unrecognized";
2230 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
2231 switch (d3dtop) {
2232 #define D3DTOP_TO_STR(u) case u: return #u
2233 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
2234 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
2235 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
2236 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
2237 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
2238 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
2239 D3DTOP_TO_STR(WINED3DTOP_ADD);
2240 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
2241 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
2242 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
2243 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
2244 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
2245 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
2246 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
2247 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
2248 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
2249 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
2250 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
2251 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
2252 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
2253 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
2254 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
2255 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
2256 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
2257 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
2258 D3DTOP_TO_STR(WINED3DTOP_LERP);
2259 #undef D3DTOP_TO_STR
2260 default:
2261 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
2262 return "unrecognized";
2266 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
2267 switch (tstype) {
2268 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2269 TSTYPE_TO_STR(WINED3DTS_VIEW);
2270 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
2271 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
2272 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
2273 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
2274 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
2275 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
2276 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
2277 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
2278 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
2279 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2280 #undef TSTYPE_TO_STR
2281 default:
2282 if (tstype > 256 && tstype < 512) {
2283 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
2284 return ("WINED3DTS_WORLDMATRIX > 0");
2286 FIXME("Unrecognized %u WINED3DTS\n", tstype);
2287 return "unrecognized";
2291 const char *debug_d3dstate(DWORD state)
2293 if (STATE_IS_RENDER(state))
2294 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2295 if (STATE_IS_TEXTURESTAGE(state))
2297 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2298 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2299 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2300 texture_stage, debug_d3dtexturestate(texture_state));
2302 if (STATE_IS_SAMPLER(state))
2303 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2304 if (STATE_IS_PIXELSHADER(state))
2305 return "STATE_PIXELSHADER";
2306 if (STATE_IS_TRANSFORM(state))
2307 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2308 if (STATE_IS_STREAMSRC(state))
2309 return "STATE_STREAMSRC";
2310 if (STATE_IS_INDEXBUFFER(state))
2311 return "STATE_INDEXBUFFER";
2312 if (STATE_IS_VDECL(state))
2313 return "STATE_VDECL";
2314 if (STATE_IS_VSHADER(state))
2315 return "STATE_VSHADER";
2316 if (STATE_IS_VIEWPORT(state))
2317 return "STATE_VIEWPORT";
2318 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2319 return "STATE_VERTEXSHADERCONSTANT";
2320 if (STATE_IS_PIXELSHADERCONSTANT(state))
2321 return "STATE_PIXELSHADERCONSTANT";
2322 if (STATE_IS_ACTIVELIGHT(state))
2323 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2324 if (STATE_IS_SCISSORRECT(state))
2325 return "STATE_SCISSORRECT";
2326 if (STATE_IS_CLIPPLANE(state))
2327 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2328 if (STATE_IS_MATERIAL(state))
2329 return "STATE_MATERIAL";
2330 if (STATE_IS_FRONTFACE(state))
2331 return "STATE_FRONTFACE";
2332 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2333 return "STATE_POINTSPRITECOORDORIGIN";
2334 if (STATE_IS_BASEVERTEXINDEX(state))
2335 return "STATE_BASEVERTEXINDEX";
2336 if (STATE_IS_FRAMEBUFFER(state))
2337 return "STATE_FRAMEBUFFER";
2339 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2342 const char *debug_d3dpool(WINED3DPOOL pool)
2344 switch (pool)
2346 #define POOL_TO_STR(p) case p: return #p
2347 POOL_TO_STR(WINED3DPOOL_DEFAULT);
2348 POOL_TO_STR(WINED3DPOOL_MANAGED);
2349 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
2350 POOL_TO_STR(WINED3DPOOL_SCRATCH);
2351 #undef POOL_TO_STR
2352 default:
2353 FIXME("Unrecognized %u WINED3DPOOL!\n", pool);
2354 return "unrecognized";
2358 const char *debug_fbostatus(GLenum status) {
2359 switch(status) {
2360 #define FBOSTATUS_TO_STR(u) case u: return #u
2361 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2362 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2363 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2364 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2365 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2366 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2367 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2368 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2369 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2370 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2371 #undef FBOSTATUS_TO_STR
2372 default:
2373 FIXME("Unrecognied FBO status 0x%08x\n", status);
2374 return "unrecognized";
2378 const char *debug_glerror(GLenum error) {
2379 switch(error) {
2380 #define GLERROR_TO_STR(u) case u: return #u
2381 GLERROR_TO_STR(GL_NO_ERROR);
2382 GLERROR_TO_STR(GL_INVALID_ENUM);
2383 GLERROR_TO_STR(GL_INVALID_VALUE);
2384 GLERROR_TO_STR(GL_INVALID_OPERATION);
2385 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2386 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2387 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2388 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2389 #undef GLERROR_TO_STR
2390 default:
2391 FIXME("Unrecognied GL error 0x%08x\n", error);
2392 return "unrecognized";
2396 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
2397 switch(basis) {
2398 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
2399 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
2400 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
2401 default: return "unrecognized";
2405 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
2406 switch(degree) {
2407 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
2408 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
2409 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
2410 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
2411 default: return "unrecognized";
2415 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2417 switch(source)
2419 #define WINED3D_TO_STR(x) case x: return #x
2420 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2421 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2422 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2423 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2424 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2425 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2426 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2427 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2428 #undef WINED3D_TO_STR
2429 default:
2430 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2431 return "unrecognized";
2435 static const char *debug_complex_fixup(enum complex_fixup fixup)
2437 switch(fixup)
2439 #define WINED3D_TO_STR(x) case x: return #x
2440 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2441 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2442 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2443 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2444 #undef WINED3D_TO_STR
2445 default:
2446 FIXME("Unrecognized complex fixup %#x\n", fixup);
2447 return "unrecognized";
2451 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2453 if (is_complex_fixup(fixup))
2455 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2456 return;
2459 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2460 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2461 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2462 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2465 const char *debug_surflocation(DWORD flag) {
2466 char buf[128];
2468 buf[0] = 0;
2469 if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM"); /* 17 */
2470 if (flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE"); /* 19 */
2471 if (flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE"); /* 18 */
2472 if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX"); /* 18 */
2473 if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE"); /* 25 */
2474 if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED"); /* 22 */
2475 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2478 /*****************************************************************************
2479 * Useful functions mapping GL <-> D3D values
2481 GLenum StencilOp(DWORD op) {
2482 switch(op) {
2483 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
2484 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
2485 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
2486 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
2487 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
2488 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
2489 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
2490 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
2491 default:
2492 FIXME("Unrecognized stencil op %d\n", op);
2493 return GL_KEEP;
2497 GLenum CompareFunc(DWORD func) {
2498 switch ((WINED3DCMPFUNC)func) {
2499 case WINED3DCMP_NEVER : return GL_NEVER;
2500 case WINED3DCMP_LESS : return GL_LESS;
2501 case WINED3DCMP_EQUAL : return GL_EQUAL;
2502 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
2503 case WINED3DCMP_GREATER : return GL_GREATER;
2504 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
2505 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
2506 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
2507 default:
2508 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
2509 return 0;
2513 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2514 WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
2516 if (op == WINED3DTOP_DISABLE) return FALSE;
2517 if (state->textures[stage]) return FALSE;
2519 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2520 && op != WINED3DTOP_SELECTARG2) return TRUE;
2521 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2522 && op != WINED3DTOP_SELECTARG1) return TRUE;
2523 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2524 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
2526 return FALSE;
2529 /* Setup this textures matrix according to the texture flags*/
2530 /* GL locking is done by the caller (state handler) */
2531 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
2532 enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2534 float mat[16];
2536 glMatrixMode(GL_TEXTURE);
2537 checkGLcall("glMatrixMode(GL_TEXTURE)");
2539 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2540 glLoadIdentity();
2541 checkGLcall("glLoadIdentity()");
2542 return;
2545 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2546 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2547 return;
2550 memcpy(mat, smat, 16 * sizeof(float));
2552 if (flags & WINED3DTTFF_PROJECTED) {
2553 if(!ffp_proj_control) {
2554 switch (flags & ~WINED3DTTFF_PROJECTED) {
2555 case WINED3DTTFF_COUNT2:
2556 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2557 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2558 break;
2559 case WINED3DTTFF_COUNT3:
2560 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2561 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2562 break;
2565 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2566 if(!calculatedCoords) {
2567 switch(vtx_fmt)
2569 case WINED3DFMT_R32_FLOAT:
2570 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2571 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2572 * the input value to the transformation will be 0, so the matrix value is irrelevant
2574 mat[12] = mat[4];
2575 mat[13] = mat[5];
2576 mat[14] = mat[6];
2577 mat[15] = mat[7];
2578 break;
2579 case WINED3DFMT_R32G32_FLOAT:
2580 /* See above, just 3rd and 4th coord
2582 mat[12] = mat[8];
2583 mat[13] = mat[9];
2584 mat[14] = mat[10];
2585 mat[15] = mat[11];
2586 break;
2587 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2588 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2590 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2591 * into a bad place. The division elimination below will apply to make sure the
2592 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2594 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2595 break;
2596 default:
2597 FIXME("Unexpected fixed function texture coord input\n");
2600 if(!ffp_proj_control) {
2601 switch (flags & ~WINED3DTTFF_PROJECTED) {
2602 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2603 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2604 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2605 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2606 * the 4th coord evaluates to 1.0 to eliminate that.
2608 * If the fixed function pipeline is used, the 4th value remains unused,
2609 * so there is no danger in doing this. With vertex shaders we have a
2610 * problem. Should an app hit that problem, the code here would have to
2611 * check for pixel shaders, and the shader has to undo the default gl divide.
2613 * A more serious problem occurs if the app passes 4 coordinates in, and the
2614 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2615 * or a replacement shader
2617 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2622 glLoadMatrixf(mat);
2623 checkGLcall("glLoadMatrixf(mat)");
2626 /* This small helper function is used to convert a bitmask into the number of masked bits */
2627 unsigned int count_bits(unsigned int mask)
2629 unsigned int count;
2630 for (count = 0; mask; ++count)
2632 mask &= mask - 1;
2634 return count;
2637 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2638 * The later function requires individual color components. */
2639 BOOL getColorBits(const struct wined3d_format *format,
2640 BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2642 TRACE("format %s.\n", debug_d3dformat(format->id));
2644 switch (format->id)
2646 case WINED3DFMT_B10G10R10A2_UNORM:
2647 case WINED3DFMT_R10G10B10A2_UNORM:
2648 case WINED3DFMT_B8G8R8X8_UNORM:
2649 case WINED3DFMT_B8G8R8_UNORM:
2650 case WINED3DFMT_B8G8R8A8_UNORM:
2651 case WINED3DFMT_R8G8B8A8_UNORM:
2652 case WINED3DFMT_B5G5R5X1_UNORM:
2653 case WINED3DFMT_B5G5R5A1_UNORM:
2654 case WINED3DFMT_B5G6R5_UNORM:
2655 case WINED3DFMT_B4G4R4X4_UNORM:
2656 case WINED3DFMT_B4G4R4A4_UNORM:
2657 case WINED3DFMT_B2G3R3_UNORM:
2658 case WINED3DFMT_P8_UINT_A8_UNORM:
2659 case WINED3DFMT_P8_UINT:
2660 break;
2661 default:
2662 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2663 return FALSE;
2666 *redSize = count_bits(format->red_mask);
2667 *greenSize = count_bits(format->green_mask);
2668 *blueSize = count_bits(format->blue_mask);
2669 *alphaSize = count_bits(format->alpha_mask);
2670 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2672 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2673 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2674 return TRUE;
2677 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2678 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
2680 TRACE("format %s.\n", debug_d3dformat(format->id));
2682 switch (format->id)
2684 case WINED3DFMT_D16_LOCKABLE:
2685 case WINED3DFMT_D16_UNORM:
2686 case WINED3DFMT_S1_UINT_D15_UNORM:
2687 case WINED3DFMT_X8D24_UNORM:
2688 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2689 case WINED3DFMT_D24_UNORM_S8_UINT:
2690 case WINED3DFMT_S8_UINT_D24_FLOAT:
2691 case WINED3DFMT_D32_UNORM:
2692 case WINED3DFMT_D32_FLOAT:
2693 case WINED3DFMT_INTZ:
2694 break;
2695 default:
2696 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2697 return FALSE;
2700 *depthSize = format->depth_size;
2701 *stencilSize = format->stencil_size;
2703 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2704 *depthSize, *stencilSize, debug_d3dformat(format->id));
2705 return TRUE;
2708 /* Note: It's the caller's responsibility to ensure values can be expressed
2709 * in the requested format. UNORM formats for example can only express values
2710 * in the range 0.0f -> 1.0f. */
2711 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color)
2713 static const struct
2715 enum wined3d_format_id format_id;
2716 float r_mul;
2717 float g_mul;
2718 float b_mul;
2719 float a_mul;
2720 BYTE r_shift;
2721 BYTE g_shift;
2722 BYTE b_shift;
2723 BYTE a_shift;
2725 conv[] =
2727 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2728 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2729 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2730 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2731 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2732 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2733 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2734 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2735 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2736 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2737 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2738 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2739 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2740 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2742 const struct wined3d_format *format = surface->resource.format;
2743 unsigned int i;
2745 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2746 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2748 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2750 DWORD ret;
2752 if (format->id != conv[i].format_id) continue;
2754 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2755 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2756 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2757 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2759 TRACE("Returning 0x%08x.\n", ret);
2761 return ret;
2764 if (format->id == WINED3DFMT_P8_UINT)
2766 PALETTEENTRY *e;
2767 BYTE r, g, b, a;
2769 if (!surface->palette)
2771 WARN("Surface doesn't have a palette, returning 0.\n");
2772 return 0;
2775 r = (BYTE)((color->r * 255.0f) + 0.5f);
2776 g = (BYTE)((color->g * 255.0f) + 0.5f);
2777 b = (BYTE)((color->b * 255.0f) + 0.5f);
2778 a = (BYTE)((color->a * 255.0f) + 0.5f);
2780 e = &surface->palette->palents[a];
2781 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2782 return a;
2784 WARN("Alpha didn't match index, searching full palette.\n");
2786 for (i = 0; i < 256; ++i)
2788 e = &surface->palette->palents[i];
2789 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2790 return i;
2793 FIXME("Unable to convert color to palette index.\n");
2795 return 0;
2798 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2800 return 0;
2803 /* DirectDraw stuff */
2804 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2806 switch (depth)
2808 case 8: return WINED3DFMT_P8_UINT;
2809 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2810 case 16: return WINED3DFMT_B5G6R5_UNORM;
2811 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2812 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2813 default: return WINED3DFMT_UNKNOWN;
2817 void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
2818 const struct wined3d_matrix *src2)
2820 struct wined3d_matrix temp;
2822 /* Now do the multiplication 'by hand'.
2823 I know that all this could be optimised, but this will be done later :-) */
2824 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);
2825 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);
2826 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);
2827 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);
2829 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);
2830 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);
2831 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);
2832 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);
2834 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);
2835 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);
2836 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);
2837 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);
2839 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);
2840 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);
2841 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);
2842 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);
2844 /* And copy the new matrix in the good storage.. */
2845 memcpy(dest, &temp, 16 * sizeof(float));
2848 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2849 DWORD size = 0;
2850 int i;
2851 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2853 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2854 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2855 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2856 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2857 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2858 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2859 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2860 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2861 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2862 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2863 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2864 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2865 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2866 default: ERR("Unexpected position mask\n");
2868 for (i = 0; i < numTextures; i++) {
2869 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2872 return size;
2875 void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_state *state,
2876 struct ffp_frag_settings *settings, BOOL ignore_textype)
2878 #define ARG1 0x01
2879 #define ARG2 0x02
2880 #define ARG0 0x04
2881 static const unsigned char args[WINED3DTOP_LERP + 1] = {
2882 /* undefined */ 0,
2883 /* D3DTOP_DISABLE */ 0,
2884 /* D3DTOP_SELECTARG1 */ ARG1,
2885 /* D3DTOP_SELECTARG2 */ ARG2,
2886 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2887 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2888 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2889 /* D3DTOP_ADD */ ARG1 | ARG2,
2890 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2891 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2892 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2893 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2894 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2895 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2896 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2897 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2898 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2899 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2900 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2901 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2902 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2903 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2904 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2905 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2906 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2907 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2908 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2910 unsigned int i;
2911 DWORD ttff;
2912 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2913 const struct wined3d_surface *rt = state->fb->render_targets[0];
2914 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2916 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2918 const struct wined3d_texture *texture;
2920 settings->op[i].padding = 0;
2921 if (state->texture_states[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE)
2923 settings->op[i].cop = WINED3DTOP_DISABLE;
2924 settings->op[i].aop = WINED3DTOP_DISABLE;
2925 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2926 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2927 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2928 settings->op[i].dst = resultreg;
2929 settings->op[i].tex_type = tex_1d;
2930 settings->op[i].projected = proj_none;
2931 i++;
2932 break;
2935 if ((texture = state->textures[i]))
2937 settings->op[i].color_fixup = texture->resource.format->color_fixup;
2938 if (ignore_textype)
2940 settings->op[i].tex_type = tex_1d;
2942 else
2944 switch (texture->target)
2946 case GL_TEXTURE_1D:
2947 settings->op[i].tex_type = tex_1d;
2948 break;
2949 case GL_TEXTURE_2D:
2950 settings->op[i].tex_type = tex_2d;
2951 break;
2952 case GL_TEXTURE_3D:
2953 settings->op[i].tex_type = tex_3d;
2954 break;
2955 case GL_TEXTURE_CUBE_MAP_ARB:
2956 settings->op[i].tex_type = tex_cube;
2957 break;
2958 case GL_TEXTURE_RECTANGLE_ARB:
2959 settings->op[i].tex_type = tex_rect;
2960 break;
2963 } else {
2964 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2965 settings->op[i].tex_type = tex_1d;
2968 cop = state->texture_states[i][WINED3DTSS_COLOROP];
2969 aop = state->texture_states[i][WINED3DTSS_ALPHAOP];
2971 carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
2972 carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
2973 carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
2975 if (is_invalid_op(state, i, cop, carg1, carg2, carg0))
2977 carg0 = ARG_UNUSED;
2978 carg2 = ARG_UNUSED;
2979 carg1 = WINED3DTA_CURRENT;
2980 cop = WINED3DTOP_SELECTARG1;
2983 if(cop == WINED3DTOP_DOTPRODUCT3) {
2984 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2985 * the color result to the alpha component of the destination
2987 aop = cop;
2988 aarg1 = carg1;
2989 aarg2 = carg2;
2990 aarg0 = carg0;
2992 else
2994 aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2995 aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2996 aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2999 if (!i && state->textures[0] && state->render_states[WINED3DRS_COLORKEYENABLE])
3001 GLenum texture_dimensions;
3003 texture = state->textures[0];
3004 texture_dimensions = texture->target;
3006 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3008 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3010 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
3012 if (aop == WINED3DTOP_DISABLE)
3014 aarg1 = WINED3DTA_TEXTURE;
3015 aop = WINED3DTOP_SELECTARG1;
3017 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
3019 if (state->render_states[WINED3DRS_ALPHABLENDENABLE])
3021 aarg2 = WINED3DTA_TEXTURE;
3022 aop = WINED3DTOP_MODULATE;
3024 else aarg1 = WINED3DTA_TEXTURE;
3026 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
3028 if (state->render_states[WINED3DRS_ALPHABLENDENABLE])
3030 aarg1 = WINED3DTA_TEXTURE;
3031 aop = WINED3DTOP_MODULATE;
3033 else aarg2 = WINED3DTA_TEXTURE;
3039 if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0))
3041 aarg0 = ARG_UNUSED;
3042 aarg2 = ARG_UNUSED;
3043 aarg1 = WINED3DTA_CURRENT;
3044 aop = WINED3DTOP_SELECTARG1;
3047 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
3048 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
3050 ttff = state->texture_states[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
3051 if (ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3))
3053 settings->op[i].projected = proj_count3;
3054 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
3055 settings->op[i].projected = proj_count4;
3056 } else {
3057 settings->op[i].projected = proj_none;
3059 } else {
3060 settings->op[i].projected = proj_none;
3063 settings->op[i].cop = cop;
3064 settings->op[i].aop = aop;
3065 settings->op[i].carg0 = carg0;
3066 settings->op[i].carg1 = carg1;
3067 settings->op[i].carg2 = carg2;
3068 settings->op[i].aarg0 = aarg0;
3069 settings->op[i].aarg1 = aarg1;
3070 settings->op[i].aarg2 = aarg2;
3072 if (state->texture_states[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP)
3073 settings->op[i].dst = tempreg;
3074 else
3075 settings->op[i].dst = resultreg;
3078 /* Clear unsupported stages */
3079 for(; i < MAX_TEXTURES; i++) {
3080 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
3083 if (!state->render_states[WINED3DRS_FOGENABLE])
3085 settings->fog = FOG_OFF;
3087 else if (state->render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
3089 if (use_vs(state) || state->vertex_declaration->position_transformed)
3091 settings->fog = FOG_LINEAR;
3093 else
3095 switch (state->render_states[WINED3DRS_FOGVERTEXMODE])
3097 case WINED3DFOG_NONE:
3098 case WINED3DFOG_LINEAR:
3099 settings->fog = FOG_LINEAR;
3100 break;
3101 case WINED3DFOG_EXP:
3102 settings->fog = FOG_EXP;
3103 break;
3104 case WINED3DFOG_EXP2:
3105 settings->fog = FOG_EXP2;
3106 break;
3110 else
3112 switch (state->render_states[WINED3DRS_FOGTABLEMODE])
3114 case WINED3DFOG_LINEAR:
3115 settings->fog = FOG_LINEAR;
3116 break;
3117 case WINED3DFOG_EXP:
3118 settings->fog = FOG_EXP;
3119 break;
3120 case WINED3DFOG_EXP2:
3121 settings->fog = FOG_EXP2;
3122 break;
3125 if (state->render_states[WINED3DRS_SRGBWRITEENABLE]
3126 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
3128 settings->sRGB_write = 1;
3129 } else {
3130 settings->sRGB_write = 0;
3132 if (device->vs_clipping || !use_vs(state) || !state->render_states[WINED3DRS_CLIPPING]
3133 || !state->render_states[WINED3DRS_CLIPPLANEENABLE])
3135 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3136 * the fixed function vertex pipeline is used(which always supports clipplanes), or
3137 * if no clipplane is enabled
3139 settings->emul_clipplanes = 0;
3140 } else {
3141 settings->emul_clipplanes = 1;
3145 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3146 const struct ffp_frag_settings *settings)
3148 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3149 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3152 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3154 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3155 * whereas desc points to an extended structure with implementation specific parts. */
3156 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3158 ERR("Failed to insert ffp frag shader.\n");
3162 /* Activates the texture dimension according to the bound D3D texture.
3163 * Does not care for the colorop or correct gl texture unit(when using nvrc)
3164 * Requires the caller to activate the correct unit before
3166 /* GL locking is done by the caller (state handler) */
3167 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3169 if (texture)
3171 switch (texture->target)
3173 case GL_TEXTURE_2D:
3174 glDisable(GL_TEXTURE_3D);
3175 checkGLcall("glDisable(GL_TEXTURE_3D)");
3176 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3178 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3179 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3181 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3183 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3184 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3186 glEnable(GL_TEXTURE_2D);
3187 checkGLcall("glEnable(GL_TEXTURE_2D)");
3188 break;
3189 case GL_TEXTURE_RECTANGLE_ARB:
3190 glDisable(GL_TEXTURE_2D);
3191 checkGLcall("glDisable(GL_TEXTURE_2D)");
3192 glDisable(GL_TEXTURE_3D);
3193 checkGLcall("glDisable(GL_TEXTURE_3D)");
3194 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3196 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3197 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3199 glEnable(GL_TEXTURE_RECTANGLE_ARB);
3200 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3201 break;
3202 case GL_TEXTURE_3D:
3203 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3205 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3206 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3208 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3210 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3211 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3213 glDisable(GL_TEXTURE_2D);
3214 checkGLcall("glDisable(GL_TEXTURE_2D)");
3215 glEnable(GL_TEXTURE_3D);
3216 checkGLcall("glEnable(GL_TEXTURE_3D)");
3217 break;
3218 case GL_TEXTURE_CUBE_MAP_ARB:
3219 glDisable(GL_TEXTURE_2D);
3220 checkGLcall("glDisable(GL_TEXTURE_2D)");
3221 glDisable(GL_TEXTURE_3D);
3222 checkGLcall("glDisable(GL_TEXTURE_3D)");
3223 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3225 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3226 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3228 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3229 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3230 break;
3232 } else {
3233 glEnable(GL_TEXTURE_2D);
3234 checkGLcall("glEnable(GL_TEXTURE_2D)");
3235 glDisable(GL_TEXTURE_3D);
3236 checkGLcall("glDisable(GL_TEXTURE_3D)");
3237 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3239 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3240 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3242 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3244 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3245 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3247 /* Binding textures is done by samplers. A dummy texture will be bound */
3251 /* GL locking is done by the caller (state handler) */
3252 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3254 DWORD sampler = state_id - STATE_SAMPLER(0);
3255 DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
3257 /* No need to enable / disable anything here for unused samplers. The
3258 * tex_colorop handler takes care. Also no action is needed with pixel
3259 * shaders, or if tex_colorop will take care of this business. */
3260 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
3261 return;
3262 if (sampler >= state->lowest_disabled_stage)
3263 return;
3264 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP)))
3265 return;
3267 texture_activate_dimensions(state->textures[sampler], context->gl_info);
3270 void *wined3d_rb_alloc(size_t size)
3272 return HeapAlloc(GetProcessHeap(), 0, size);
3275 void *wined3d_rb_realloc(void *ptr, size_t size)
3277 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3280 void wined3d_rb_free(void *ptr)
3282 HeapFree(GetProcessHeap(), 0, ptr);
3285 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3287 const struct ffp_frag_settings *ka = key;
3288 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3290 return memcmp(ka, kb, sizeof(*ka));
3293 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3295 wined3d_rb_alloc,
3296 wined3d_rb_realloc,
3297 wined3d_rb_free,
3298 ffp_frag_program_key_compare,
3301 UINT wined3d_log2i(UINT32 x)
3303 static const UINT l[] =
3305 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3306 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3307 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3308 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3309 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3310 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3311 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3312 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3313 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3314 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3315 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3316 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3317 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3318 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3319 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3320 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3322 UINT32 i;
3324 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3327 /* Set the shader type for this device, depending on the given capabilities
3328 * and the user preferences in wined3d_settings. */
3329 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3331 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3333 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3334 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3336 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3337 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3338 * shaders only on this card. */
3339 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3340 else *vs_selected = SHADER_GLSL;
3342 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3343 else *vs_selected = SHADER_NONE;
3345 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3346 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3347 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3348 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3349 else *ps_selected = SHADER_NONE;
3352 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3353 const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format *src_format,
3354 const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format *dst_format)
3356 static const struct blit_shader * const blitters[] =
3358 &arbfp_blit,
3359 &ffp_blit,
3360 &cpu_blit,
3362 unsigned int i;
3364 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3366 if (blitters[i]->blit_supported(gl_info, blit_op,
3367 src_rect, src_usage, src_pool, src_format,
3368 dst_rect, dst_usage, dst_pool, dst_format))
3369 return blitters[i];
3372 return NULL;
3375 void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
3377 const struct wined3d_viewport *vp = &state->viewport;
3379 SetRect(rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
3381 if (state->render_states[WINED3DRS_SCISSORTESTENABLE])
3382 IntersectRect(rect, rect, &state->scissor_rect);