wined3d: Dump postblend color.
[wine/wine-gecko.git] / dlls / wined3d / utils.c
blob92a8b48d44ff622b15ebab504fdc2da68c61c681
1 /*
2 * Utility functions for the WineD3D Library
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2008 Henri Verbeet
9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
10 * Copyright 2009-2010 Henri Verbeet for CodeWeavers
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "config.h"
28 #include "wine/port.h"
30 #include "wined3d_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
34 struct StaticPixelFormatDesc
36 enum wined3d_format_id id;
37 DWORD alphaMask, redMask, greenMask, blueMask;
38 UINT bpp;
39 BYTE depthSize, stencilSize;
42 /*****************************************************************************
43 * Pixel format array
45 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
46 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
47 * high masks do not fit into the 32 bit values needed for ddraw. It is only
48 * used for ddraw mostly, and to figure out if the format has alpha at all, so
49 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
50 * formats are not usable in 2D rendering because ddraw doesn't support them.
52 static const struct StaticPixelFormatDesc formats[] =
54 /* format id alphamask redmask greenmask bluemask bpp depth stencil */
55 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
56 /* FourCC formats */
57 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
58 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
59 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
60 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
61 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
62 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
63 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
64 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
65 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
66 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
67 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
68 /* IEEE formats */
69 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
70 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
71 {WINED3DFMT_R32G32B32_FLOAT, 0x0, 0x0, 0x0, 0x0, 12, 0, 0},
72 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0},
73 /* Hmm? */
74 {WINED3DFMT_R8G8_SNORM_Cx, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
75 /* Float */
76 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
77 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
78 {WINED3DFMT_R16G16_SINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
79 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
80 {WINED3DFMT_R16G16B16A16_SINT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
81 /* Palettized formats */
82 {WINED3DFMT_P8_UINT_A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
83 {WINED3DFMT_P8_UINT, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
84 /* Standard ARGB formats. */
85 {WINED3DFMT_B8G8R8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0},
86 {WINED3DFMT_B8G8R8A8_UNORM, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
87 {WINED3DFMT_B8G8R8X8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
88 {WINED3DFMT_B5G6R5_UNORM, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0},
89 {WINED3DFMT_B5G5R5X1_UNORM, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
90 {WINED3DFMT_B5G5R5A1_UNORM, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
91 {WINED3DFMT_B4G4R4A4_UNORM, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
92 {WINED3DFMT_B2G3R3_UNORM, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0},
93 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0},
94 {WINED3DFMT_B2G3R3A8_UNORM, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0},
95 {WINED3DFMT_B4G4R4X4_UNORM, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
96 {WINED3DFMT_R10G10B10A2_UNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
97 {WINED3DFMT_R10G10B10A2_UINT, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
98 {WINED3DFMT_R10G10B10A2_SNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
99 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
100 {WINED3DFMT_R8G8B8A8_UINT, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
101 {WINED3DFMT_R8G8B8X8_UNORM, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
102 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0},
103 {WINED3DFMT_B10G10R10A2_UNORM, 0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0},
104 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0},
105 /* Luminance */
106 {WINED3DFMT_L8_UNORM, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
107 {WINED3DFMT_L8A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
108 {WINED3DFMT_L4A4_UNORM, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0},
109 {WINED3DFMT_L16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
110 /* Bump mapping stuff */
111 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
112 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
113 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
114 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
115 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
116 {WINED3DFMT_R10G11B11_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
117 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0},
118 /* Depth stencil formats */
119 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
120 {WINED3DFMT_D32_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
121 {WINED3DFMT_S1_UINT_D15_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 15, 1},
122 {WINED3DFMT_D24_UNORM_S8_UINT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
123 {WINED3DFMT_X8D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 0},
124 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 4},
125 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
126 {WINED3DFMT_D32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
127 {WINED3DFMT_S8_UINT_D24_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
128 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
129 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
130 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
131 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
132 /* Vendor-specific formats */
133 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
134 {WINED3DFMT_NVDB, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
135 {WINED3DFMT_INTZ, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
136 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
137 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
138 {WINED3DFMT_NULL, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
139 /* Unsure about them, could not find a Windows driver that supports them */
140 {WINED3DFMT_R16, 0x0, 0x0000ffff, 0x0, 0x0, 2, 0, 0},
141 {WINED3DFMT_AL16, 0xffff0000, 0x0, 0x0, 0x0, 4, 0, 0},
144 struct wined3d_format_base_flags
146 enum wined3d_format_id id;
147 DWORD flags;
150 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
151 * still needs to use the correct block based calculation for e.g. the
152 * resource size. */
153 static const struct wined3d_format_base_flags format_base_flags[] =
155 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
156 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
157 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
158 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
159 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
160 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
161 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
162 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
163 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
164 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
165 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
166 {WINED3DFMT_INTZ, WINED3DFMT_FLAG_FOURCC},
167 {WINED3DFMT_NULL, WINED3DFMT_FLAG_FOURCC},
168 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
169 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
170 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
171 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
172 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
173 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
174 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
175 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
176 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
177 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
178 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
179 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
180 {WINED3DFMT_NVDB, WINED3DFMT_FLAG_FOURCC},
181 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
182 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
183 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
184 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
185 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
186 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
187 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
188 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
189 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
190 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
191 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
194 struct wined3d_format_block_info
196 enum wined3d_format_id id;
197 UINT block_width;
198 UINT block_height;
199 UINT block_byte_count;
202 static const struct wined3d_format_block_info format_block_info[] =
204 {WINED3DFMT_DXT1, 4, 4, 8},
205 {WINED3DFMT_DXT2, 4, 4, 16},
206 {WINED3DFMT_DXT3, 4, 4, 16},
207 {WINED3DFMT_DXT4, 4, 4, 16},
208 {WINED3DFMT_DXT5, 4, 4, 16},
209 {WINED3DFMT_ATI2N, 4, 4, 16},
210 {WINED3DFMT_YUY2, 2, 1, 4},
211 {WINED3DFMT_UYVY, 2, 1, 4},
214 struct wined3d_format_vertex_info
216 enum wined3d_format_id id;
217 enum wined3d_ffp_emit_idx emit_idx;
218 GLint component_count;
219 GLenum gl_vtx_type;
220 GLint gl_vtx_format;
221 GLboolean gl_normalized;
222 unsigned int component_size;
225 static const struct wined3d_format_vertex_info format_vertex_info[] =
227 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
228 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
229 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
230 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
231 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
232 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
233 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
234 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
235 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
236 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
237 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
238 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
239 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
240 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
241 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
242 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
243 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
246 struct wined3d_format_texture_info
248 enum wined3d_format_id id;
249 GLint gl_internal;
250 GLint gl_srgb_internal;
251 GLint gl_rt_internal;
252 GLint gl_format;
253 GLint gl_type;
254 unsigned int conv_byte_count;
255 unsigned int flags;
256 enum wined3d_gl_extension extension;
257 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
260 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
262 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
263 * format+type combination to load it. Thus convert it to A8L8, then load it
264 * with A4L4 internal, but A8L8 format+type
266 unsigned int x, y;
267 const unsigned char *Source;
268 unsigned char *Dest;
269 UINT outpitch = pitch * 2;
271 for(y = 0; y < height; y++) {
272 Source = src + y * pitch;
273 Dest = dst + y * outpitch;
274 for (x = 0; x < width; x++ ) {
275 unsigned char color = (*Source++);
276 /* A */ Dest[1] = (color & 0xf0) << 0;
277 /* L */ Dest[0] = (color & 0x0f) << 4;
278 Dest += 2;
283 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
285 unsigned int x, y;
286 const WORD *Source;
288 for(y = 0; y < height; y++)
290 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
291 Source = (const WORD *)(src + y * pitch);
292 for (x = 0; x < width; x++ )
294 short color = (*Source++);
295 unsigned char l = ((color >> 10) & 0xfc);
296 short v = ((color >> 5) & 0x3e);
297 short u = ((color ) & 0x1f);
298 short v_conv = v + 16;
299 short u_conv = u + 16;
301 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
302 Dest_s += 1;
307 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
309 unsigned int x, y;
310 const WORD *Source;
311 unsigned char *Dest;
312 UINT outpitch = (pitch * 3)/2;
314 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
315 * fixed function and shaders without further conversion once the surface is
316 * loaded
318 for(y = 0; y < height; y++) {
319 Source = (const WORD *)(src + y * pitch);
320 Dest = dst + y * outpitch;
321 for (x = 0; x < width; x++ ) {
322 short color = (*Source++);
323 unsigned char l = ((color >> 10) & 0xfc);
324 char v = ((color >> 5) & 0x3e);
325 char u = ((color ) & 0x1f);
327 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
328 * and doubles the positive range. Thus shift left only once, gl does the 2nd
329 * shift. GL reads a signed value and converts it into an unsigned value.
331 /* M */ Dest[2] = l << 1;
333 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
334 * from 5 bit values to 8 bit values.
336 /* V */ Dest[1] = v << 3;
337 /* U */ Dest[0] = u << 3;
338 Dest += 3;
343 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
345 unsigned int x, y;
346 const short *Source;
347 unsigned char *Dest;
348 UINT outpitch = (pitch * 3)/2;
350 for(y = 0; y < height; y++)
352 Source = (const short *)(src + y * pitch);
353 Dest = dst + y * outpitch;
354 for (x = 0; x < width; x++ )
356 const short color = (*Source++);
357 /* B */ Dest[0] = 0xff;
358 /* G */ Dest[1] = (color >> 8) + 128; /* V */
359 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
360 Dest += 3;
365 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
367 unsigned int x, y;
368 const DWORD *Source;
369 unsigned char *Dest;
371 /* Doesn't work correctly with the fixed function pipeline, but can work in
372 * shaders if the shader is adjusted. (There's no use for this format in gl's
373 * standard fixed function pipeline anyway).
375 for(y = 0; y < height; y++)
377 Source = (const DWORD *)(src + y * pitch);
378 Dest = dst + y * pitch;
379 for (x = 0; x < width; x++ )
381 LONG color = (*Source++);
382 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
383 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
384 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
385 Dest += 4;
390 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
392 unsigned int x, y;
393 const DWORD *Source;
394 unsigned char *Dest;
396 /* This implementation works with the fixed function pipeline and shaders
397 * without further modification after converting the surface.
399 for(y = 0; y < height; y++)
401 Source = (const DWORD *)(src + y * pitch);
402 Dest = dst + y * pitch;
403 for (x = 0; x < width; x++ )
405 LONG color = (*Source++);
406 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
407 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
408 /* U */ Dest[0] = (color & 0xff); /* U */
409 /* I */ Dest[3] = 255; /* X */
410 Dest += 4;
415 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
417 unsigned int x, y;
418 const DWORD *Source;
419 unsigned char *Dest;
421 for(y = 0; y < height; y++)
423 Source = (const DWORD *)(src + y * pitch);
424 Dest = dst + y * pitch;
425 for (x = 0; x < width; x++ )
427 LONG color = (*Source++);
428 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
429 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
430 /* R */ Dest[2] = (color & 0xff) + 128; /* U */
431 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
432 Dest += 4;
437 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
439 unsigned int x, y;
440 const DWORD *Source;
441 unsigned short *Dest;
442 UINT outpitch = (pitch * 3)/2;
444 for(y = 0; y < height; y++)
446 Source = (const DWORD *)(src + y * pitch);
447 Dest = (unsigned short *) (dst + y * outpitch);
448 for (x = 0; x < width; x++ )
450 const DWORD color = (*Source++);
451 /* B */ Dest[0] = 0xffff;
452 /* G */ Dest[1] = (color >> 16) + 32768; /* V */
453 /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */
454 Dest += 3;
459 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
461 unsigned int x, y;
462 const WORD *Source;
463 WORD *Dest;
464 UINT outpitch = (pitch * 3)/2;
466 for(y = 0; y < height; y++)
468 Source = (const WORD *)(src + y * pitch);
469 Dest = (WORD *) (dst + y * outpitch);
470 for (x = 0; x < width; x++ )
472 WORD green = (*Source++);
473 WORD red = (*Source++);
474 Dest[0] = green;
475 Dest[1] = red;
476 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
477 * shader overwrites it anyway
479 Dest[2] = 0xffff;
480 Dest += 3;
485 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
487 unsigned int x, y;
488 const float *Source;
489 float *Dest;
490 UINT outpitch = (pitch * 3)/2;
492 for(y = 0; y < height; y++)
494 Source = (const float *)(src + y * pitch);
495 Dest = (float *) (dst + y * outpitch);
496 for (x = 0; x < width; x++ )
498 float green = (*Source++);
499 float red = (*Source++);
500 Dest[0] = green;
501 Dest[1] = red;
502 Dest[2] = 1.0f;
503 Dest += 3;
508 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
510 unsigned int x, y;
511 UINT outpitch = pitch * 2;
513 for (y = 0; y < height; ++y)
515 const WORD *source = (const WORD *)(src + y * pitch);
516 DWORD *dest = (DWORD *)(dst + y * outpitch);
518 for (x = 0; x < width; ++x)
520 /* The depth data is normalized, so needs to be scaled,
521 * the stencil data isn't. Scale depth data by
522 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
523 WORD d15 = source[x] >> 1;
524 DWORD d24 = (d15 << 9) + (d15 >> 6);
525 dest[x] = (d24 << 8) | (source[x] & 0x1);
530 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
532 unsigned int x, y;
534 for (y = 0; y < height; ++y)
536 const DWORD *source = (const DWORD *)(src + y * pitch);
537 DWORD *dest = (DWORD *)(dst + y * pitch);
539 for (x = 0; x < width; ++x)
541 /* Just need to clear out the X4 part. */
542 dest[x] = source[x] & ~0xf0;
547 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
549 unsigned int x, y;
550 UINT outpitch = pitch * 2;
552 for (y = 0; y < height; ++y)
554 const DWORD *source = (const DWORD *)(src + y * pitch);
555 float *dest_f = (float *)(dst + y * outpitch);
556 DWORD *dest_s = (DWORD *)(dst + y * outpitch);
558 for (x = 0; x < width; ++x)
560 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
561 dest_s[x * 2 + 1] = source[x] & 0xff;
566 static const struct wined3d_format_texture_info format_texture_info[] =
568 /* format id internal srgbInternal rtInternal
569 format type
570 flags
571 extension */
572 /* FourCC formats */
573 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
574 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
575 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
576 * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
577 * endian machine
579 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
580 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
581 WINED3DFMT_FLAG_FILTERING,
582 WINED3D_GL_EXT_NONE, NULL},
583 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
584 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
585 WINED3DFMT_FLAG_FILTERING,
586 APPLE_YCBCR_422, NULL},
587 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
588 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
589 WINED3DFMT_FLAG_FILTERING,
590 WINED3D_GL_EXT_NONE, NULL},
591 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
592 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
593 WINED3DFMT_FLAG_FILTERING,
594 APPLE_YCBCR_422, NULL},
595 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
596 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
597 WINED3DFMT_FLAG_FILTERING,
598 WINED3D_GL_EXT_NONE, NULL},
599 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
600 GL_RGBA, GL_UNSIGNED_BYTE, 0,
601 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
602 | WINED3DFMT_FLAG_COMPRESSED,
603 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
604 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
605 GL_RGBA, GL_UNSIGNED_BYTE, 0,
606 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
607 | WINED3DFMT_FLAG_COMPRESSED,
608 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
609 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
610 GL_RGBA, GL_UNSIGNED_BYTE, 0,
611 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
612 | WINED3DFMT_FLAG_COMPRESSED,
613 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
614 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
615 GL_RGBA, GL_UNSIGNED_BYTE, 0,
616 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
617 | WINED3DFMT_FLAG_COMPRESSED,
618 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
619 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
620 GL_RGBA, GL_UNSIGNED_BYTE, 0,
621 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
622 | WINED3DFMT_FLAG_COMPRESSED,
623 EXT_TEXTURE_COMPRESSION_S3TC, NULL},
624 /* IEEE formats */
625 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
626 GL_RED, GL_FLOAT, 0,
627 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
628 ARB_TEXTURE_FLOAT, NULL},
629 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
630 GL_RED, GL_FLOAT, 0,
631 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
632 ARB_TEXTURE_RG, NULL},
633 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
634 GL_RGB, GL_FLOAT, 12,
635 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
636 ARB_TEXTURE_FLOAT, convert_r32g32_float},
637 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
638 GL_RG, GL_FLOAT, 0,
639 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
640 ARB_TEXTURE_RG, NULL},
641 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
642 GL_RGBA, GL_FLOAT, 0,
643 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
644 ARB_TEXTURE_FLOAT, NULL},
645 /* Float */
646 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
647 GL_RED, GL_HALF_FLOAT_ARB, 0,
648 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
649 ARB_TEXTURE_FLOAT, NULL},
650 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
651 GL_RED, GL_HALF_FLOAT_ARB, 0,
652 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
653 ARB_TEXTURE_RG, NULL},
654 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
655 GL_RGB, GL_HALF_FLOAT_ARB, 6,
656 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
657 ARB_TEXTURE_FLOAT, convert_r16g16},
658 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
659 GL_RG, GL_HALF_FLOAT_ARB, 0,
660 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
661 ARB_TEXTURE_RG, NULL},
662 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
663 GL_RGBA, GL_HALF_FLOAT_ARB, 0,
664 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
665 ARB_TEXTURE_FLOAT, NULL},
666 /* Palettized formats */
667 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
668 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
670 ARB_FRAGMENT_PROGRAM, NULL},
671 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
672 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
674 EXT_PALETTED_TEXTURE, NULL},
675 /* Standard ARGB formats */
676 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
677 GL_BGR, GL_UNSIGNED_BYTE, 0,
678 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
679 WINED3D_GL_EXT_NONE, NULL},
680 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
681 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
682 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
683 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE | WINED3DFMT_FLAG_VTF,
684 WINED3D_GL_EXT_NONE, NULL},
685 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
686 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
687 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
688 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
689 WINED3D_GL_EXT_NONE, NULL},
690 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
691 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
692 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
693 WINED3D_GL_EXT_NONE, NULL},
694 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
695 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
696 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
697 WINED3D_GL_EXT_NONE, NULL},
698 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
699 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
700 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
701 WINED3D_GL_EXT_NONE, NULL},
702 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
703 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
704 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
705 WINED3D_GL_EXT_NONE, NULL},
706 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
707 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
708 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
709 WINED3D_GL_EXT_NONE, NULL},
710 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
711 GL_ALPHA, GL_UNSIGNED_BYTE, 0,
712 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
713 WINED3D_GL_EXT_NONE, NULL},
714 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
715 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
716 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
717 WINED3D_GL_EXT_NONE, NULL},
718 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
719 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
720 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
721 WINED3D_GL_EXT_NONE, NULL},
722 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
723 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
724 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
725 WINED3D_GL_EXT_NONE, NULL},
726 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
727 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
728 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
729 WINED3D_GL_EXT_NONE, NULL},
730 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
731 GL_RGB, GL_UNSIGNED_SHORT, 6,
732 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
733 WINED3D_GL_EXT_NONE, convert_r16g16},
734 {WINED3DFMT_R16G16_UNORM, GL_RG16, GL_RG16, 0,
735 GL_RG, GL_UNSIGNED_SHORT, 0,
736 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
737 ARB_TEXTURE_RG, NULL},
738 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
739 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
740 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
741 WINED3D_GL_EXT_NONE, NULL},
742 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
743 GL_RGBA, GL_UNSIGNED_SHORT, 0,
744 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
745 WINED3D_GL_EXT_NONE, NULL},
746 /* Luminance */
747 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
748 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
749 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
750 WINED3D_GL_EXT_NONE, NULL},
751 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
752 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
753 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
754 WINED3D_GL_EXT_NONE, NULL},
755 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
756 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
757 WINED3DFMT_FLAG_FILTERING,
758 WINED3D_GL_EXT_NONE, convert_l4a4_unorm},
759 /* Bump mapping stuff */
760 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
761 GL_BGR, GL_UNSIGNED_BYTE, 3,
762 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
763 WINED3D_GL_EXT_NONE, convert_r8g8_snorm},
764 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
765 GL_DSDT_NV, GL_BYTE, 0,
766 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
767 NV_TEXTURE_SHADER, NULL},
768 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
769 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
770 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
771 WINED3D_GL_EXT_NONE, convert_r5g5_snorm_l6_unorm},
772 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
773 GL_DSDT_MAG_NV, GL_BYTE, 3,
774 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
775 NV_TEXTURE_SHADER, convert_r5g5_snorm_l6_unorm_nv},
776 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
777 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
778 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
779 WINED3D_GL_EXT_NONE, convert_r8g8_snorm_l8x8_unorm},
780 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
781 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
782 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
783 NV_TEXTURE_SHADER, convert_r8g8_snorm_l8x8_unorm_nv},
784 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
785 GL_BGRA, GL_UNSIGNED_BYTE, 4,
786 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
787 WINED3D_GL_EXT_NONE, convert_r8g8b8a8_snorm},
788 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
789 GL_RGBA, GL_BYTE, 0,
790 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
791 NV_TEXTURE_SHADER, NULL},
792 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
793 GL_BGR, GL_UNSIGNED_SHORT, 6,
794 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
795 WINED3D_GL_EXT_NONE, convert_r16g16_snorm},
796 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
797 GL_HILO_NV, GL_SHORT, 0,
798 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
799 NV_TEXTURE_SHADER, NULL},
800 /* Depth stencil formats */
801 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
802 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
803 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
804 ARB_DEPTH_TEXTURE, NULL},
805 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
806 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
807 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
808 ARB_DEPTH_TEXTURE, NULL},
809 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
810 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
811 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
812 ARB_DEPTH_TEXTURE, NULL},
813 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
814 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
815 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
816 EXT_PACKED_DEPTH_STENCIL, convert_s1_uint_d15_unorm},
817 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
818 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
819 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
820 ARB_FRAMEBUFFER_OBJECT, convert_s1_uint_d15_unorm},
821 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
822 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
823 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
824 | WINED3DFMT_FLAG_SHADOW,
825 ARB_DEPTH_TEXTURE, NULL},
826 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
827 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
828 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
829 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
830 EXT_PACKED_DEPTH_STENCIL, NULL},
831 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
832 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
833 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
834 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
835 ARB_FRAMEBUFFER_OBJECT, NULL},
836 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
837 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
838 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
839 | WINED3DFMT_FLAG_SHADOW,
840 ARB_DEPTH_TEXTURE, NULL},
841 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
842 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
843 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
844 ARB_DEPTH_TEXTURE, NULL},
845 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
846 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
847 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
848 EXT_PACKED_DEPTH_STENCIL, convert_s4x4_uint_d24_unorm},
849 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
850 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
851 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
852 ARB_FRAMEBUFFER_OBJECT, convert_s4x4_uint_d24_unorm},
853 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
854 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
855 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
856 | WINED3DFMT_FLAG_SHADOW,
857 ARB_DEPTH_TEXTURE, NULL},
858 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
859 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
860 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
861 WINED3D_GL_EXT_NONE, NULL},
862 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
863 GL_DEPTH_COMPONENT, GL_FLOAT, 0,
864 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
865 ARB_DEPTH_BUFFER_FLOAT, NULL},
866 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
867 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
868 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
869 ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float},
870 /* Vendor-specific formats */
871 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
872 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
873 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_COMPRESSED,
874 ATI_TEXTURE_COMPRESSION_3DC, NULL},
875 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2, GL_COMPRESSED_RED_GREEN_RGTC2, 0,
876 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
877 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_COMPRESSED,
878 ARB_TEXTURE_COMPRESSION_RGTC, NULL},
879 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
880 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
881 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
882 | WINED3DFMT_FLAG_STENCIL,
883 EXT_PACKED_DEPTH_STENCIL, NULL},
884 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
885 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
886 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
887 | WINED3DFMT_FLAG_STENCIL,
888 ARB_FRAMEBUFFER_OBJECT, NULL},
889 {WINED3DFMT_NULL, GL_RGBA8, GL_RGBA8, 0,
890 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
891 WINED3DFMT_FLAG_RENDERTARGET,
892 ARB_FRAMEBUFFER_OBJECT, NULL},
895 static inline int getFmtIdx(enum wined3d_format_id format_id)
897 /* First check if the format is at the position of its value.
898 * This will catch the argb formats before the loop is entered. */
899 if (format_id < (sizeof(formats) / sizeof(*formats))
900 && formats[format_id].id == format_id)
902 return format_id;
904 else
906 unsigned int i;
908 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
910 if (formats[i].id == format_id) return i;
913 return -1;
916 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
918 UINT format_count = sizeof(formats) / sizeof(*formats);
919 UINT i;
921 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
922 if (!gl_info->formats)
924 ERR("Failed to allocate memory.\n");
925 return FALSE;
928 for (i = 0; i < format_count; ++i)
930 struct wined3d_format *format = &gl_info->formats[i];
931 format->id = formats[i].id;
932 format->red_mask = formats[i].redMask;
933 format->green_mask = formats[i].greenMask;
934 format->blue_mask = formats[i].blueMask;
935 format->alpha_mask = formats[i].alphaMask;
936 format->byte_count = formats[i].bpp;
937 format->depth_size = formats[i].depthSize;
938 format->stencil_size = formats[i].stencilSize;
939 format->block_width = 1;
940 format->block_height = 1;
941 format->block_byte_count = formats[i].bpp;
944 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
946 int fmt_idx = getFmtIdx(format_base_flags[i].id);
948 if (fmt_idx == -1)
950 ERR("Format %s (%#x) not found.\n",
951 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
952 HeapFree(GetProcessHeap(), 0, gl_info->formats);
953 return FALSE;
956 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
959 return TRUE;
962 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
964 unsigned int i;
966 for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i)
968 struct wined3d_format *format;
969 int fmt_idx = getFmtIdx(format_block_info[i].id);
971 if (fmt_idx == -1)
973 ERR("Format %s (%#x) not found.\n",
974 debug_d3dformat(format_block_info[i].id), format_block_info[i].id);
975 return FALSE;
978 format = &gl_info->formats[fmt_idx];
979 format->block_width = format_block_info[i].block_width;
980 format->block_height = format_block_info[i].block_height;
981 format->block_byte_count = format_block_info[i].block_byte_count;
982 format->flags |= WINED3DFMT_FLAG_BLOCKS;
985 return TRUE;
988 /* Context activation is done by the caller. */
989 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
991 /* Check if the default internal format is supported as a frame buffer
992 * target, otherwise fall back to the render target internal.
994 * Try to stick to the standard format if possible, this limits precision differences. */
995 GLenum status;
996 GLuint tex;
998 ENTER_GL();
1000 while (gl_info->gl_ops.gl.p_glGetError());
1001 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
1003 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1004 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1006 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0,
1007 format->glFormat, format->glType, NULL);
1008 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1009 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1011 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1013 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1014 checkGLcall("Framebuffer format check");
1016 if (status == GL_FRAMEBUFFER_COMPLETE)
1018 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
1019 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
1020 format->rtInternal = format->glInternal;
1022 else
1024 if (!format->rtInternal)
1026 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
1028 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
1029 " and no fallback specified.\n", debug_d3dformat(format->id));
1030 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1032 else
1034 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
1036 format->rtInternal = format->glInternal;
1038 else
1040 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
1041 debug_d3dformat(format->id));
1043 while (gl_info->gl_ops.gl.p_glGetError());
1045 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1047 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0,
1048 format->glFormat, format->glType, NULL);
1049 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1050 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1052 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1054 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1055 checkGLcall("Framebuffer format check");
1057 if (status == GL_FRAMEBUFFER_COMPLETE)
1059 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
1060 debug_d3dformat(format->id));
1062 else
1064 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1065 debug_d3dformat(format->id));
1066 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
1071 if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
1072 || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
1073 && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
1074 && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA)
1076 GLuint rb, tex2;
1077 DWORD readback[16 * 16], color;
1078 BYTE r, a;
1079 BOOL match = TRUE;
1081 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1082 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1084 gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
1085 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
1086 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
1087 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
1088 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
1089 checkGLcall("RB attachment");
1092 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
1093 gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1094 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1095 if (gl_info->gl_ops.gl.p_glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
1097 while (gl_info->gl_ops.gl.p_glGetError());
1098 TRACE("Format doesn't support post-pixelshader blending.\n");
1099 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1101 else
1103 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16);
1104 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1105 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1106 gl_info->gl_ops.gl.p_glLoadIdentity();
1107 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1108 gl_info->gl_ops.gl.p_glLoadIdentity();
1110 gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1112 /* Draw a full-black quad */
1113 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1114 gl_info->gl_ops.gl.p_glColor4ub(0x00, 0x00, 0x00, 0xff);
1115 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1116 gl_info->gl_ops.gl.p_glColor4ub(0x00, 0x00, 0x00, 0xff);
1117 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1118 gl_info->gl_ops.gl.p_glColor4ub(0x00, 0x00, 0x00, 0xff);
1119 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1120 gl_info->gl_ops.gl.p_glColor4ub(0x00, 0x00, 0x00, 0xff);
1121 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1122 gl_info->gl_ops.gl.p_glEnd();
1124 /* Draw a half-transparent red quad */
1125 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1126 gl_info->gl_ops.gl.p_glColor4ub(0xff, 0x00, 0x00, 0x80);
1127 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
1128 gl_info->gl_ops.gl.p_glColor4ub(0xff, 0x00, 0x00, 0x80);
1129 gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
1130 gl_info->gl_ops.gl.p_glColor4ub(0xff, 0x00, 0x00, 0x80);
1131 gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
1132 gl_info->gl_ops.gl.p_glColor4ub(0xff, 0x00, 0x00, 0x80);
1133 gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
1134 gl_info->gl_ops.gl.p_glEnd();
1136 gl_info->gl_ops.gl.p_glGenTextures(1, &tex2);
1137 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex2);
1139 gl_info->gl_ops.gl.p_glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, 16, 16, 0);
1140 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1141 checkGLcall("Post-pixelshader blending check");
1143 color = readback[7 * 16 + 7];
1144 a = color >> 24;
1145 r = (color & 0x00ff0000) >> 16;
1147 if (format->red_mask && (r < 0x7b || r > 0x84))
1148 match = FALSE;
1149 /* If the alpha component is more than 1 bit */
1150 else if ((format->alpha_mask & (format->alpha_mask - 1)) && (a < 0x9f || a > 0xdf))
1151 match = FALSE;
1152 if (!match)
1154 TRACE("Format doesn't support post-pixelshader blending.\n");
1155 TRACE("Color output: %#x\n", color);
1156 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1158 else
1160 TRACE("Format supports post-pixelshader blending.\n");
1161 TRACE("Color output: %#x\n", color);
1162 format->flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
1165 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1166 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex2);
1169 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
1170 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
1172 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
1173 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
1174 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
1175 checkGLcall("RB cleanup");
1179 if (format->glInternal != format->glGammaInternal)
1181 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0,
1182 format->glFormat, format->glType, NULL);
1183 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1185 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1186 checkGLcall("Framebuffer format check");
1188 if (status == GL_FRAMEBUFFER_COMPLETE)
1190 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
1191 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1193 else
1195 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
1198 else if (status == GL_FRAMEBUFFER_COMPLETE)
1199 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
1201 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1203 LEAVE_GL();
1206 /* Context activation is done by the caller. */
1207 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
1209 unsigned int i;
1210 GLuint fbo;
1212 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1214 ENTER_GL();
1216 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1217 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1218 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1219 gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0);
1221 LEAVE_GL();
1224 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
1226 struct wined3d_format *format = &gl_info->formats[i];
1228 if (!format->glInternal) continue;
1230 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
1232 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1233 debug_d3dformat(format->id));
1234 continue;
1237 if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
1239 TRACE("Skipping format %s because it's a compressed format.\n",
1240 debug_d3dformat(format->id));
1241 continue;
1244 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1246 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
1247 check_fbo_compat(gl_info, format);
1249 else
1251 format->rtInternal = format->glInternal;
1255 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1257 ENTER_GL();
1259 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1261 LEAVE_GL();
1265 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
1267 unsigned int i;
1269 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
1271 int fmt_idx = getFmtIdx(format_texture_info[i].id);
1272 struct wined3d_format *format;
1274 if (fmt_idx == -1)
1276 ERR("Format %s (%#x) not found.\n",
1277 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
1278 return FALSE;
1281 if (!gl_info->supported[format_texture_info[i].extension]) continue;
1283 format = &gl_info->formats[fmt_idx];
1285 /* ARB_texture_rg defines floating point formats, but only if
1286 * ARB_texture_float is also supported. */
1287 if (!gl_info->supported[ARB_TEXTURE_FLOAT]
1288 && (format->flags & WINED3DFMT_FLAG_FLOAT))
1289 continue;
1291 format->glInternal = format_texture_info[i].gl_internal;
1292 format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
1293 format->rtInternal = format_texture_info[i].gl_rt_internal;
1294 format->glFormat = format_texture_info[i].gl_format;
1295 format->glType = format_texture_info[i].gl_type;
1296 format->color_fixup = COLOR_FIXUP_IDENTITY;
1297 format->flags |= format_texture_info[i].flags;
1298 format->height_scale.numerator = 1;
1299 format->height_scale.denominator = 1;
1301 if (format->glGammaInternal != format->glInternal)
1303 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
1304 if (!gl_info->supported[EXT_TEXTURE_SRGB])
1306 format->glGammaInternal = format->glInternal;
1307 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
1309 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1311 format->glInternal = format->glGammaInternal;
1315 /* Texture conversion stuff */
1316 format->convert = format_texture_info[i].convert;
1317 format->conv_byte_count = format_texture_info[i].conv_byte_count;
1320 return TRUE;
1323 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
1325 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1326 c1 >>= 8; c2 >>= 8;
1327 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1328 c1 >>= 8; c2 >>= 8;
1329 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1330 c1 >>= 8; c2 >>= 8;
1331 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
1332 return TRUE;
1335 /* A context is provided by the caller */
1336 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
1338 static const DWORD data[] = {0x00000000, 0xffffffff};
1339 GLuint tex, fbo, buffer;
1340 DWORD readback[16 * 1];
1341 BOOL ret = FALSE;
1343 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1344 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1345 * falling back to software. If this changes in the future this code will get fooled and
1346 * apps might hit the software path due to incorrectly advertised caps.
1348 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1349 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1350 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1353 ENTER_GL();
1354 while (gl_info->gl_ops.gl.p_glGetError());
1356 gl_info->gl_ops.gl.p_glGenTextures(1, &buffer);
1357 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1358 memset(readback, 0x7e, sizeof(readback));
1359 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0,
1360 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
1361 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1362 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1363 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1364 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1365 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1367 gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
1368 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
1369 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0,
1370 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
1371 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1372 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1373 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1374 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1375 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1376 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
1378 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
1379 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1380 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
1381 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
1383 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1);
1384 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
1385 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
1386 gl_info->gl_ops.gl.p_glLoadIdentity();
1387 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
1388 gl_info->gl_ops.gl.p_glLoadIdentity();
1390 gl_info->gl_ops.gl.p_glClearColor(0, 1, 0, 0);
1391 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
1393 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
1394 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 0.0);
1395 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, -1.0f);
1396 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 0.0);
1397 gl_info->gl_ops.gl.p_glVertex2f(1.0f, -1.0f);
1398 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 1.0);
1399 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, 1.0f);
1400 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 1.0);
1401 gl_info->gl_ops.gl.p_glVertex2f(1.0f, 1.0f);
1402 gl_info->gl_ops.gl.p_glEnd();
1404 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
1405 memset(readback, 0x7f, sizeof(readback));
1406 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
1407 if (color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5)
1408 || color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
1410 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, assuming no filtering\n",
1411 readback[6], readback[9]);
1412 ret = FALSE;
1414 else
1416 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1417 readback[6], readback[9]);
1418 ret = TRUE;
1421 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1422 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
1423 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
1424 gl_info->gl_ops.gl.p_glDeleteTextures(1, &buffer);
1426 if (gl_info->gl_ops.gl.p_glGetError())
1428 FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
1429 ret = FALSE;
1431 LEAVE_GL();
1432 return ret;
1435 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1437 struct wined3d_format *format;
1438 unsigned int fmt_idx, i;
1439 static const enum wined3d_format_id fmts16[] =
1441 WINED3DFMT_R16_FLOAT,
1442 WINED3DFMT_R16G16_FLOAT,
1443 WINED3DFMT_R16G16B16A16_FLOAT,
1445 BOOL filtered;
1447 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
1449 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1450 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
1452 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1453 filtered = TRUE;
1455 else if (gl_info->limits.glsl_varyings > 44)
1457 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1458 filtered = TRUE;
1460 else
1462 TRACE("Assuming no float16 blending\n");
1463 filtered = FALSE;
1466 if(filtered)
1468 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1470 fmt_idx = getFmtIdx(fmts16[i]);
1471 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
1474 return;
1477 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
1479 fmt_idx = getFmtIdx(fmts16[i]);
1480 format = &gl_info->formats[fmt_idx];
1481 if (!format->glInternal) continue; /* Not supported by GL */
1483 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
1484 if(filtered)
1486 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
1487 format->flags |= WINED3DFMT_FLAG_FILTERING;
1489 else
1491 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
1496 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
1498 int idx;
1500 idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
1501 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1502 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1504 idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
1505 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1506 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1508 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
1509 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1510 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1512 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1513 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1514 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1516 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
1517 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1518 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
1520 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1521 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1522 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1523 * the only driver that implements it(fglrx) has a buggy implementation.
1525 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1526 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1527 * conversion for this format.
1529 if (!gl_info->supported[NV_TEXTURE_SHADER])
1531 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1532 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1533 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1534 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1535 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1536 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1538 else
1540 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
1541 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1542 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1544 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
1545 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1546 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1549 if (!gl_info->supported[NV_TEXTURE_SHADER])
1551 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1552 * with each other
1554 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1555 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1556 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
1557 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1558 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1559 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
1560 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
1561 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1562 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
1564 else
1566 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1567 * are converted at surface loading time, but they do not need any modification in
1568 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1569 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1573 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
1575 idx = getFmtIdx(WINED3DFMT_ATI2N);
1576 gl_info->formats[idx].color_fixup = create_color_fixup_desc(
1577 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1579 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
1581 idx = getFmtIdx(WINED3DFMT_ATI2N);
1582 gl_info->formats[idx].color_fixup= create_color_fixup_desc(
1583 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
1586 if (!gl_info->supported[APPLE_YCBCR_422])
1588 idx = getFmtIdx(WINED3DFMT_YUY2);
1589 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
1591 idx = getFmtIdx(WINED3DFMT_UYVY);
1592 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
1595 idx = getFmtIdx(WINED3DFMT_YV12);
1596 gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
1597 gl_info->formats[idx].height_scale.numerator = 3;
1598 gl_info->formats[idx].height_scale.denominator = 2;
1599 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
1601 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
1603 idx = getFmtIdx(WINED3DFMT_P8_UINT);
1604 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
1607 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
1609 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
1610 gl_info->formats[idx].gl_vtx_format = GL_BGRA;
1613 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
1615 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1616 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1617 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
1618 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
1620 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
1621 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
1625 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
1627 unsigned int i;
1629 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
1631 struct wined3d_format *format;
1632 int fmt_idx = getFmtIdx(format_vertex_info[i].id);
1634 if (fmt_idx == -1)
1636 ERR("Format %s (%#x) not found.\n",
1637 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
1638 return FALSE;
1641 format = &gl_info->formats[fmt_idx];
1642 format->emit_idx = format_vertex_info[i].emit_idx;
1643 format->component_count = format_vertex_info[i].component_count;
1644 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
1645 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
1646 format->gl_normalized = format_vertex_info[i].gl_normalized;
1647 format->component_size = format_vertex_info[i].component_size;
1650 return TRUE;
1653 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
1655 if (!init_format_base_info(gl_info)) return FALSE;
1657 if (!init_format_block_info(gl_info))
1659 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1660 gl_info->formats = NULL;
1661 return FALSE;
1664 return TRUE;
1667 /* Context activation is done by the caller. */
1668 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
1670 if (!init_format_base_info(gl_info)) return FALSE;
1672 if (!init_format_block_info(gl_info)) goto fail;
1673 if (!init_format_texture_info(gl_info)) goto fail;
1674 if (!init_format_vertex_info(gl_info)) goto fail;
1676 apply_format_fixups(gl_info);
1677 init_format_fbo_compat_info(gl_info);
1678 init_format_filter_info(gl_info, vendor);
1680 return TRUE;
1682 fail:
1683 HeapFree(GetProcessHeap(), 0, gl_info->formats);
1684 gl_info->formats = NULL;
1685 return FALSE;
1688 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
1689 enum wined3d_format_id format_id)
1691 int idx = getFmtIdx(format_id);
1693 if (idx == -1)
1695 FIXME("Can't find format %s (%#x) in the format lookup table\n",
1696 debug_d3dformat(format_id), format_id);
1697 /* Get the caller a valid pointer */
1698 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
1701 return &gl_info->formats[idx];
1704 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
1706 UINT size;
1708 if (format->id == WINED3DFMT_UNKNOWN)
1710 size = 0;
1712 else if (format->flags & WINED3DFMT_FLAG_BLOCKS)
1714 UINT row_block_count = (width + format->block_width - 1) / format->block_width;
1715 UINT row_count = (height + format->block_height - 1) / format->block_height;
1716 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
1718 else
1720 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
1723 if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
1725 /* The D3D format requirements make sure that the resulting format is an integer again */
1726 size *= format->height_scale.numerator;
1727 size /= format->height_scale.denominator;
1730 return size;
1733 /*****************************************************************************
1734 * Trace formatting of useful values
1736 const char *debug_d3dformat(enum wined3d_format_id format_id)
1738 switch (format_id)
1740 #define FMT_TO_STR(format_id) case format_id: return #format_id
1741 FMT_TO_STR(WINED3DFMT_UNKNOWN);
1742 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
1743 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
1744 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
1745 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
1746 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
1747 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
1748 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
1749 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
1750 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
1751 FMT_TO_STR(WINED3DFMT_P8_UINT);
1752 FMT_TO_STR(WINED3DFMT_L8_UNORM);
1753 FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
1754 FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
1755 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
1756 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
1757 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
1758 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
1759 FMT_TO_STR(WINED3DFMT_UYVY);
1760 FMT_TO_STR(WINED3DFMT_YUY2);
1761 FMT_TO_STR(WINED3DFMT_YV12);
1762 FMT_TO_STR(WINED3DFMT_DXT1);
1763 FMT_TO_STR(WINED3DFMT_DXT2);
1764 FMT_TO_STR(WINED3DFMT_DXT3);
1765 FMT_TO_STR(WINED3DFMT_DXT4);
1766 FMT_TO_STR(WINED3DFMT_DXT5);
1767 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
1768 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
1769 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
1770 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
1771 FMT_TO_STR(WINED3DFMT_D32_UNORM);
1772 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
1773 FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
1774 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
1775 FMT_TO_STR(WINED3DFMT_L16_UNORM);
1776 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
1777 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
1778 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
1779 FMT_TO_STR(WINED3DFMT_ATI2N);
1780 FMT_TO_STR(WINED3DFMT_NVDB);
1781 FMT_TO_STR(WINED3DFMT_NVHU);
1782 FMT_TO_STR(WINED3DFMT_NVHS);
1783 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
1784 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
1785 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
1786 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
1787 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
1788 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
1789 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
1790 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
1791 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
1792 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
1793 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
1794 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
1795 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
1796 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
1797 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
1798 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
1799 FMT_TO_STR(WINED3DFMT_R32G32_UINT);
1800 FMT_TO_STR(WINED3DFMT_R32G32_SINT);
1801 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
1802 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
1803 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
1804 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
1805 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
1806 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
1807 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
1808 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
1809 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
1810 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
1811 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
1812 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
1813 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
1814 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
1815 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
1816 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
1817 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
1818 FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
1819 FMT_TO_STR(WINED3DFMT_R16G16_UINT);
1820 FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
1821 FMT_TO_STR(WINED3DFMT_R16G16_SINT);
1822 FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
1823 FMT_TO_STR(WINED3DFMT_D32_FLOAT);
1824 FMT_TO_STR(WINED3DFMT_R32_FLOAT);
1825 FMT_TO_STR(WINED3DFMT_R32_UINT);
1826 FMT_TO_STR(WINED3DFMT_R32_SINT);
1827 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
1828 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
1829 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
1830 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
1831 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
1832 FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
1833 FMT_TO_STR(WINED3DFMT_R8G8_UINT);
1834 FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
1835 FMT_TO_STR(WINED3DFMT_R8G8_SINT);
1836 FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
1837 FMT_TO_STR(WINED3DFMT_R16_FLOAT);
1838 FMT_TO_STR(WINED3DFMT_D16_UNORM);
1839 FMT_TO_STR(WINED3DFMT_R16_UNORM);
1840 FMT_TO_STR(WINED3DFMT_R16_UINT);
1841 FMT_TO_STR(WINED3DFMT_R16_SNORM);
1842 FMT_TO_STR(WINED3DFMT_R16_SINT);
1843 FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
1844 FMT_TO_STR(WINED3DFMT_R8_UNORM);
1845 FMT_TO_STR(WINED3DFMT_R8_UINT);
1846 FMT_TO_STR(WINED3DFMT_R8_SNORM);
1847 FMT_TO_STR(WINED3DFMT_R8_SINT);
1848 FMT_TO_STR(WINED3DFMT_A8_UNORM);
1849 FMT_TO_STR(WINED3DFMT_R1_UNORM);
1850 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
1851 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
1852 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
1853 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
1854 FMT_TO_STR(WINED3DFMT_BC1_UNORM);
1855 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
1856 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
1857 FMT_TO_STR(WINED3DFMT_BC2_UNORM);
1858 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
1859 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
1860 FMT_TO_STR(WINED3DFMT_BC3_UNORM);
1861 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
1862 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
1863 FMT_TO_STR(WINED3DFMT_BC4_UNORM);
1864 FMT_TO_STR(WINED3DFMT_BC4_SNORM);
1865 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
1866 FMT_TO_STR(WINED3DFMT_BC5_UNORM);
1867 FMT_TO_STR(WINED3DFMT_BC5_SNORM);
1868 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
1869 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
1870 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
1871 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
1872 FMT_TO_STR(WINED3DFMT_INTZ);
1873 FMT_TO_STR(WINED3DFMT_NULL);
1874 FMT_TO_STR(WINED3DFMT_R16);
1875 FMT_TO_STR(WINED3DFMT_AL16);
1876 #undef FMT_TO_STR
1877 default:
1879 char fourcc[5];
1880 fourcc[0] = (char)(format_id);
1881 fourcc[1] = (char)(format_id >> 8);
1882 fourcc[2] = (char)(format_id >> 16);
1883 fourcc[3] = (char)(format_id >> 24);
1884 fourcc[4] = 0;
1885 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
1886 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
1887 else
1888 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
1890 return "unrecognized";
1894 const char *debug_d3ddevicetype(enum wined3d_device_type device_type)
1896 switch (device_type)
1898 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1899 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_HAL);
1900 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_REF);
1901 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_SW);
1902 #undef DEVTYPE_TO_STR
1903 default:
1904 FIXME("Unrecognized device type %#x.\n", device_type);
1905 return "unrecognized";
1909 const char *debug_d3dusage(DWORD usage)
1911 char buf[333];
1913 buf[0] = '\0';
1914 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1915 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
1916 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
1917 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
1918 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
1919 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
1920 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
1921 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
1922 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
1923 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
1924 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
1925 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
1926 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
1927 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
1928 #undef WINED3DUSAGE_TO_STR
1929 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
1931 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1934 const char *debug_d3dusagequery(DWORD usagequery)
1936 char buf[238];
1938 buf[0] = '\0';
1939 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1940 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
1941 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
1942 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
1943 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
1944 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
1945 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
1946 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
1947 #undef WINED3DUSAGEQUERY_TO_STR
1948 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
1950 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
1953 const char *debug_d3ddeclmethod(enum wined3d_decl_method method)
1955 switch (method)
1957 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1958 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_DEFAULT);
1959 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_U);
1960 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_V);
1961 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_CROSS_UV);
1962 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_UV);
1963 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP);
1964 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP_PRESAMPLED);
1965 #undef WINED3DDECLMETHOD_TO_STR
1966 default:
1967 FIXME("Unrecognized declaration method %#x.\n", method);
1968 return "unrecognized";
1972 const char *debug_d3ddeclusage(enum wined3d_decl_usage usage)
1974 switch (usage)
1976 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1977 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITION);
1978 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_WEIGHT);
1979 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_INDICES);
1980 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_NORMAL);
1981 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_PSIZE);
1982 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TEXCOORD);
1983 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TANGENT);
1984 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BINORMAL);
1985 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TESS_FACTOR);
1986 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITIONT);
1987 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_COLOR);
1988 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_FOG);
1989 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_DEPTH);
1990 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_SAMPLE);
1991 #undef WINED3DDECLUSAGE_TO_STR
1992 default:
1993 FIXME("Unrecognized %u declaration usage!\n", usage);
1994 return "unrecognized";
1998 const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
2000 switch (resource_type)
2002 #define RES_TO_STR(res) case res: return #res
2003 RES_TO_STR(WINED3D_RTYPE_SURFACE);
2004 RES_TO_STR(WINED3D_RTYPE_VOLUME);
2005 RES_TO_STR(WINED3D_RTYPE_TEXTURE);
2006 RES_TO_STR(WINED3D_RTYPE_VOLUME_TEXTURE);
2007 RES_TO_STR(WINED3D_RTYPE_CUBE_TEXTURE);
2008 RES_TO_STR(WINED3D_RTYPE_BUFFER);
2009 #undef RES_TO_STR
2010 default:
2011 FIXME("Unrecognized resource type %#x.\n", resource_type);
2012 return "unrecognized";
2016 const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type)
2018 switch (primitive_type)
2020 #define PRIM_TO_STR(prim) case prim: return #prim
2021 PRIM_TO_STR(WINED3D_PT_UNDEFINED);
2022 PRIM_TO_STR(WINED3D_PT_POINTLIST);
2023 PRIM_TO_STR(WINED3D_PT_LINELIST);
2024 PRIM_TO_STR(WINED3D_PT_LINESTRIP);
2025 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST);
2026 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP);
2027 PRIM_TO_STR(WINED3D_PT_TRIANGLEFAN);
2028 PRIM_TO_STR(WINED3D_PT_LINELIST_ADJ);
2029 PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ);
2030 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ);
2031 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ);
2032 #undef PRIM_TO_STR
2033 default:
2034 FIXME("Unrecognized %u primitive type!\n", primitive_type);
2035 return "unrecognized";
2039 const char *debug_d3drenderstate(enum wined3d_render_state state)
2041 switch (state)
2043 #define D3DSTATE_TO_STR(u) case u: return #u
2044 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIAS);
2045 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREPERSPECTIVE);
2046 D3DSTATE_TO_STR(WINED3D_RS_WRAPU);
2047 D3DSTATE_TO_STR(WINED3D_RS_WRAPV);
2048 D3DSTATE_TO_STR(WINED3D_RS_ZENABLE);
2049 D3DSTATE_TO_STR(WINED3D_RS_FILLMODE);
2050 D3DSTATE_TO_STR(WINED3D_RS_SHADEMODE);
2051 D3DSTATE_TO_STR(WINED3D_RS_LINEPATTERN);
2052 D3DSTATE_TO_STR(WINED3D_RS_MONOENABLE);
2053 D3DSTATE_TO_STR(WINED3D_RS_ROP2);
2054 D3DSTATE_TO_STR(WINED3D_RS_PLANEMASK);
2055 D3DSTATE_TO_STR(WINED3D_RS_ZWRITEENABLE);
2056 D3DSTATE_TO_STR(WINED3D_RS_ALPHATESTENABLE);
2057 D3DSTATE_TO_STR(WINED3D_RS_LASTPIXEL);
2058 D3DSTATE_TO_STR(WINED3D_RS_SRCBLEND);
2059 D3DSTATE_TO_STR(WINED3D_RS_DESTBLEND);
2060 D3DSTATE_TO_STR(WINED3D_RS_CULLMODE);
2061 D3DSTATE_TO_STR(WINED3D_RS_ZFUNC);
2062 D3DSTATE_TO_STR(WINED3D_RS_ALPHAREF);
2063 D3DSTATE_TO_STR(WINED3D_RS_ALPHAFUNC);
2064 D3DSTATE_TO_STR(WINED3D_RS_DITHERENABLE);
2065 D3DSTATE_TO_STR(WINED3D_RS_ALPHABLENDENABLE);
2066 D3DSTATE_TO_STR(WINED3D_RS_FOGENABLE);
2067 D3DSTATE_TO_STR(WINED3D_RS_SPECULARENABLE);
2068 D3DSTATE_TO_STR(WINED3D_RS_ZVISIBLE);
2069 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXEL);
2070 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXELX);
2071 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEDALPHA);
2072 D3DSTATE_TO_STR(WINED3D_RS_FOGCOLOR);
2073 D3DSTATE_TO_STR(WINED3D_RS_FOGTABLEMODE);
2074 D3DSTATE_TO_STR(WINED3D_RS_FOGSTART);
2075 D3DSTATE_TO_STR(WINED3D_RS_FOGEND);
2076 D3DSTATE_TO_STR(WINED3D_RS_FOGDENSITY);
2077 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEENABLE);
2078 D3DSTATE_TO_STR(WINED3D_RS_EDGEANTIALIAS);
2079 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYENABLE);
2080 D3DSTATE_TO_STR(WINED3D_RS_MIPMAPLODBIAS);
2081 D3DSTATE_TO_STR(WINED3D_RS_RANGEFOGENABLE);
2082 D3DSTATE_TO_STR(WINED3D_RS_ANISOTROPY);
2083 D3DSTATE_TO_STR(WINED3D_RS_FLUSHBATCH);
2084 D3DSTATE_TO_STR(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT);
2085 D3DSTATE_TO_STR(WINED3D_RS_STENCILENABLE);
2086 D3DSTATE_TO_STR(WINED3D_RS_STENCILFAIL);
2087 D3DSTATE_TO_STR(WINED3D_RS_STENCILZFAIL);
2088 D3DSTATE_TO_STR(WINED3D_RS_STENCILPASS);
2089 D3DSTATE_TO_STR(WINED3D_RS_STENCILFUNC);
2090 D3DSTATE_TO_STR(WINED3D_RS_STENCILREF);
2091 D3DSTATE_TO_STR(WINED3D_RS_STENCILMASK);
2092 D3DSTATE_TO_STR(WINED3D_RS_STENCILWRITEMASK);
2093 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREFACTOR);
2094 D3DSTATE_TO_STR(WINED3D_RS_WRAP0);
2095 D3DSTATE_TO_STR(WINED3D_RS_WRAP1);
2096 D3DSTATE_TO_STR(WINED3D_RS_WRAP2);
2097 D3DSTATE_TO_STR(WINED3D_RS_WRAP3);
2098 D3DSTATE_TO_STR(WINED3D_RS_WRAP4);
2099 D3DSTATE_TO_STR(WINED3D_RS_WRAP5);
2100 D3DSTATE_TO_STR(WINED3D_RS_WRAP6);
2101 D3DSTATE_TO_STR(WINED3D_RS_WRAP7);
2102 D3DSTATE_TO_STR(WINED3D_RS_CLIPPING);
2103 D3DSTATE_TO_STR(WINED3D_RS_LIGHTING);
2104 D3DSTATE_TO_STR(WINED3D_RS_EXTENTS);
2105 D3DSTATE_TO_STR(WINED3D_RS_AMBIENT);
2106 D3DSTATE_TO_STR(WINED3D_RS_FOGVERTEXMODE);
2107 D3DSTATE_TO_STR(WINED3D_RS_COLORVERTEX);
2108 D3DSTATE_TO_STR(WINED3D_RS_LOCALVIEWER);
2109 D3DSTATE_TO_STR(WINED3D_RS_NORMALIZENORMALS);
2110 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYBLENDENABLE);
2111 D3DSTATE_TO_STR(WINED3D_RS_DIFFUSEMATERIALSOURCE);
2112 D3DSTATE_TO_STR(WINED3D_RS_SPECULARMATERIALSOURCE);
2113 D3DSTATE_TO_STR(WINED3D_RS_AMBIENTMATERIALSOURCE);
2114 D3DSTATE_TO_STR(WINED3D_RS_EMISSIVEMATERIALSOURCE);
2115 D3DSTATE_TO_STR(WINED3D_RS_VERTEXBLEND);
2116 D3DSTATE_TO_STR(WINED3D_RS_CLIPPLANEENABLE);
2117 D3DSTATE_TO_STR(WINED3D_RS_SOFTWAREVERTEXPROCESSING);
2118 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE);
2119 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MIN);
2120 D3DSTATE_TO_STR(WINED3D_RS_POINTSPRITEENABLE);
2121 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALEENABLE);
2122 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_A);
2123 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_B);
2124 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_C);
2125 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEANTIALIAS);
2126 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEMASK);
2127 D3DSTATE_TO_STR(WINED3D_RS_PATCHEDGESTYLE);
2128 D3DSTATE_TO_STR(WINED3D_RS_PATCHSEGMENTS);
2129 D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN);
2130 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX);
2131 D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE);
2132 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
2133 D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR);
2134 D3DSTATE_TO_STR(WINED3D_RS_BLENDOP);
2135 D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE);
2136 D3DSTATE_TO_STR(WINED3D_RS_NORMALDEGREE);
2137 D3DSTATE_TO_STR(WINED3D_RS_SCISSORTESTENABLE);
2138 D3DSTATE_TO_STR(WINED3D_RS_SLOPESCALEDEPTHBIAS);
2139 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIASEDLINEENABLE);
2140 D3DSTATE_TO_STR(WINED3D_RS_MINTESSELLATIONLEVEL);
2141 D3DSTATE_TO_STR(WINED3D_RS_MAXTESSELLATIONLEVEL);
2142 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_X);
2143 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Y);
2144 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Z);
2145 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_W);
2146 D3DSTATE_TO_STR(WINED3D_RS_ENABLEADAPTIVETESSELLATION);
2147 D3DSTATE_TO_STR(WINED3D_RS_TWOSIDEDSTENCILMODE);
2148 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFAIL);
2149 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILZFAIL);
2150 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILPASS);
2151 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFUNC);
2152 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1);
2153 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2);
2154 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3);
2155 D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR);
2156 D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE);
2157 D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS);
2158 D3DSTATE_TO_STR(WINED3D_RS_WRAP8);
2159 D3DSTATE_TO_STR(WINED3D_RS_WRAP9);
2160 D3DSTATE_TO_STR(WINED3D_RS_WRAP10);
2161 D3DSTATE_TO_STR(WINED3D_RS_WRAP11);
2162 D3DSTATE_TO_STR(WINED3D_RS_WRAP12);
2163 D3DSTATE_TO_STR(WINED3D_RS_WRAP13);
2164 D3DSTATE_TO_STR(WINED3D_RS_WRAP14);
2165 D3DSTATE_TO_STR(WINED3D_RS_WRAP15);
2166 D3DSTATE_TO_STR(WINED3D_RS_SEPARATEALPHABLENDENABLE);
2167 D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
2168 D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
2169 D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
2170 #undef D3DSTATE_TO_STR
2171 default:
2172 FIXME("Unrecognized %u render state!\n", state);
2173 return "unrecognized";
2177 const char *debug_d3dsamplerstate(enum wined3d_sampler_state state)
2179 switch (state)
2181 #define D3DSTATE_TO_STR(u) case u: return #u
2182 D3DSTATE_TO_STR(WINED3D_SAMP_BORDER_COLOR);
2183 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_U);
2184 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_V);
2185 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_W);
2186 D3DSTATE_TO_STR(WINED3D_SAMP_MAG_FILTER);
2187 D3DSTATE_TO_STR(WINED3D_SAMP_MIN_FILTER);
2188 D3DSTATE_TO_STR(WINED3D_SAMP_MIP_FILTER);
2189 D3DSTATE_TO_STR(WINED3D_SAMP_MIPMAP_LOD_BIAS);
2190 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_MIP_LEVEL);
2191 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_ANISOTROPY);
2192 D3DSTATE_TO_STR(WINED3D_SAMP_SRGB_TEXTURE);
2193 D3DSTATE_TO_STR(WINED3D_SAMP_ELEMENT_INDEX);
2194 D3DSTATE_TO_STR(WINED3D_SAMP_DMAP_OFFSET);
2195 #undef D3DSTATE_TO_STR
2196 default:
2197 FIXME("Unrecognized %u sampler state!\n", state);
2198 return "unrecognized";
2202 const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type)
2204 switch (filter_type)
2206 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
2207 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_NONE);
2208 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_POINT);
2209 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_LINEAR);
2210 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_ANISOTROPIC);
2211 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_FLAT_CUBIC);
2212 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_CUBIC);
2213 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_PYRAMIDAL_QUAD);
2214 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_QUAD);
2215 #undef D3DTEXTUREFILTERTYPE_TO_STR
2216 default:
2217 FIXME("Unrecognied texture filter type 0x%08x.\n", filter_type);
2218 return "unrecognized";
2222 const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state)
2224 switch (state)
2226 #define D3DSTATE_TO_STR(u) case u: return #u
2227 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_OP);
2228 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG1);
2229 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG2);
2230 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_OP);
2231 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG1);
2232 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG2);
2233 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT00);
2234 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT01);
2235 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT10);
2236 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT11);
2237 D3DSTATE_TO_STR(WINED3D_TSS_TEXCOORD_INDEX);
2238 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LSCALE);
2239 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LOFFSET);
2240 D3DSTATE_TO_STR(WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS);
2241 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG0);
2242 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG0);
2243 D3DSTATE_TO_STR(WINED3D_TSS_RESULT_ARG);
2244 D3DSTATE_TO_STR(WINED3D_TSS_CONSTANT);
2245 #undef D3DSTATE_TO_STR
2246 default:
2247 FIXME("Unrecognized %u texture state!\n", state);
2248 return "unrecognized";
2252 const char *debug_d3dtop(enum wined3d_texture_op d3dtop)
2254 switch (d3dtop)
2256 #define D3DTOP_TO_STR(u) case u: return #u
2257 D3DTOP_TO_STR(WINED3D_TOP_DISABLE);
2258 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG1);
2259 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG2);
2260 D3DTOP_TO_STR(WINED3D_TOP_MODULATE);
2261 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_2X);
2262 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_4X);
2263 D3DTOP_TO_STR(WINED3D_TOP_ADD);
2264 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED);
2265 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED_2X);
2266 D3DTOP_TO_STR(WINED3D_TOP_SUBTRACT);
2267 D3DTOP_TO_STR(WINED3D_TOP_ADD_SMOOTH);
2268 D3DTOP_TO_STR(WINED3D_TOP_BLEND_DIFFUSE_ALPHA);
2269 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA);
2270 D3DTOP_TO_STR(WINED3D_TOP_BLEND_FACTOR_ALPHA);
2271 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM);
2272 D3DTOP_TO_STR(WINED3D_TOP_BLEND_CURRENT_ALPHA);
2273 D3DTOP_TO_STR(WINED3D_TOP_PREMODULATE);
2274 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR);
2275 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA);
2276 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR);
2277 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA);
2278 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP);
2279 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP_LUMINANCE);
2280 D3DTOP_TO_STR(WINED3D_TOP_DOTPRODUCT3);
2281 D3DTOP_TO_STR(WINED3D_TOP_MULTIPLY_ADD);
2282 D3DTOP_TO_STR(WINED3D_TOP_LERP);
2283 #undef D3DTOP_TO_STR
2284 default:
2285 FIXME("Unrecognized texture op %#x.\n", d3dtop);
2286 return "unrecognized";
2290 const char *debug_d3dtstype(enum wined3d_transform_state tstype)
2292 switch (tstype)
2294 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2295 TSTYPE_TO_STR(WINED3D_TS_VIEW);
2296 TSTYPE_TO_STR(WINED3D_TS_PROJECTION);
2297 TSTYPE_TO_STR(WINED3D_TS_TEXTURE0);
2298 TSTYPE_TO_STR(WINED3D_TS_TEXTURE1);
2299 TSTYPE_TO_STR(WINED3D_TS_TEXTURE2);
2300 TSTYPE_TO_STR(WINED3D_TS_TEXTURE3);
2301 TSTYPE_TO_STR(WINED3D_TS_TEXTURE4);
2302 TSTYPE_TO_STR(WINED3D_TS_TEXTURE5);
2303 TSTYPE_TO_STR(WINED3D_TS_TEXTURE6);
2304 TSTYPE_TO_STR(WINED3D_TS_TEXTURE7);
2305 TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(0));
2306 #undef TSTYPE_TO_STR
2307 default:
2308 if (tstype > 256 && tstype < 512)
2310 FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype);
2311 return ("WINED3D_TS_WORLD_MATRIX > 0");
2313 FIXME("Unrecognized transform state %#x.\n", tstype);
2314 return "unrecognized";
2318 const char *debug_d3dstate(DWORD state)
2320 if (STATE_IS_RENDER(state))
2321 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
2322 if (STATE_IS_TEXTURESTAGE(state))
2324 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2325 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
2326 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2327 texture_stage, debug_d3dtexturestate(texture_state));
2329 if (STATE_IS_SAMPLER(state))
2330 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
2331 if (STATE_IS_PIXELSHADER(state))
2332 return "STATE_PIXELSHADER";
2333 if (STATE_IS_TRANSFORM(state))
2334 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
2335 if (STATE_IS_STREAMSRC(state))
2336 return "STATE_STREAMSRC";
2337 if (STATE_IS_INDEXBUFFER(state))
2338 return "STATE_INDEXBUFFER";
2339 if (STATE_IS_VDECL(state))
2340 return "STATE_VDECL";
2341 if (STATE_IS_VSHADER(state))
2342 return "STATE_VSHADER";
2343 if (STATE_IS_VIEWPORT(state))
2344 return "STATE_VIEWPORT";
2345 if (STATE_IS_VERTEXSHADERCONSTANT(state))
2346 return "STATE_VERTEXSHADERCONSTANT";
2347 if (STATE_IS_PIXELSHADERCONSTANT(state))
2348 return "STATE_PIXELSHADERCONSTANT";
2349 if (STATE_IS_ACTIVELIGHT(state))
2350 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
2351 if (STATE_IS_SCISSORRECT(state))
2352 return "STATE_SCISSORRECT";
2353 if (STATE_IS_CLIPPLANE(state))
2354 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
2355 if (STATE_IS_MATERIAL(state))
2356 return "STATE_MATERIAL";
2357 if (STATE_IS_FRONTFACE(state))
2358 return "STATE_FRONTFACE";
2359 if (STATE_IS_POINTSPRITECOORDORIGIN(state))
2360 return "STATE_POINTSPRITECOORDORIGIN";
2361 if (STATE_IS_BASEVERTEXINDEX(state))
2362 return "STATE_BASEVERTEXINDEX";
2363 if (STATE_IS_FRAMEBUFFER(state))
2364 return "STATE_FRAMEBUFFER";
2366 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
2369 const char *debug_d3dpool(enum wined3d_pool pool)
2371 switch (pool)
2373 #define POOL_TO_STR(p) case p: return #p
2374 POOL_TO_STR(WINED3D_POOL_DEFAULT);
2375 POOL_TO_STR(WINED3D_POOL_MANAGED);
2376 POOL_TO_STR(WINED3D_POOL_SYSTEM_MEM);
2377 POOL_TO_STR(WINED3D_POOL_SCRATCH);
2378 #undef POOL_TO_STR
2379 default:
2380 FIXME("Unrecognized pool %#x.\n", pool);
2381 return "unrecognized";
2385 const char *debug_fbostatus(GLenum status) {
2386 switch(status) {
2387 #define FBOSTATUS_TO_STR(u) case u: return #u
2388 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
2389 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2390 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
2391 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
2392 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
2393 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
2394 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
2395 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
2396 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
2397 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
2398 #undef FBOSTATUS_TO_STR
2399 default:
2400 FIXME("Unrecognied FBO status 0x%08x\n", status);
2401 return "unrecognized";
2405 const char *debug_glerror(GLenum error) {
2406 switch(error) {
2407 #define GLERROR_TO_STR(u) case u: return #u
2408 GLERROR_TO_STR(GL_NO_ERROR);
2409 GLERROR_TO_STR(GL_INVALID_ENUM);
2410 GLERROR_TO_STR(GL_INVALID_VALUE);
2411 GLERROR_TO_STR(GL_INVALID_OPERATION);
2412 GLERROR_TO_STR(GL_STACK_OVERFLOW);
2413 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
2414 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
2415 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
2416 #undef GLERROR_TO_STR
2417 default:
2418 FIXME("Unrecognied GL error 0x%08x\n", error);
2419 return "unrecognized";
2423 const char *debug_d3dbasis(enum wined3d_basis_type basis)
2425 switch (basis)
2427 case WINED3D_BASIS_BEZIER: return "WINED3D_BASIS_BEZIER";
2428 case WINED3D_BASIS_BSPLINE: return "WINED3D_BASIS_BSPLINE";
2429 case WINED3D_BASIS_INTERPOLATE: return "WINED3D_BASIS_INTERPOLATE";
2430 default: return "unrecognized";
2434 const char *debug_d3ddegree(enum wined3d_degree_type degree)
2436 switch (degree)
2438 case WINED3D_DEGREE_LINEAR: return "WINED3D_DEGREE_LINEAR";
2439 case WINED3D_DEGREE_QUADRATIC: return "WINED3D_DEGREE_QUADRATIC";
2440 case WINED3D_DEGREE_CUBIC: return "WINED3D_DEGREE_CUBIC";
2441 case WINED3D_DEGREE_QUINTIC: return "WINED3D_DEGREE_QUINTIC";
2442 default: return "unrecognized";
2446 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
2448 switch(source)
2450 #define WINED3D_TO_STR(x) case x: return #x
2451 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
2452 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
2453 WINED3D_TO_STR(CHANNEL_SOURCE_X);
2454 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
2455 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
2456 WINED3D_TO_STR(CHANNEL_SOURCE_W);
2457 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
2458 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
2459 #undef WINED3D_TO_STR
2460 default:
2461 FIXME("Unrecognized fixup_channel_source %#x\n", source);
2462 return "unrecognized";
2466 static const char *debug_complex_fixup(enum complex_fixup fixup)
2468 switch(fixup)
2470 #define WINED3D_TO_STR(x) case x: return #x
2471 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
2472 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
2473 WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
2474 WINED3D_TO_STR(COMPLEX_FIXUP_P8);
2475 #undef WINED3D_TO_STR
2476 default:
2477 FIXME("Unrecognized complex fixup %#x\n", fixup);
2478 return "unrecognized";
2482 void dump_color_fixup_desc(struct color_fixup_desc fixup)
2484 if (is_complex_fixup(fixup))
2486 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
2487 return;
2490 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
2491 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
2492 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
2493 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
2496 const char *debug_surflocation(DWORD flag) {
2497 char buf[128];
2499 buf[0] = 0;
2500 if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM"); /* 17 */
2501 if (flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE"); /* 19 */
2502 if (flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE"); /* 18 */
2503 if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX"); /* 18 */
2504 if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE"); /* 25 */
2505 if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED"); /* 22 */
2506 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
2509 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
2510 enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2512 if (op == WINED3D_TOP_DISABLE)
2513 return FALSE;
2514 if (state->textures[stage])
2515 return FALSE;
2517 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2518 && op != WINED3D_TOP_SELECT_ARG2)
2519 return TRUE;
2520 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2521 && op != WINED3D_TOP_SELECT_ARG1)
2522 return TRUE;
2523 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
2524 && (op == WINED3D_TOP_MULTIPLY_ADD || op == WINED3D_TOP_LERP))
2525 return TRUE;
2527 return FALSE;
2530 /* Setup this textures matrix according to the texture flags*/
2531 /* GL locking is done by the caller (state handler) */
2532 void set_texture_matrix(const struct wined3d_gl_info *gl_info, const float *smat, DWORD flags,
2533 BOOL calculatedCoords, BOOL transformed, enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
2535 float mat[16];
2537 gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
2538 checkGLcall("glMatrixMode(GL_TEXTURE)");
2540 if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed)
2542 gl_info->gl_ops.gl.p_glLoadIdentity();
2543 checkGLcall("glLoadIdentity()");
2544 return;
2547 if (flags == (WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED))
2549 ERR("Invalid texture transform flags: WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED.\n");
2550 return;
2553 memcpy(mat, smat, 16 * sizeof(float));
2555 if (flags & WINED3D_TTFF_PROJECTED)
2557 if (!ffp_proj_control)
2559 switch (flags & ~WINED3D_TTFF_PROJECTED)
2561 case WINED3D_TTFF_COUNT2:
2562 mat[ 3] = mat[ 1];
2563 mat[ 7] = mat[ 5];
2564 mat[11] = mat[ 9];
2565 mat[15] = mat[13];
2566 mat[ 1] = mat[ 5] = mat[ 9] = mat[13] = 0.0f;
2567 break;
2568 case WINED3D_TTFF_COUNT3:
2569 mat[ 3] = mat[ 2];
2570 mat[ 7] = mat[ 6];
2571 mat[11] = mat[10];
2572 mat[15] = mat[14];
2573 mat[ 2] = mat[ 6] = mat[10] = mat[14] = 0.0f;
2574 break;
2577 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2578 if(!calculatedCoords) {
2579 switch(vtx_fmt)
2581 case WINED3DFMT_R32_FLOAT:
2582 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2583 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2584 * the input value to the transformation will be 0, so the matrix value is irrelevant
2586 mat[12] = mat[4];
2587 mat[13] = mat[5];
2588 mat[14] = mat[6];
2589 mat[15] = mat[7];
2590 break;
2591 case WINED3DFMT_R32G32_FLOAT:
2592 /* See above, just 3rd and 4th coord
2594 mat[12] = mat[8];
2595 mat[13] = mat[9];
2596 mat[14] = mat[10];
2597 mat[15] = mat[11];
2598 break;
2599 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
2600 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
2602 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2603 * into a bad place. The division elimination below will apply to make sure the
2604 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2606 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
2607 break;
2608 default:
2609 FIXME("Unexpected fixed function texture coord input\n");
2612 if (!ffp_proj_control)
2614 switch (flags & ~WINED3D_TTFF_PROJECTED)
2616 /* case WINED3D_TTFF_COUNT1: Won't ever get here. */
2617 case WINED3D_TTFF_COUNT2:
2618 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2619 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2620 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2621 * the 4th coord evaluates to 1.0 to eliminate that.
2623 * If the fixed function pipeline is used, the 4th value remains unused,
2624 * so there is no danger in doing this. With vertex shaders we have a
2625 * problem. Should an app hit that problem, the code here would have to
2626 * check for pixel shaders, and the shader has to undo the default gl divide.
2628 * A more serious problem occurs if the app passes 4 coordinates in, and the
2629 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2630 * or a replacement shader. */
2631 default:
2632 mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2637 gl_info->gl_ops.gl.p_glLoadMatrixf(mat);
2638 checkGLcall("glLoadMatrixf(mat)");
2641 /* This small helper function is used to convert a bitmask into the number of masked bits */
2642 unsigned int count_bits(unsigned int mask)
2644 unsigned int count;
2645 for (count = 0; mask; ++count)
2647 mask &= mask - 1;
2649 return count;
2652 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2653 * The later function requires individual color components. */
2654 BOOL getColorBits(const struct wined3d_format *format,
2655 BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
2657 TRACE("format %s.\n", debug_d3dformat(format->id));
2659 switch (format->id)
2661 case WINED3DFMT_B10G10R10A2_UNORM:
2662 case WINED3DFMT_R10G10B10A2_UNORM:
2663 case WINED3DFMT_B8G8R8X8_UNORM:
2664 case WINED3DFMT_B8G8R8_UNORM:
2665 case WINED3DFMT_B8G8R8A8_UNORM:
2666 case WINED3DFMT_R8G8B8A8_UNORM:
2667 case WINED3DFMT_B5G5R5X1_UNORM:
2668 case WINED3DFMT_B5G5R5A1_UNORM:
2669 case WINED3DFMT_B5G6R5_UNORM:
2670 case WINED3DFMT_B4G4R4X4_UNORM:
2671 case WINED3DFMT_B4G4R4A4_UNORM:
2672 case WINED3DFMT_B2G3R3_UNORM:
2673 case WINED3DFMT_P8_UINT_A8_UNORM:
2674 case WINED3DFMT_P8_UINT:
2675 break;
2676 default:
2677 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
2678 return FALSE;
2681 *redSize = count_bits(format->red_mask);
2682 *greenSize = count_bits(format->green_mask);
2683 *blueSize = count_bits(format->blue_mask);
2684 *alphaSize = count_bits(format->alpha_mask);
2685 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2687 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
2688 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
2689 return TRUE;
2692 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2693 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
2695 TRACE("format %s.\n", debug_d3dformat(format->id));
2697 switch (format->id)
2699 case WINED3DFMT_D16_LOCKABLE:
2700 case WINED3DFMT_D16_UNORM:
2701 case WINED3DFMT_S1_UINT_D15_UNORM:
2702 case WINED3DFMT_X8D24_UNORM:
2703 case WINED3DFMT_S4X4_UINT_D24_UNORM:
2704 case WINED3DFMT_D24_UNORM_S8_UINT:
2705 case WINED3DFMT_S8_UINT_D24_FLOAT:
2706 case WINED3DFMT_D32_UNORM:
2707 case WINED3DFMT_D32_FLOAT:
2708 case WINED3DFMT_INTZ:
2709 break;
2710 default:
2711 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
2712 return FALSE;
2715 *depthSize = format->depth_size;
2716 *stencilSize = format->stencil_size;
2718 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
2719 *depthSize, *stencilSize, debug_d3dformat(format->id));
2720 return TRUE;
2723 /* Note: It's the caller's responsibility to ensure values can be expressed
2724 * in the requested format. UNORM formats for example can only express values
2725 * in the range 0.0f -> 1.0f. */
2726 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color)
2728 static const struct
2730 enum wined3d_format_id format_id;
2731 float r_mul;
2732 float g_mul;
2733 float b_mul;
2734 float a_mul;
2735 BYTE r_shift;
2736 BYTE g_shift;
2737 BYTE b_shift;
2738 BYTE a_shift;
2740 conv[] =
2742 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2743 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2744 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
2745 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
2746 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2747 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
2748 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
2749 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2750 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
2751 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
2752 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2753 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
2754 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
2755 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
2757 const struct wined3d_format *format = surface->resource.format;
2758 unsigned int i;
2760 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
2761 color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
2763 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
2765 DWORD ret;
2767 if (format->id != conv[i].format_id) continue;
2769 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
2770 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
2771 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
2772 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
2774 TRACE("Returning 0x%08x.\n", ret);
2776 return ret;
2779 if (format->id == WINED3DFMT_P8_UINT)
2781 PALETTEENTRY *e;
2782 BYTE r, g, b, a;
2784 if (!surface->palette)
2786 WARN("Surface doesn't have a palette, returning 0.\n");
2787 return 0;
2790 r = (BYTE)((color->r * 255.0f) + 0.5f);
2791 g = (BYTE)((color->g * 255.0f) + 0.5f);
2792 b = (BYTE)((color->b * 255.0f) + 0.5f);
2793 a = (BYTE)((color->a * 255.0f) + 0.5f);
2795 e = &surface->palette->palents[a];
2796 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2797 return a;
2799 WARN("Alpha didn't match index, searching full palette.\n");
2801 for (i = 0; i < 256; ++i)
2803 e = &surface->palette->palents[i];
2804 if (e->peRed == r && e->peGreen == g && e->peBlue == b)
2805 return i;
2808 FIXME("Unable to convert color to palette index.\n");
2810 return 0;
2813 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
2815 return 0;
2818 /* DirectDraw stuff */
2819 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
2821 switch (depth)
2823 case 8: return WINED3DFMT_P8_UINT;
2824 case 15: return WINED3DFMT_B5G5R5X1_UNORM;
2825 case 16: return WINED3DFMT_B5G6R5_UNORM;
2826 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2827 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2828 default: return WINED3DFMT_UNKNOWN;
2832 void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
2833 const struct wined3d_matrix *src2)
2835 struct wined3d_matrix temp;
2837 /* Now do the multiplication 'by hand'.
2838 I know that all this could be optimised, but this will be done later :-) */
2839 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);
2840 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);
2841 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);
2842 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);
2844 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);
2845 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);
2846 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);
2847 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);
2849 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);
2850 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);
2851 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);
2852 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);
2854 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);
2855 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);
2856 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);
2857 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);
2859 /* And copy the new matrix in the good storage.. */
2860 memcpy(dest, &temp, 16 * sizeof(float));
2863 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2864 DWORD size = 0;
2865 int i;
2866 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2868 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2869 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2870 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2871 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2872 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2873 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2874 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2875 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2876 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2877 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2878 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2879 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2880 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
2881 default: ERR("Unexpected position mask\n");
2883 for (i = 0; i < numTextures; i++) {
2884 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2887 return size;
2890 void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_state *state,
2891 struct ffp_frag_settings *settings, BOOL ignore_textype)
2893 #define ARG1 0x01
2894 #define ARG2 0x02
2895 #define ARG0 0x04
2896 static const unsigned char args[WINED3D_TOP_LERP + 1] =
2898 /* undefined */ 0,
2899 /* D3DTOP_DISABLE */ 0,
2900 /* D3DTOP_SELECTARG1 */ ARG1,
2901 /* D3DTOP_SELECTARG2 */ ARG2,
2902 /* D3DTOP_MODULATE */ ARG1 | ARG2,
2903 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
2904 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
2905 /* D3DTOP_ADD */ ARG1 | ARG2,
2906 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
2907 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
2908 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
2909 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
2910 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
2911 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
2912 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
2913 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
2914 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
2915 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
2916 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
2917 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
2918 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
2919 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
2920 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
2921 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
2922 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
2923 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
2924 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
2926 unsigned int i;
2927 DWORD ttff;
2928 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
2929 const struct wined3d_surface *rt = state->fb->render_targets[0];
2930 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2932 for (i = 0; i < gl_info->limits.texture_stages; ++i)
2934 const struct wined3d_texture *texture;
2936 settings->op[i].padding = 0;
2937 if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
2939 settings->op[i].cop = WINED3D_TOP_DISABLE;
2940 settings->op[i].aop = WINED3D_TOP_DISABLE;
2941 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
2942 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
2943 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2944 settings->op[i].dst = resultreg;
2945 settings->op[i].tex_type = tex_1d;
2946 settings->op[i].projected = proj_none;
2947 i++;
2948 break;
2951 if ((texture = state->textures[i]))
2953 settings->op[i].color_fixup = texture->resource.format->color_fixup;
2954 if (ignore_textype)
2956 settings->op[i].tex_type = tex_1d;
2958 else
2960 switch (texture->target)
2962 case GL_TEXTURE_1D:
2963 settings->op[i].tex_type = tex_1d;
2964 break;
2965 case GL_TEXTURE_2D:
2966 settings->op[i].tex_type = tex_2d;
2967 break;
2968 case GL_TEXTURE_3D:
2969 settings->op[i].tex_type = tex_3d;
2970 break;
2971 case GL_TEXTURE_CUBE_MAP_ARB:
2972 settings->op[i].tex_type = tex_cube;
2973 break;
2974 case GL_TEXTURE_RECTANGLE_ARB:
2975 settings->op[i].tex_type = tex_rect;
2976 break;
2979 } else {
2980 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
2981 settings->op[i].tex_type = tex_1d;
2984 cop = state->texture_states[i][WINED3D_TSS_COLOR_OP];
2985 aop = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
2987 carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG1] : ARG_UNUSED;
2988 carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG2] : ARG_UNUSED;
2989 carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG0] : ARG_UNUSED;
2991 if (is_invalid_op(state, i, cop, carg1, carg2, carg0))
2993 carg0 = ARG_UNUSED;
2994 carg2 = ARG_UNUSED;
2995 carg1 = WINED3DTA_CURRENT;
2996 cop = WINED3D_TOP_SELECT_ARG1;
2999 if (cop == WINED3D_TOP_DOTPRODUCT3)
3001 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
3002 * the color result to the alpha component of the destination
3004 aop = cop;
3005 aarg1 = carg1;
3006 aarg2 = carg2;
3007 aarg0 = carg0;
3009 else
3011 aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] : ARG_UNUSED;
3012 aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] : ARG_UNUSED;
3013 aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] : ARG_UNUSED;
3016 if (!i && state->textures[0] && state->render_states[WINED3D_RS_COLORKEYENABLE])
3018 GLenum texture_dimensions;
3020 texture = state->textures[0];
3021 texture_dimensions = texture->target;
3023 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3025 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3027 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
3029 if (aop == WINED3D_TOP_DISABLE)
3031 aarg1 = WINED3DTA_TEXTURE;
3032 aop = WINED3D_TOP_SELECT_ARG1;
3034 else if (aop == WINED3D_TOP_SELECT_ARG1 && aarg1 != WINED3DTA_TEXTURE)
3036 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3038 aarg2 = WINED3DTA_TEXTURE;
3039 aop = WINED3D_TOP_MODULATE;
3041 else aarg1 = WINED3DTA_TEXTURE;
3043 else if (aop == WINED3D_TOP_SELECT_ARG2 && aarg2 != WINED3DTA_TEXTURE)
3045 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3047 aarg1 = WINED3DTA_TEXTURE;
3048 aop = WINED3D_TOP_MODULATE;
3050 else aarg2 = WINED3DTA_TEXTURE;
3056 if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0))
3058 aarg0 = ARG_UNUSED;
3059 aarg2 = ARG_UNUSED;
3060 aarg1 = WINED3DTA_CURRENT;
3061 aop = WINED3D_TOP_SELECT_ARG1;
3064 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
3065 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
3067 ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
3068 if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3))
3069 settings->op[i].projected = proj_count3;
3070 else if (ttff & WINED3D_TTFF_PROJECTED)
3071 settings->op[i].projected = proj_count4;
3072 else
3073 settings->op[i].projected = proj_none;
3075 else
3077 settings->op[i].projected = proj_none;
3080 settings->op[i].cop = cop;
3081 settings->op[i].aop = aop;
3082 settings->op[i].carg0 = carg0;
3083 settings->op[i].carg1 = carg1;
3084 settings->op[i].carg2 = carg2;
3085 settings->op[i].aarg0 = aarg0;
3086 settings->op[i].aarg1 = aarg1;
3087 settings->op[i].aarg2 = aarg2;
3089 if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP)
3090 settings->op[i].dst = tempreg;
3091 else
3092 settings->op[i].dst = resultreg;
3095 /* Clear unsupported stages */
3096 for(; i < MAX_TEXTURES; i++) {
3097 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
3100 if (!state->render_states[WINED3D_RS_FOGENABLE])
3102 settings->fog = FOG_OFF;
3104 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
3106 if (use_vs(state) || state->vertex_declaration->position_transformed)
3108 settings->fog = FOG_LINEAR;
3110 else
3112 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
3114 case WINED3D_FOG_NONE:
3115 case WINED3D_FOG_LINEAR:
3116 settings->fog = FOG_LINEAR;
3117 break;
3118 case WINED3D_FOG_EXP:
3119 settings->fog = FOG_EXP;
3120 break;
3121 case WINED3D_FOG_EXP2:
3122 settings->fog = FOG_EXP2;
3123 break;
3127 else
3129 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
3131 case WINED3D_FOG_LINEAR:
3132 settings->fog = FOG_LINEAR;
3133 break;
3134 case WINED3D_FOG_EXP:
3135 settings->fog = FOG_EXP;
3136 break;
3137 case WINED3D_FOG_EXP2:
3138 settings->fog = FOG_EXP2;
3139 break;
3142 if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB]
3143 && state->render_states[WINED3D_RS_SRGBWRITEENABLE]
3144 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
3146 settings->sRGB_write = 1;
3147 } else {
3148 settings->sRGB_write = 0;
3150 if (device->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
3151 || !state->render_states[WINED3D_RS_CLIPPLANEENABLE])
3153 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
3154 * the fixed function vertex pipeline is used(which always supports clipplanes), or
3155 * if no clipplane is enabled
3157 settings->emul_clipplanes = 0;
3158 } else {
3159 settings->emul_clipplanes = 1;
3163 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
3164 const struct ffp_frag_settings *settings)
3166 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
3167 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
3170 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
3172 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
3173 * whereas desc points to an extended structure with implementation specific parts. */
3174 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
3176 ERR("Failed to insert ffp frag shader.\n");
3180 /* Activates the texture dimension according to the bound D3D texture.
3181 * Does not care for the colorop or correct gl texture unit(when using nvrc)
3182 * Requires the caller to activate the correct unit before
3184 /* GL locking is done by the caller (state handler) */
3185 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
3187 if (texture)
3189 switch (texture->target)
3191 case GL_TEXTURE_2D:
3192 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3193 checkGLcall("glDisable(GL_TEXTURE_3D)");
3194 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3196 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3197 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3199 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3201 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3202 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3204 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3205 checkGLcall("glEnable(GL_TEXTURE_2D)");
3206 break;
3207 case GL_TEXTURE_RECTANGLE_ARB:
3208 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3209 checkGLcall("glDisable(GL_TEXTURE_2D)");
3210 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3211 checkGLcall("glDisable(GL_TEXTURE_3D)");
3212 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3214 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3215 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3217 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_RECTANGLE_ARB);
3218 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3219 break;
3220 case GL_TEXTURE_3D:
3221 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3223 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3224 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3226 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3228 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3229 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3231 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3232 checkGLcall("glDisable(GL_TEXTURE_2D)");
3233 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D);
3234 checkGLcall("glEnable(GL_TEXTURE_3D)");
3235 break;
3236 case GL_TEXTURE_CUBE_MAP_ARB:
3237 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3238 checkGLcall("glDisable(GL_TEXTURE_2D)");
3239 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3240 checkGLcall("glDisable(GL_TEXTURE_3D)");
3241 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3243 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3244 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3246 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3247 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3248 break;
3251 else
3253 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
3254 checkGLcall("glEnable(GL_TEXTURE_2D)");
3255 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3256 checkGLcall("glDisable(GL_TEXTURE_3D)");
3257 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3259 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3260 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3262 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3264 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3265 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3267 /* Binding textures is done by samplers. A dummy texture will be bound */
3271 /* GL locking is done by the caller (state handler) */
3272 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3274 DWORD sampler = state_id - STATE_SAMPLER(0);
3275 DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
3277 /* No need to enable / disable anything here for unused samplers. The
3278 * tex_colorop handler takes care. Also no action is needed with pixel
3279 * shaders, or if tex_colorop will take care of this business. */
3280 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
3281 return;
3282 if (sampler >= state->lowest_disabled_stage)
3283 return;
3284 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)))
3285 return;
3287 texture_activate_dimensions(state->textures[sampler], context->gl_info);
3290 void *wined3d_rb_alloc(size_t size)
3292 return HeapAlloc(GetProcessHeap(), 0, size);
3295 void *wined3d_rb_realloc(void *ptr, size_t size)
3297 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
3300 void wined3d_rb_free(void *ptr)
3302 HeapFree(GetProcessHeap(), 0, ptr);
3305 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
3307 const struct ffp_frag_settings *ka = key;
3308 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
3310 return memcmp(ka, kb, sizeof(*ka));
3313 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
3315 wined3d_rb_alloc,
3316 wined3d_rb_realloc,
3317 wined3d_rb_free,
3318 ffp_frag_program_key_compare,
3321 UINT wined3d_log2i(UINT32 x)
3323 static const UINT l[] =
3325 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3326 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3327 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3328 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3329 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3330 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3331 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3332 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3333 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3334 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3335 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3336 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3337 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3338 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3339 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3340 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3342 UINT32 i;
3344 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
3347 /* Set the shader type for this device, depending on the given capabilities
3348 * and the user preferences in wined3d_settings. */
3349 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
3351 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
3353 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
3354 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
3356 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3357 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3358 * shaders only on this card. */
3359 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
3360 else *vs_selected = SHADER_GLSL;
3362 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
3363 else *vs_selected = SHADER_NONE;
3365 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
3366 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
3367 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
3368 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
3369 else *ps_selected = SHADER_NONE;
3372 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
3373 const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
3374 const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
3376 static const struct blit_shader * const blitters[] =
3378 &arbfp_blit,
3379 &ffp_blit,
3380 &cpu_blit,
3382 unsigned int i;
3384 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
3386 if (blitters[i]->blit_supported(gl_info, blit_op,
3387 src_rect, src_usage, src_pool, src_format,
3388 dst_rect, dst_usage, dst_pool, dst_format))
3389 return blitters[i];
3392 return NULL;
3395 void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
3397 const struct wined3d_viewport *vp = &state->viewport;
3399 SetRect(rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
3401 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
3402 IntersectRect(rect, rect, &state->scissor_rect);