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 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
28 #include "wined3d_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
32 struct StaticPixelFormatDesc
35 DWORD alphaMask
, redMask
, greenMask
, blueMask
;
37 short depthSize
, stencilSize
;
40 /*****************************************************************************
43 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
44 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
45 * high masks do not fit into the 32 bit values needed for ddraw. It is only
46 * used for ddraw mostly, and to figure out if the format has alpha at all, so
47 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
48 * formats are not usable in 2D rendering because ddraw doesn't support them.
50 static const struct StaticPixelFormatDesc formats
[] =
52 /* WINED3DFORMAT alphamask redmask greenmask bluemask bpp depth stencil */
53 {WINED3DFMT_UNKNOWN
, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
55 {WINED3DFMT_UYVY
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
56 {WINED3DFMT_YUY2
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
57 {WINED3DFMT_YV12
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
58 {WINED3DFMT_DXT1
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
59 {WINED3DFMT_DXT2
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
60 {WINED3DFMT_DXT3
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
61 {WINED3DFMT_DXT4
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
62 {WINED3DFMT_DXT5
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
63 {WINED3DFMT_MULTI2_ARGB8
, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
64 {WINED3DFMT_G8R8_G8B8
, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
65 {WINED3DFMT_R8G8_B8G8
, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0},
67 {WINED3DFMT_R32_FLOAT
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
68 {WINED3DFMT_R32G32_FLOAT
, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
69 {WINED3DFMT_R32G32B32_FLOAT
, 0x0, 0x0, 0x0, 0x0, 12, 0, 0},
70 {WINED3DFMT_R32G32B32A32_FLOAT
, 0x1, 0x0, 0x0, 0x0, 16, 0, 0},
72 {WINED3DFMT_R8G8_SNORM_Cx
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
74 {WINED3DFMT_R16_FLOAT
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
75 {WINED3DFMT_R16G16_FLOAT
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
76 {WINED3DFMT_R16G16_SINT
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
77 {WINED3DFMT_R16G16B16A16_FLOAT
, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
78 {WINED3DFMT_R16G16B16A16_SINT
, 0x1, 0x0, 0x0, 0x0, 8, 0, 0},
79 /* Palettized formats */
80 {WINED3DFMT_P8_UINT_A8_UNORM
, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
81 {WINED3DFMT_P8_UINT
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
82 /* Standard ARGB formats. */
83 {WINED3DFMT_B8G8R8_UNORM
, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0},
84 {WINED3DFMT_B8G8R8A8_UNORM
, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
85 {WINED3DFMT_B8G8R8X8_UNORM
, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0},
86 {WINED3DFMT_B5G6R5_UNORM
, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0},
87 {WINED3DFMT_B5G5R5X1_UNORM
, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
88 {WINED3DFMT_B5G5R5A1_UNORM
, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0},
89 {WINED3DFMT_B4G4R4A4_UNORM
, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
90 {WINED3DFMT_B2G3R3_UNORM
, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0},
91 {WINED3DFMT_A8_UNORM
, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0},
92 {WINED3DFMT_B2G3R3A8_UNORM
, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0},
93 {WINED3DFMT_B4G4R4X4_UNORM
, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0},
94 {WINED3DFMT_R10G10B10A2_UNORM
, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
95 {WINED3DFMT_R10G10B10A2_UINT
, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
96 {WINED3DFMT_R10G10B10A2_SNORM
, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0},
97 {WINED3DFMT_R8G8B8A8_UNORM
, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
98 {WINED3DFMT_R8G8B8A8_UINT
, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
99 {WINED3DFMT_R8G8B8X8_UNORM
, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0},
100 {WINED3DFMT_R16G16_UNORM
, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0},
101 {WINED3DFMT_B10G10R10A2_UNORM
, 0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0},
102 {WINED3DFMT_R16G16B16A16_UNORM
, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0},
104 {WINED3DFMT_L8_UNORM
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
105 {WINED3DFMT_L8A8_UNORM
, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0},
106 {WINED3DFMT_L4A4_UNORM
, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0},
107 {WINED3DFMT_L16_UNORM
, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
108 /* Bump mapping stuff */
109 {WINED3DFMT_R8G8_SNORM
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
110 {WINED3DFMT_R5G5_SNORM_L6_UNORM
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
111 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
112 {WINED3DFMT_R8G8B8A8_SNORM
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
113 {WINED3DFMT_R16G16_SNORM
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
114 {WINED3DFMT_R10G11B11_SNORM
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
115 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM
, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0},
116 /* Depth stencil formats */
117 {WINED3DFMT_D16_LOCKABLE
, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
118 {WINED3DFMT_D32_UNORM
, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
119 {WINED3DFMT_S1_UINT_D15_UNORM
, 0x0, 0x0, 0x0, 0x0, 2, 15, 1},
120 {WINED3DFMT_D24_UNORM_S8_UINT
, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
121 {WINED3DFMT_X8D24_UNORM
, 0x0, 0x0, 0x0, 0x0, 4, 24, 0},
122 {WINED3DFMT_S4X4_UINT_D24_UNORM
, 0x0, 0x0, 0x0, 0x0, 4, 24, 4},
123 {WINED3DFMT_D16_UNORM
, 0x0, 0x0, 0x0, 0x0, 2, 16, 0},
124 {WINED3DFMT_D32_FLOAT
, 0x0, 0x0, 0x0, 0x0, 4, 32, 0},
125 {WINED3DFMT_S8_UINT_D24_FLOAT
, 0x0, 0x0, 0x0, 0x0, 4, 24, 8},
126 {WINED3DFMT_VERTEXDATA
, 0x0, 0x0, 0x0, 0x0, 0, 0, 0},
127 {WINED3DFMT_R16_UINT
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
128 {WINED3DFMT_R32_UINT
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0},
129 {WINED3DFMT_R16G16B16A16_SNORM
, 0x0, 0x0, 0x0, 0x0, 8, 0, 0},
130 /* Vendor-specific formats */
131 {WINED3DFMT_ATI2N
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0},
132 {WINED3DFMT_NVHU
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
133 {WINED3DFMT_NVHS
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0},
136 struct wined3d_format_base_flags
138 WINED3DFORMAT format
;
142 static const struct wined3d_format_base_flags format_base_flags
[] =
144 {WINED3DFMT_UYVY
, WINED3DFMT_FLAG_FOURCC
},
145 {WINED3DFMT_YUY2
, WINED3DFMT_FLAG_FOURCC
},
146 {WINED3DFMT_YV12
, WINED3DFMT_FLAG_FOURCC
},
147 {WINED3DFMT_DXT1
, WINED3DFMT_FLAG_FOURCC
},
148 {WINED3DFMT_DXT2
, WINED3DFMT_FLAG_FOURCC
},
149 {WINED3DFMT_DXT3
, WINED3DFMT_FLAG_FOURCC
},
150 {WINED3DFMT_DXT4
, WINED3DFMT_FLAG_FOURCC
},
151 {WINED3DFMT_DXT5
, WINED3DFMT_FLAG_FOURCC
},
152 {WINED3DFMT_MULTI2_ARGB8
, WINED3DFMT_FLAG_FOURCC
},
153 {WINED3DFMT_G8R8_G8B8
, WINED3DFMT_FLAG_FOURCC
},
154 {WINED3DFMT_R8G8_B8G8
, WINED3DFMT_FLAG_FOURCC
},
155 {WINED3DFMT_P8_UINT
, WINED3DFMT_FLAG_GETDC
},
156 {WINED3DFMT_B8G8R8_UNORM
, WINED3DFMT_FLAG_GETDC
},
157 {WINED3DFMT_B8G8R8A8_UNORM
, WINED3DFMT_FLAG_GETDC
},
158 {WINED3DFMT_B8G8R8X8_UNORM
, WINED3DFMT_FLAG_GETDC
},
159 {WINED3DFMT_B5G6R5_UNORM
, WINED3DFMT_FLAG_GETDC
},
160 {WINED3DFMT_B5G5R5X1_UNORM
, WINED3DFMT_FLAG_GETDC
},
161 {WINED3DFMT_B5G5R5A1_UNORM
, WINED3DFMT_FLAG_GETDC
},
162 {WINED3DFMT_B4G4R4A4_UNORM
, WINED3DFMT_FLAG_GETDC
},
163 {WINED3DFMT_B4G4R4X4_UNORM
, WINED3DFMT_FLAG_GETDC
},
164 {WINED3DFMT_R8G8B8A8_UNORM
, WINED3DFMT_FLAG_GETDC
},
165 {WINED3DFMT_R8G8B8X8_UNORM
, WINED3DFMT_FLAG_GETDC
},
166 {WINED3DFMT_ATI2N
, WINED3DFMT_FLAG_FOURCC
},
167 {WINED3DFMT_NVHU
, WINED3DFMT_FLAG_FOURCC
},
168 {WINED3DFMT_NVHS
, WINED3DFMT_FLAG_FOURCC
},
169 {WINED3DFMT_R32_FLOAT
, WINED3DFMT_FLAG_FLOAT
},
170 {WINED3DFMT_R32G32_FLOAT
, WINED3DFMT_FLAG_FLOAT
},
171 {WINED3DFMT_R32G32B32_FLOAT
, WINED3DFMT_FLAG_FLOAT
},
172 {WINED3DFMT_R32G32B32A32_FLOAT
, WINED3DFMT_FLAG_FLOAT
},
173 {WINED3DFMT_R16_FLOAT
, WINED3DFMT_FLAG_FLOAT
},
174 {WINED3DFMT_R16G16_FLOAT
, WINED3DFMT_FLAG_FLOAT
},
175 {WINED3DFMT_R16G16B16A16_FLOAT
, WINED3DFMT_FLAG_FLOAT
},
176 {WINED3DFMT_D32_FLOAT
, WINED3DFMT_FLAG_FLOAT
},
177 {WINED3DFMT_S8_UINT_D24_FLOAT
, WINED3DFMT_FLAG_FLOAT
},
180 struct wined3d_format_compression_info
182 WINED3DFORMAT format
;
185 UINT block_byte_count
;
188 static const struct wined3d_format_compression_info format_compression_info
[] =
190 {WINED3DFMT_DXT1
, 4, 4, 8},
191 {WINED3DFMT_DXT2
, 4, 4, 16},
192 {WINED3DFMT_DXT3
, 4, 4, 16},
193 {WINED3DFMT_DXT4
, 4, 4, 16},
194 {WINED3DFMT_DXT5
, 4, 4, 16},
195 {WINED3DFMT_ATI2N
, 1, 1, 1},
198 struct wined3d_format_vertex_info
200 WINED3DFORMAT format
;
201 enum wined3d_ffp_emit_idx emit_idx
;
202 GLint component_count
;
205 GLboolean gl_normalized
;
206 unsigned int component_size
;
209 static const struct wined3d_format_vertex_info format_vertex_info
[] =
211 {WINED3DFMT_R32_FLOAT
, WINED3D_FFP_EMIT_FLOAT1
, 1, GL_FLOAT
, 1, GL_FALSE
, sizeof(float)},
212 {WINED3DFMT_R32G32_FLOAT
, WINED3D_FFP_EMIT_FLOAT2
, 2, GL_FLOAT
, 2, GL_FALSE
, sizeof(float)},
213 {WINED3DFMT_R32G32B32_FLOAT
, WINED3D_FFP_EMIT_FLOAT3
, 3, GL_FLOAT
, 3, GL_FALSE
, sizeof(float)},
214 {WINED3DFMT_R32G32B32A32_FLOAT
, WINED3D_FFP_EMIT_FLOAT4
, 4, GL_FLOAT
, 4, GL_FALSE
, sizeof(float)},
215 {WINED3DFMT_B8G8R8A8_UNORM
, WINED3D_FFP_EMIT_D3DCOLOR
, 4, GL_UNSIGNED_BYTE
, 4, GL_TRUE
, sizeof(BYTE
)},
216 {WINED3DFMT_R8G8B8A8_UINT
, WINED3D_FFP_EMIT_UBYTE4
, 4, GL_UNSIGNED_BYTE
, 4, GL_FALSE
, sizeof(BYTE
)},
217 {WINED3DFMT_R16G16_SINT
, WINED3D_FFP_EMIT_SHORT2
, 2, GL_SHORT
, 2, GL_FALSE
, sizeof(short int)},
218 {WINED3DFMT_R16G16B16A16_SINT
, WINED3D_FFP_EMIT_SHORT4
, 4, GL_SHORT
, 4, GL_FALSE
, sizeof(short int)},
219 {WINED3DFMT_R8G8B8A8_UNORM
, WINED3D_FFP_EMIT_UBYTE4N
, 4, GL_UNSIGNED_BYTE
, 4, GL_TRUE
, sizeof(BYTE
)},
220 {WINED3DFMT_R16G16_SNORM
, WINED3D_FFP_EMIT_SHORT2N
, 2, GL_SHORT
, 2, GL_TRUE
, sizeof(short int)},
221 {WINED3DFMT_R16G16B16A16_SNORM
, WINED3D_FFP_EMIT_SHORT4N
, 4, GL_SHORT
, 4, GL_TRUE
, sizeof(short int)},
222 {WINED3DFMT_R16G16_UNORM
, WINED3D_FFP_EMIT_USHORT2N
, 2, GL_UNSIGNED_SHORT
, 2, GL_TRUE
, sizeof(short int)},
223 {WINED3DFMT_R16G16B16A16_UNORM
, WINED3D_FFP_EMIT_USHORT4N
, 4, GL_UNSIGNED_SHORT
, 4, GL_TRUE
, sizeof(short int)},
224 {WINED3DFMT_R10G10B10A2_UINT
, WINED3D_FFP_EMIT_UDEC3
, 3, GL_UNSIGNED_SHORT
, 3, GL_FALSE
, sizeof(short int)},
225 {WINED3DFMT_R10G10B10A2_SNORM
, WINED3D_FFP_EMIT_DEC3N
, 3, GL_SHORT
, 3, GL_TRUE
, sizeof(short int)},
226 {WINED3DFMT_R16G16_FLOAT
, WINED3D_FFP_EMIT_FLOAT16_2
, 2, GL_FLOAT
, 2, GL_FALSE
, sizeof(GLhalfNV
)},
227 {WINED3DFMT_R16G16B16A16_FLOAT
, WINED3D_FFP_EMIT_FLOAT16_4
, 4, GL_FLOAT
, 4, GL_FALSE
, sizeof(GLhalfNV
)}
230 struct wined3d_format_texture_info
232 WINED3DFORMAT format
;
234 GLint gl_srgb_internal
;
235 GLint gl_rt_internal
;
238 unsigned int conv_byte_count
;
240 GL_SupportedExt extension
;
241 void (*convert
)(const BYTE
*src
, BYTE
*dst
, UINT pitch
, UINT width
, UINT height
);
244 static void convert_l4a4_unorm(const BYTE
*src
, BYTE
*dst
, UINT pitch
, UINT width
, UINT height
)
246 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
247 * format+type combination to load it. Thus convert it to A8L8, then load it
248 * with A4L4 internal, but A8L8 format+type
251 const unsigned char *Source
;
253 UINT outpitch
= pitch
* 2;
255 for(y
= 0; y
< height
; y
++) {
256 Source
= src
+ y
* pitch
;
257 Dest
= dst
+ y
* outpitch
;
258 for (x
= 0; x
< width
; x
++ ) {
259 unsigned char color
= (*Source
++);
260 /* A */ Dest
[1] = (color
& 0xf0) << 0;
261 /* L */ Dest
[0] = (color
& 0x0f) << 4;
267 static void convert_r5g5_snorm_l6_unorm(const BYTE
*src
, BYTE
*dst
, UINT pitch
, UINT width
, UINT height
)
272 for(y
= 0; y
< height
; y
++)
274 unsigned short *Dest_s
= (unsigned short *) (dst
+ y
* pitch
);
275 Source
= (const WORD
*)(src
+ y
* pitch
);
276 for (x
= 0; x
< width
; x
++ )
278 short color
= (*Source
++);
279 unsigned char l
= ((color
>> 10) & 0xfc);
280 short v
= ((color
>> 5) & 0x3e);
281 short u
= ((color
) & 0x1f);
282 short v_conv
= v
+ 16;
283 short u_conv
= u
+ 16;
285 *Dest_s
= ((v_conv
<< 11) & 0xf800) | ((l
<< 5) & 0x7e0) | (u_conv
& 0x1f);
291 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE
*src
, BYTE
*dst
, UINT pitch
, UINT width
, UINT height
)
296 UINT outpitch
= (pitch
* 3)/2;
298 /* This makes the gl surface bigger(24 bit instead of 16), but it works with
299 * fixed function and shaders without further conversion once the surface is
302 for(y
= 0; y
< height
; y
++) {
303 Source
= (const WORD
*)(src
+ y
* pitch
);
304 Dest
= dst
+ y
* outpitch
;
305 for (x
= 0; x
< width
; x
++ ) {
306 short color
= (*Source
++);
307 unsigned char l
= ((color
>> 10) & 0xfc);
308 char v
= ((color
>> 5) & 0x3e);
309 char u
= ((color
) & 0x1f);
311 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
312 * and doubles the positive range. Thus shift left only once, gl does the 2nd
313 * shift. GL reads a signed value and converts it into an unsigned value.
315 /* M */ Dest
[2] = l
<< 1;
317 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
318 * from 5 bit values to 8 bit values.
320 /* V */ Dest
[1] = v
<< 3;
321 /* U */ Dest
[0] = u
<< 3;
327 static void convert_r8g8_snorm(const BYTE
*src
, BYTE
*dst
, UINT pitch
, UINT width
, UINT height
)
332 UINT outpitch
= (pitch
* 3)/2;
334 for(y
= 0; y
< height
; y
++)
336 Source
= (const short *)(src
+ y
* pitch
);
337 Dest
= dst
+ y
* outpitch
;
338 for (x
= 0; x
< width
; x
++ )
340 LONG color
= (*Source
++);
341 /* B */ Dest
[0] = 0xff;
342 /* G */ Dest
[1] = (color
>> 8) + 128; /* V */
343 /* R */ Dest
[2] = (color
) + 128; /* U */
349 static void convert_r8g8_snorm_l8x8_unorm(const BYTE
*src
, BYTE
*dst
, UINT pitch
, UINT width
, UINT height
)
355 /* Doesn't work correctly with the fixed function pipeline, but can work in
356 * shaders if the shader is adjusted. (There's no use for this format in gl's
357 * standard fixed function pipeline anyway).
359 for(y
= 0; y
< height
; y
++)
361 Source
= (const DWORD
*)(src
+ y
* pitch
);
362 Dest
= dst
+ y
* pitch
;
363 for (x
= 0; x
< width
; x
++ )
365 LONG color
= (*Source
++);
366 /* B */ Dest
[0] = ((color
>> 16) & 0xff); /* L */
367 /* G */ Dest
[1] = ((color
>> 8 ) & 0xff) + 128; /* V */
368 /* R */ Dest
[2] = (color
& 0xff) + 128; /* U */
374 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE
*src
, BYTE
*dst
, UINT pitch
, UINT width
, UINT height
)
380 /* This implementation works with the fixed function pipeline and shaders
381 * without further modification after converting the surface.
383 for(y
= 0; y
< height
; y
++)
385 Source
= (const DWORD
*)(src
+ y
* pitch
);
386 Dest
= dst
+ y
* pitch
;
387 for (x
= 0; x
< width
; x
++ )
389 LONG color
= (*Source
++);
390 /* L */ Dest
[2] = ((color
>> 16) & 0xff); /* L */
391 /* V */ Dest
[1] = ((color
>> 8 ) & 0xff); /* V */
392 /* U */ Dest
[0] = (color
& 0xff); /* U */
393 /* I */ Dest
[3] = 255; /* X */
399 static void convert_r8g8b8a8_snorm(const BYTE
*src
, BYTE
*dst
, UINT pitch
, UINT width
, UINT height
)
405 for(y
= 0; y
< height
; y
++)
407 Source
= (const DWORD
*)(src
+ y
* pitch
);
408 Dest
= dst
+ y
* pitch
;
409 for (x
= 0; x
< width
; x
++ )
411 LONG color
= (*Source
++);
412 /* B */ Dest
[0] = ((color
>> 16) & 0xff) + 128; /* W */
413 /* G */ Dest
[1] = ((color
>> 8 ) & 0xff) + 128; /* V */
414 /* R */ Dest
[2] = (color
& 0xff) + 128; /* U */
415 /* A */ Dest
[3] = ((color
>> 24) & 0xff) + 128; /* Q */
421 static void convert_r16g16_snorm(const BYTE
*src
, BYTE
*dst
, UINT pitch
, UINT width
, UINT height
)
425 unsigned short *Dest
;
426 UINT outpitch
= (pitch
* 3)/2;
428 for(y
= 0; y
< height
; y
++)
430 Source
= (const DWORD
*)(src
+ y
* pitch
);
431 Dest
= (unsigned short *) (dst
+ y
* outpitch
);
432 for (x
= 0; x
< width
; x
++ )
434 DWORD color
= (*Source
++);
435 /* B */ Dest
[0] = 0xffff;
436 /* G */ Dest
[1] = (color
>> 16) + 32768; /* V */
437 /* R */ Dest
[2] = (color
) + 32768; /* U */
443 static void convert_r16g16(const BYTE
*src
, BYTE
*dst
, UINT pitch
, UINT width
, UINT height
)
448 UINT outpitch
= (pitch
* 3)/2;
450 for(y
= 0; y
< height
; y
++)
452 Source
= (const WORD
*)(src
+ y
* pitch
);
453 Dest
= (WORD
*) (dst
+ y
* outpitch
);
454 for (x
= 0; x
< width
; x
++ )
456 WORD green
= (*Source
++);
457 WORD red
= (*Source
++);
460 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
461 * shader overwrites it anyway
469 static void convert_r32g32_float(const BYTE
*src
, BYTE
*dst
, UINT pitch
, UINT width
, UINT height
)
474 UINT outpitch
= (pitch
* 3)/2;
476 for(y
= 0; y
< height
; y
++)
478 Source
= (const float *)(src
+ y
* pitch
);
479 Dest
= (float *) (dst
+ y
* outpitch
);
480 for (x
= 0; x
< width
; x
++ )
482 float green
= (*Source
++);
483 float red
= (*Source
++);
492 static void convert_s1_uint_d15_unorm(const BYTE
*src
, BYTE
*dst
, UINT pitch
, UINT width
, UINT height
)
495 UINT outpitch
= pitch
* 2;
497 for (y
= 0; y
< height
; ++y
)
499 const WORD
*source
= (const WORD
*)(src
+ y
* pitch
);
500 DWORD
*dest
= (DWORD
*)(dst
+ y
* outpitch
);
502 for (x
= 0; x
< width
; ++x
)
504 /* The depth data is normalized, so needs to be scaled,
505 * the stencil data isn't. Scale depth data by
506 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
507 WORD d15
= source
[x
] >> 1;
508 DWORD d24
= (d15
<< 9) + (d15
>> 6);
509 dest
[x
] = (d24
<< 8) | (source
[x
] & 0x1);
514 static void convert_s4x4_uint_d24_unorm(const BYTE
*src
, BYTE
*dst
, UINT pitch
, UINT width
, UINT height
)
518 for (y
= 0; y
< height
; ++y
)
520 const DWORD
*source
= (const DWORD
*)(src
+ y
* pitch
);
521 DWORD
*dest
= (DWORD
*)(dst
+ y
* pitch
);
523 for (x
= 0; x
< width
; ++x
)
525 /* Just need to clear out the X4 part. */
526 dest
[x
] = source
[x
] & ~0xf0;
531 static void convert_s8_uint_d24_float(const BYTE
*src
, BYTE
*dst
, UINT pitch
, UINT width
, UINT height
)
534 UINT outpitch
= pitch
* 2;
536 for (y
= 0; y
< height
; ++y
)
538 const DWORD
*source
= (const DWORD
*)(src
+ y
* pitch
);
539 float *dest_f
= (float *)(dst
+ y
* outpitch
);
540 DWORD
*dest_s
= (DWORD
*)(dst
+ y
* outpitch
);
542 for (x
= 0; x
< width
; ++x
)
544 dest_f
[x
* 2] = float_24_to_32((source
[x
] & 0xffffff00) >> 8);
545 dest_s
[x
* 2 + 1] = source
[x
] & 0xff;
550 static const struct wined3d_format_texture_info format_texture_info
[] =
552 /* WINED3DFORMAT internal srgbInternal rtInternal
557 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
558 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
559 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
560 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
563 {WINED3DFMT_UYVY
, GL_LUMINANCE_ALPHA
, GL_LUMINANCE_ALPHA
, 0,
564 GL_LUMINANCE_ALPHA
, GL_UNSIGNED_BYTE
, 0,
565 WINED3DFMT_FLAG_FILTERING
,
566 WINED3D_GL_EXT_NONE
, NULL
},
567 {WINED3DFMT_UYVY
, GL_RGB
, GL_RGB
, 0,
568 GL_YCBCR_422_APPLE
, UNSIGNED_SHORT_8_8_APPLE
, 0,
569 WINED3DFMT_FLAG_FILTERING
,
570 APPLE_YCBCR_422
, NULL
},
571 {WINED3DFMT_YUY2
, GL_LUMINANCE_ALPHA
, GL_LUMINANCE_ALPHA
, 0,
572 GL_LUMINANCE_ALPHA
, GL_UNSIGNED_BYTE
, 0,
573 WINED3DFMT_FLAG_FILTERING
,
574 WINED3D_GL_EXT_NONE
, NULL
},
575 {WINED3DFMT_YUY2
, GL_RGB
, GL_RGB
, 0,
576 GL_YCBCR_422_APPLE
, UNSIGNED_SHORT_8_8_REV_APPLE
, 0,
577 WINED3DFMT_FLAG_FILTERING
,
578 APPLE_YCBCR_422
, NULL
},
579 {WINED3DFMT_YV12
, GL_ALPHA
, GL_ALPHA
, 0,
580 GL_ALPHA
, GL_UNSIGNED_BYTE
, 0,
581 WINED3DFMT_FLAG_FILTERING
,
582 WINED3D_GL_EXT_NONE
, NULL
},
583 {WINED3DFMT_DXT1
, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
, 0,
584 GL_RGBA
, GL_UNSIGNED_BYTE
, 0,
585 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ
,
586 EXT_TEXTURE_COMPRESSION_S3TC
, NULL
},
587 {WINED3DFMT_DXT2
, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
, 0,
588 GL_RGBA
, GL_UNSIGNED_BYTE
, 0,
589 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ
,
590 EXT_TEXTURE_COMPRESSION_S3TC
, NULL
},
591 {WINED3DFMT_DXT3
, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
, 0,
592 GL_RGBA
, GL_UNSIGNED_BYTE
, 0,
593 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ
,
594 EXT_TEXTURE_COMPRESSION_S3TC
, NULL
},
595 {WINED3DFMT_DXT4
, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
, 0,
596 GL_RGBA
, GL_UNSIGNED_BYTE
, 0,
597 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ
,
598 EXT_TEXTURE_COMPRESSION_S3TC
, NULL
},
599 {WINED3DFMT_DXT5
, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
, 0,
600 GL_RGBA
, GL_UNSIGNED_BYTE
, 0,
601 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ
,
602 EXT_TEXTURE_COMPRESSION_S3TC
, NULL
},
604 {WINED3DFMT_R32_FLOAT
, GL_RGB32F_ARB
, GL_RGB32F_ARB
, 0,
606 WINED3DFMT_FLAG_RENDERTARGET
,
607 ARB_TEXTURE_FLOAT
, NULL
},
608 {WINED3DFMT_R32_FLOAT
, GL_R32F
, GL_R32F
, 0,
610 WINED3DFMT_FLAG_RENDERTARGET
,
611 ARB_TEXTURE_RG
, NULL
},
612 {WINED3DFMT_R32G32_FLOAT
, GL_RGB32F_ARB
, GL_RGB32F_ARB
, 0,
613 GL_RGB
, GL_FLOAT
, 12,
614 WINED3DFMT_FLAG_RENDERTARGET
,
615 ARB_TEXTURE_FLOAT
, &convert_r32g32_float
},
616 {WINED3DFMT_R32G32_FLOAT
, GL_RG32F
, GL_RG32F
, 0,
618 WINED3DFMT_FLAG_RENDERTARGET
,
619 ARB_TEXTURE_RG
, NULL
},
620 {WINED3DFMT_R32G32B32A32_FLOAT
, GL_RGBA32F_ARB
, GL_RGBA32F_ARB
, 0,
621 GL_RGBA
, GL_FLOAT
, 0,
622 WINED3DFMT_FLAG_RENDERTARGET
| WINED3DFMT_FLAG_VTF
,
623 ARB_TEXTURE_FLOAT
, NULL
},
625 {WINED3DFMT_R16_FLOAT
, GL_RGB16F_ARB
, GL_RGB16F_ARB
, 0,
626 GL_RED
, GL_HALF_FLOAT_ARB
, 0,
627 WINED3DFMT_FLAG_RENDERTARGET
,
628 ARB_TEXTURE_FLOAT
, NULL
},
629 {WINED3DFMT_R16_FLOAT
, GL_R16F
, GL_R16F
, 0,
630 GL_RED
, GL_HALF_FLOAT_ARB
, 0,
631 WINED3DFMT_FLAG_RENDERTARGET
,
632 ARB_TEXTURE_RG
, NULL
},
633 {WINED3DFMT_R16G16_FLOAT
, GL_RGB16F_ARB
, GL_RGB16F_ARB
, 0,
634 GL_RGB
, GL_HALF_FLOAT_ARB
, 6,
635 WINED3DFMT_FLAG_RENDERTARGET
,
636 ARB_TEXTURE_FLOAT
, &convert_r16g16
},
637 {WINED3DFMT_R16G16_FLOAT
, GL_RG16F
, GL_RG16F
, 0,
638 GL_RG
, GL_HALF_FLOAT_ARB
, 0,
639 WINED3DFMT_FLAG_RENDERTARGET
,
640 ARB_TEXTURE_RG
, NULL
},
641 {WINED3DFMT_R16G16B16A16_FLOAT
, GL_RGBA16F_ARB
, GL_RGBA16F_ARB
, 0,
642 GL_RGBA
, GL_HALF_FLOAT_ARB
, 0,
643 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_RENDERTARGET
,
644 ARB_TEXTURE_FLOAT
, NULL
},
645 /* Palettized formats */
646 {WINED3DFMT_P8_UINT
, GL_RGBA
, GL_RGBA
, 0,
647 GL_ALPHA
, GL_UNSIGNED_BYTE
, 0,
649 ARB_FRAGMENT_PROGRAM
, NULL
},
650 {WINED3DFMT_P8_UINT
, GL_COLOR_INDEX8_EXT
, GL_COLOR_INDEX8_EXT
, 0,
651 GL_COLOR_INDEX
, GL_UNSIGNED_BYTE
, 0,
653 EXT_PALETTED_TEXTURE
, NULL
},
654 /* Standard ARGB formats */
655 {WINED3DFMT_B8G8R8_UNORM
, GL_RGB8
, GL_RGB8
, 0,
656 GL_BGR
, GL_UNSIGNED_BYTE
, 0,
657 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_RENDERTARGET
,
658 WINED3D_GL_EXT_NONE
, NULL
},
659 {WINED3DFMT_B8G8R8A8_UNORM
, GL_RGBA8
, GL_SRGB8_ALPHA8_EXT
, 0,
660 GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
, 0,
661 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_RENDERTARGET
662 | WINED3DFMT_FLAG_SRGB_READ
| WINED3DFMT_FLAG_SRGB_WRITE
,
663 WINED3D_GL_EXT_NONE
, NULL
},
664 {WINED3DFMT_B8G8R8X8_UNORM
, GL_RGB8
, GL_SRGB8_EXT
, 0,
665 GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
, 0,
666 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_RENDERTARGET
667 | WINED3DFMT_FLAG_SRGB_READ
| WINED3DFMT_FLAG_SRGB_WRITE
,
668 WINED3D_GL_EXT_NONE
, NULL
},
669 {WINED3DFMT_B5G6R5_UNORM
, GL_RGB5
, GL_RGB5
, GL_RGB8
,
670 GL_RGB
, GL_UNSIGNED_SHORT_5_6_5
, 0,
671 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_RENDERTARGET
,
672 WINED3D_GL_EXT_NONE
, NULL
},
673 {WINED3DFMT_B5G5R5X1_UNORM
, GL_RGB5
, GL_RGB5_A1
, 0,
674 GL_BGRA
, GL_UNSIGNED_SHORT_1_5_5_5_REV
, 0,
675 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
,
676 WINED3D_GL_EXT_NONE
, NULL
},
677 {WINED3DFMT_B5G5R5A1_UNORM
, GL_RGB5_A1
, GL_RGB5_A1
, 0,
678 GL_BGRA
, GL_UNSIGNED_SHORT_1_5_5_5_REV
, 0,
679 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
,
680 WINED3D_GL_EXT_NONE
, NULL
},
681 {WINED3DFMT_B4G4R4A4_UNORM
, GL_RGBA4
, GL_SRGB8_ALPHA8_EXT
, 0,
682 GL_BGRA
, GL_UNSIGNED_SHORT_4_4_4_4_REV
, 0,
683 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ
,
684 WINED3D_GL_EXT_NONE
, NULL
},
685 {WINED3DFMT_B2G3R3_UNORM
, GL_R3_G3_B2
, GL_R3_G3_B2
, 0,
686 GL_RGB
, GL_UNSIGNED_BYTE_3_3_2
, 0,
687 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
,
688 WINED3D_GL_EXT_NONE
, NULL
},
689 {WINED3DFMT_A8_UNORM
, GL_ALPHA8
, GL_ALPHA8
, 0,
690 GL_ALPHA
, GL_UNSIGNED_BYTE
, 0,
691 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
,
692 WINED3D_GL_EXT_NONE
, NULL
},
693 {WINED3DFMT_B4G4R4X4_UNORM
, GL_RGB4
, GL_RGB4
, 0,
694 GL_BGRA
, GL_UNSIGNED_SHORT_4_4_4_4_REV
, 0,
695 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
,
696 WINED3D_GL_EXT_NONE
, NULL
},
697 {WINED3DFMT_R10G10B10A2_UNORM
, GL_RGB10_A2
, GL_RGB10_A2
, 0,
698 GL_RGBA
, GL_UNSIGNED_INT_2_10_10_10_REV
, 0,
699 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
,
700 WINED3D_GL_EXT_NONE
, NULL
},
701 {WINED3DFMT_R8G8B8A8_UNORM
, GL_RGBA8
, GL_RGBA8
, 0,
702 GL_RGBA
, GL_UNSIGNED_INT_8_8_8_8_REV
, 0,
703 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
,
704 WINED3D_GL_EXT_NONE
, NULL
},
705 {WINED3DFMT_R8G8B8X8_UNORM
, GL_RGB8
, GL_RGB8
, 0,
706 GL_RGBA
, GL_UNSIGNED_INT_8_8_8_8_REV
, 0,
707 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
,
708 WINED3D_GL_EXT_NONE
, NULL
},
709 {WINED3DFMT_R16G16_UNORM
, GL_RGB16
, GL_RGB16
, GL_RGBA16
,
710 GL_RGB
, GL_UNSIGNED_SHORT
, 6,
711 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
,
712 WINED3D_GL_EXT_NONE
, &convert_r16g16
},
713 {WINED3DFMT_B10G10R10A2_UNORM
, GL_RGB10_A2
, GL_RGB10_A2
, 0,
714 GL_BGRA
, GL_UNSIGNED_INT_2_10_10_10_REV
, 0,
715 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
,
716 WINED3D_GL_EXT_NONE
, NULL
},
717 {WINED3DFMT_R16G16B16A16_UNORM
, GL_RGBA16
, GL_RGBA16
, 0,
718 GL_RGBA
, GL_UNSIGNED_SHORT
, 0,
719 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_RENDERTARGET
,
720 WINED3D_GL_EXT_NONE
, NULL
},
722 {WINED3DFMT_L8_UNORM
, GL_LUMINANCE8
, GL_SLUMINANCE8_EXT
, 0,
723 GL_LUMINANCE
, GL_UNSIGNED_BYTE
, 0,
724 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ
,
725 WINED3D_GL_EXT_NONE
, NULL
},
726 {WINED3DFMT_L8A8_UNORM
, GL_LUMINANCE8_ALPHA8
, GL_SLUMINANCE8_ALPHA8_EXT
, 0,
727 GL_LUMINANCE_ALPHA
, GL_UNSIGNED_BYTE
, 0,
728 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ
,
729 WINED3D_GL_EXT_NONE
, NULL
},
730 {WINED3DFMT_L4A4_UNORM
, GL_LUMINANCE4_ALPHA4
, GL_LUMINANCE4_ALPHA4
, 0,
731 GL_LUMINANCE_ALPHA
, GL_UNSIGNED_BYTE
, 2,
733 WINED3D_GL_EXT_NONE
, &convert_l4a4_unorm
},
734 /* Bump mapping stuff */
735 {WINED3DFMT_R8G8_SNORM
, GL_RGB8
, GL_RGB8
, 0,
736 GL_BGR
, GL_UNSIGNED_BYTE
, 3,
737 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_BUMPMAP
,
738 WINED3D_GL_EXT_NONE
, &convert_r8g8_snorm
},
739 {WINED3DFMT_R8G8_SNORM
, GL_DSDT8_NV
, GL_DSDT8_NV
, 0,
740 GL_DSDT_NV
, GL_BYTE
, 0,
741 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_BUMPMAP
,
742 NV_TEXTURE_SHADER
, NULL
},
743 {WINED3DFMT_R5G5_SNORM_L6_UNORM
, GL_RGB5
, GL_RGB5
, 0,
744 GL_RGB
, GL_UNSIGNED_SHORT_5_6_5
, 2,
745 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_BUMPMAP
,
746 WINED3D_GL_EXT_NONE
, &convert_r5g5_snorm_l6_unorm
},
747 {WINED3DFMT_R5G5_SNORM_L6_UNORM
, GL_DSDT8_MAG8_NV
, GL_DSDT8_MAG8_NV
, 0,
748 GL_DSDT_MAG_NV
, GL_BYTE
, 3,
749 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_BUMPMAP
,
750 NV_TEXTURE_SHADER
, &convert_r5g5_snorm_l6_unorm_nv
},
751 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM
, GL_RGB8
, GL_RGB8
, 0,
752 GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
, 4,
753 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_BUMPMAP
,
754 WINED3D_GL_EXT_NONE
, &convert_r8g8_snorm_l8x8_unorm
},
755 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM
, GL_DSDT8_MAG8_INTENSITY8_NV
, GL_DSDT8_MAG8_INTENSITY8_NV
, 0,
756 GL_DSDT_MAG_VIB_NV
, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV
, 4,
757 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_BUMPMAP
,
758 NV_TEXTURE_SHADER
, &convert_r8g8_snorm_l8x8_unorm_nv
},
759 {WINED3DFMT_R8G8B8A8_SNORM
, GL_RGBA8
, GL_RGBA8
, 0,
760 GL_BGRA
, GL_UNSIGNED_BYTE
, 4,
761 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_BUMPMAP
,
762 WINED3D_GL_EXT_NONE
, &convert_r8g8b8a8_snorm
},
763 {WINED3DFMT_R8G8B8A8_SNORM
, GL_SIGNED_RGBA8_NV
, GL_SIGNED_RGBA8_NV
, 0,
765 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_BUMPMAP
,
766 NV_TEXTURE_SHADER
, NULL
},
767 {WINED3DFMT_R16G16_SNORM
, GL_RGB16
, GL_RGB16
, 0,
768 GL_BGR
, GL_UNSIGNED_SHORT
, 6,
769 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_BUMPMAP
,
770 WINED3D_GL_EXT_NONE
, &convert_r16g16_snorm
},
771 {WINED3DFMT_R16G16_SNORM
, GL_SIGNED_HILO16_NV
, GL_SIGNED_HILO16_NV
, 0,
772 GL_HILO_NV
, GL_SHORT
, 0,
773 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_BUMPMAP
,
774 NV_TEXTURE_SHADER
, NULL
},
775 /* Depth stencil formats */
776 {WINED3DFMT_D16_LOCKABLE
, GL_DEPTH_COMPONENT24_ARB
, GL_DEPTH_COMPONENT24_ARB
, 0,
777 GL_DEPTH_COMPONENT
, GL_UNSIGNED_SHORT
, 0,
778 WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_SHADOW
,
779 ARB_DEPTH_TEXTURE
, NULL
},
780 {WINED3DFMT_D32_UNORM
, GL_DEPTH_COMPONENT32_ARB
, GL_DEPTH_COMPONENT32_ARB
, 0,
781 GL_DEPTH_COMPONENT
, GL_UNSIGNED_INT
, 0,
782 WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_SHADOW
,
783 ARB_DEPTH_TEXTURE
, NULL
},
784 {WINED3DFMT_S1_UINT_D15_UNORM
, GL_DEPTH_COMPONENT24_ARB
, GL_DEPTH_COMPONENT24_ARB
, 0,
785 GL_DEPTH_COMPONENT
, GL_UNSIGNED_SHORT
, 0,
786 WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_SHADOW
,
787 ARB_DEPTH_TEXTURE
, NULL
},
788 {WINED3DFMT_S1_UINT_D15_UNORM
, GL_DEPTH24_STENCIL8_EXT
, GL_DEPTH24_STENCIL8_EXT
, 0,
789 GL_DEPTH_STENCIL_EXT
, GL_UNSIGNED_INT_24_8_EXT
, 4,
790 WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_STENCIL
| WINED3DFMT_FLAG_SHADOW
,
791 EXT_PACKED_DEPTH_STENCIL
, &convert_s1_uint_d15_unorm
},
792 {WINED3DFMT_S1_UINT_D15_UNORM
, GL_DEPTH24_STENCIL8
, GL_DEPTH24_STENCIL8
, 0,
793 GL_DEPTH_STENCIL
, GL_UNSIGNED_INT_24_8
, 4,
794 WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_STENCIL
| WINED3DFMT_FLAG_SHADOW
,
795 ARB_FRAMEBUFFER_OBJECT
, &convert_s1_uint_d15_unorm
},
796 {WINED3DFMT_D24_UNORM_S8_UINT
, GL_DEPTH_COMPONENT24_ARB
, GL_DEPTH_COMPONENT24_ARB
, 0,
797 GL_DEPTH_COMPONENT
, GL_UNSIGNED_INT
, 0,
798 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_DEPTH
799 | WINED3DFMT_FLAG_SHADOW
,
800 ARB_DEPTH_TEXTURE
, NULL
},
801 {WINED3DFMT_D24_UNORM_S8_UINT
, GL_DEPTH24_STENCIL8_EXT
, GL_DEPTH24_STENCIL8_EXT
, 0,
802 GL_DEPTH_STENCIL_EXT
, GL_UNSIGNED_INT_24_8_EXT
, 0,
803 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_DEPTH
804 | WINED3DFMT_FLAG_STENCIL
| WINED3DFMT_FLAG_SHADOW
,
805 EXT_PACKED_DEPTH_STENCIL
, NULL
},
806 {WINED3DFMT_D24_UNORM_S8_UINT
, GL_DEPTH24_STENCIL8
, GL_DEPTH24_STENCIL8
, 0,
807 GL_DEPTH_STENCIL
, GL_UNSIGNED_INT_24_8
, 0,
808 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_DEPTH
809 | WINED3DFMT_FLAG_STENCIL
| WINED3DFMT_FLAG_SHADOW
,
810 ARB_FRAMEBUFFER_OBJECT
, NULL
},
811 {WINED3DFMT_X8D24_UNORM
, GL_DEPTH_COMPONENT24_ARB
, GL_DEPTH_COMPONENT24_ARB
, 0,
812 GL_DEPTH_COMPONENT
, GL_UNSIGNED_INT
, 0,
813 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_DEPTH
814 | WINED3DFMT_FLAG_SHADOW
,
815 ARB_DEPTH_TEXTURE
, NULL
},
816 {WINED3DFMT_S4X4_UINT_D24_UNORM
, GL_DEPTH_COMPONENT24_ARB
, GL_DEPTH_COMPONENT24_ARB
, 0,
817 GL_DEPTH_COMPONENT
, GL_UNSIGNED_INT
, 0,
818 WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_SHADOW
,
819 ARB_DEPTH_TEXTURE
, NULL
},
820 {WINED3DFMT_S4X4_UINT_D24_UNORM
, GL_DEPTH24_STENCIL8_EXT
, GL_DEPTH24_STENCIL8_EXT
, 0,
821 GL_DEPTH_STENCIL_EXT
, GL_UNSIGNED_INT_24_8_EXT
, 4,
822 WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_STENCIL
| WINED3DFMT_FLAG_SHADOW
,
823 EXT_PACKED_DEPTH_STENCIL
, &convert_s4x4_uint_d24_unorm
},
824 {WINED3DFMT_S4X4_UINT_D24_UNORM
, GL_DEPTH24_STENCIL8
, GL_DEPTH24_STENCIL8
, 0,
825 GL_DEPTH_STENCIL
, GL_UNSIGNED_INT_24_8
, 4,
826 WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_STENCIL
| WINED3DFMT_FLAG_SHADOW
,
827 ARB_FRAMEBUFFER_OBJECT
, &convert_s4x4_uint_d24_unorm
},
828 {WINED3DFMT_D16_UNORM
, GL_DEPTH_COMPONENT24_ARB
, GL_DEPTH_COMPONENT24_ARB
, 0,
829 GL_DEPTH_COMPONENT
, GL_UNSIGNED_SHORT
, 0,
830 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_DEPTH
831 | WINED3DFMT_FLAG_SHADOW
,
832 ARB_DEPTH_TEXTURE
, NULL
},
833 {WINED3DFMT_L16_UNORM
, GL_LUMINANCE16
, GL_LUMINANCE16
, 0,
834 GL_LUMINANCE
, GL_UNSIGNED_SHORT
, 0,
835 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
,
836 WINED3D_GL_EXT_NONE
, NULL
},
837 {WINED3DFMT_D32_FLOAT
, GL_DEPTH_COMPONENT32F
, GL_DEPTH_COMPONENT32F
, 0,
838 GL_DEPTH_COMPONENT
, GL_FLOAT
, 0,
839 WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_SHADOW
,
840 ARB_DEPTH_BUFFER_FLOAT
, NULL
},
841 {WINED3DFMT_S8_UINT_D24_FLOAT
, GL_DEPTH32F_STENCIL8
, GL_DEPTH32F_STENCIL8
, 0,
842 GL_DEPTH_STENCIL
, GL_FLOAT_32_UNSIGNED_INT_24_8_REV
, 8,
843 WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_STENCIL
| WINED3DFMT_FLAG_SHADOW
,
844 ARB_DEPTH_BUFFER_FLOAT
, &convert_s8_uint_d24_float
},
845 /* Vendor-specific formats */
846 {WINED3DFMT_ATI2N
, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI
, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI
, 0,
847 GL_LUMINANCE_ALPHA
, GL_UNSIGNED_BYTE
, 0,
849 ATI_TEXTURE_COMPRESSION_3DC
, NULL
},
850 {WINED3DFMT_ATI2N
, GL_COMPRESSED_RED_GREEN_RGTC2_EXT
, GL_COMPRESSED_RED_GREEN_RGTC2_EXT
, 0,
851 GL_LUMINANCE_ALPHA
, GL_UNSIGNED_BYTE
, 0,
853 EXT_TEXTURE_COMPRESSION_RGTC
, NULL
},
856 static inline int getFmtIdx(WINED3DFORMAT fmt
) {
857 /* First check if the format is at the position of its value.
858 * This will catch the argb formats before the loop is entered
860 if(fmt
< (sizeof(formats
) / sizeof(formats
[0])) && formats
[fmt
].format
== fmt
) {
864 for(i
= 0; i
< (sizeof(formats
) / sizeof(formats
[0])); i
++) {
865 if(formats
[i
].format
== fmt
) {
873 static BOOL
init_format_base_info(struct wined3d_gl_info
*gl_info
)
875 UINT format_count
= sizeof(formats
) / sizeof(*formats
);
878 gl_info
->gl_formats
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, format_count
* sizeof(*gl_info
->gl_formats
));
879 if (!gl_info
->gl_formats
)
881 ERR("Failed to allocate memory.\n");
885 for (i
= 0; i
< format_count
; ++i
)
887 struct wined3d_format_desc
*desc
= &gl_info
->gl_formats
[i
];
888 desc
->format
= formats
[i
].format
;
889 desc
->red_mask
= formats
[i
].redMask
;
890 desc
->green_mask
= formats
[i
].greenMask
;
891 desc
->blue_mask
= formats
[i
].blueMask
;
892 desc
->alpha_mask
= formats
[i
].alphaMask
;
893 desc
->byte_count
= formats
[i
].bpp
;
894 desc
->depth_size
= formats
[i
].depthSize
;
895 desc
->stencil_size
= formats
[i
].stencilSize
;
898 for (i
= 0; i
< (sizeof(format_base_flags
) / sizeof(*format_base_flags
)); ++i
)
900 int fmt_idx
= getFmtIdx(format_base_flags
[i
].format
);
904 ERR("Format %s (%#x) not found.\n",
905 debug_d3dformat(format_base_flags
[i
].format
), format_base_flags
[i
].format
);
906 HeapFree(GetProcessHeap(), 0, gl_info
->gl_formats
);
910 gl_info
->gl_formats
[fmt_idx
].Flags
|= format_base_flags
[i
].flags
;
916 static BOOL
init_format_compression_info(struct wined3d_gl_info
*gl_info
)
920 for (i
= 0; i
< (sizeof(format_compression_info
) / sizeof(*format_compression_info
)); ++i
)
922 struct wined3d_format_desc
*format_desc
;
923 int fmt_idx
= getFmtIdx(format_compression_info
[i
].format
);
927 ERR("Format %s (%#x) not found.\n",
928 debug_d3dformat(format_compression_info
[i
].format
), format_compression_info
[i
].format
);
932 format_desc
= &gl_info
->gl_formats
[fmt_idx
];
933 format_desc
->block_width
= format_compression_info
[i
].block_width
;
934 format_desc
->block_height
= format_compression_info
[i
].block_height
;
935 format_desc
->block_byte_count
= format_compression_info
[i
].block_byte_count
;
936 format_desc
->Flags
|= WINED3DFMT_FLAG_COMPRESSED
;
942 /* Context activation is done by the caller. */
943 static void check_fbo_compat(const struct wined3d_gl_info
*gl_info
, struct wined3d_format_desc
*format_desc
)
945 /* Check if the default internal format is supported as a frame buffer
946 * target, otherwise fall back to the render target internal.
948 * Try to stick to the standard format if possible, this limits precision differences. */
957 glGenTextures(1, &tex
);
958 glBindTexture(GL_TEXTURE_2D
, tex
);
960 glTexImage2D(GL_TEXTURE_2D
, 0, format_desc
->glInternal
, 16, 16, 0,
961 format_desc
->glFormat
, format_desc
->glType
, NULL
);
962 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
963 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
965 gl_info
->fbo_ops
.glFramebufferTexture2D(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, tex
, 0);
967 status
= gl_info
->fbo_ops
.glCheckFramebufferStatus(GL_FRAMEBUFFER
);
968 checkGLcall("Framebuffer format check");
970 if (status
== GL_FRAMEBUFFER_COMPLETE
)
972 TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(format_desc
->format
));
973 format_desc
->Flags
|= WINED3DFMT_FLAG_FBO_ATTACHABLE
;
974 format_desc
->rtInternal
= format_desc
->glInternal
;
978 if (!format_desc
->rtInternal
)
980 if (format_desc
->Flags
& WINED3DFMT_FLAG_RENDERTARGET
)
982 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
983 " and no fallback specified.\n", debug_d3dformat(format_desc
->format
));
984 format_desc
->Flags
&= ~WINED3DFMT_FLAG_RENDERTARGET
;
988 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format_desc
->format
));
990 format_desc
->rtInternal
= format_desc
->glInternal
;
994 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
995 debug_d3dformat(format_desc
->format
));
999 gl_info
->fbo_ops
.glFramebufferTexture2D(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, 0, 0);
1001 glTexImage2D(GL_TEXTURE_2D
, 0, format_desc
->rtInternal
, 16, 16, 0,
1002 format_desc
->glFormat
, format_desc
->glType
, NULL
);
1003 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
1004 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
1006 gl_info
->fbo_ops
.glFramebufferTexture2D(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, tex
, 0);
1008 status
= gl_info
->fbo_ops
.glCheckFramebufferStatus(GL_FRAMEBUFFER
);
1009 checkGLcall("Framebuffer format check");
1011 if (status
== GL_FRAMEBUFFER_COMPLETE
)
1013 TRACE("Format %s rtInternal format is supported as FBO color attachment\n",
1014 debug_d3dformat(format_desc
->format
));
1018 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
1019 debug_d3dformat(format_desc
->format
));
1020 format_desc
->Flags
&= ~WINED3DFMT_FLAG_RENDERTARGET
;
1025 if (status
== GL_FRAMEBUFFER_COMPLETE
&& format_desc
->Flags
& WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
)
1029 if (gl_info
->supported
[ARB_FRAMEBUFFER_OBJECT
]
1030 || gl_info
->supported
[EXT_PACKED_DEPTH_STENCIL
])
1032 gl_info
->fbo_ops
.glGenRenderbuffers(1, &rb
);
1033 gl_info
->fbo_ops
.glBindRenderbuffer(GL_RENDERBUFFER
, rb
);
1034 gl_info
->fbo_ops
.glRenderbufferStorage(GL_RENDERBUFFER
, GL_DEPTH24_STENCIL8
, 16, 16);
1035 gl_info
->fbo_ops
.glFramebufferRenderbuffer(GL_FRAMEBUFFER
, GL_DEPTH_ATTACHMENT
, GL_RENDERBUFFER
, rb
);
1036 gl_info
->fbo_ops
.glFramebufferRenderbuffer(GL_FRAMEBUFFER
, GL_STENCIL_ATTACHMENT
, GL_RENDERBUFFER
, rb
);
1037 checkGLcall("RB attachment");
1041 glClear(GL_COLOR_BUFFER_BIT
);
1042 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION
)
1044 while(glGetError());
1045 TRACE("Format doesn't support post-pixelshader blending.\n");
1046 format_desc
->Flags
&= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
;
1049 if (gl_info
->supported
[ARB_FRAMEBUFFER_OBJECT
]
1050 || gl_info
->supported
[EXT_PACKED_DEPTH_STENCIL
])
1052 gl_info
->fbo_ops
.glFramebufferRenderbuffer(GL_FRAMEBUFFER
, GL_DEPTH_ATTACHMENT
, GL_RENDERBUFFER
, 0);
1053 gl_info
->fbo_ops
.glFramebufferRenderbuffer(GL_FRAMEBUFFER
, GL_STENCIL_ATTACHMENT
, GL_RENDERBUFFER
, 0);
1054 gl_info
->fbo_ops
.glDeleteRenderbuffers(1, &rb
);
1055 checkGLcall("RB cleanup");
1059 glDeleteTextures(1, &tex
);
1064 /* Context activation is done by the caller. */
1065 static void init_format_fbo_compat_info(struct wined3d_gl_info
*gl_info
)
1070 if (wined3d_settings
.offscreen_rendering_mode
== ORM_FBO
)
1074 gl_info
->fbo_ops
.glGenFramebuffers(1, &fbo
);
1075 gl_info
->fbo_ops
.glBindFramebuffer(GL_FRAMEBUFFER
, fbo
);
1080 for (i
= 0; i
< sizeof(formats
) / sizeof(*formats
); ++i
)
1082 struct wined3d_format_desc
*desc
= &gl_info
->gl_formats
[i
];
1084 if (!desc
->glInternal
) continue;
1086 if (desc
->Flags
& (WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_STENCIL
))
1088 TRACE("Skipping format %s because it's a depth/stencil format.\n",
1089 debug_d3dformat(desc
->format
));
1093 if (desc
->Flags
& WINED3DFMT_FLAG_COMPRESSED
)
1095 TRACE("Skipping format %s because it's a compressed format.\n",
1096 debug_d3dformat(desc
->format
));
1100 if (wined3d_settings
.offscreen_rendering_mode
== ORM_FBO
)
1102 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc
->format
));
1103 check_fbo_compat(gl_info
, desc
);
1107 desc
->rtInternal
= desc
->glInternal
;
1111 if (wined3d_settings
.offscreen_rendering_mode
== ORM_FBO
)
1115 gl_info
->fbo_ops
.glDeleteFramebuffers(1, &fbo
);
1121 static BOOL
init_format_texture_info(struct wined3d_gl_info
*gl_info
)
1125 for (i
= 0; i
< sizeof(format_texture_info
) / sizeof(*format_texture_info
); ++i
)
1127 int fmt_idx
= getFmtIdx(format_texture_info
[i
].format
);
1128 struct wined3d_format_desc
*desc
;
1132 ERR("Format %s (%#x) not found.\n",
1133 debug_d3dformat(format_texture_info
[i
].format
), format_texture_info
[i
].format
);
1137 if (!gl_info
->supported
[format_texture_info
[i
].extension
]) continue;
1139 desc
= &gl_info
->gl_formats
[fmt_idx
];
1140 desc
->glInternal
= format_texture_info
[i
].gl_internal
;
1141 desc
->glGammaInternal
= format_texture_info
[i
].gl_srgb_internal
;
1142 desc
->rtInternal
= format_texture_info
[i
].gl_rt_internal
;
1143 desc
->glFormat
= format_texture_info
[i
].gl_format
;
1144 desc
->glType
= format_texture_info
[i
].gl_type
;
1145 desc
->color_fixup
= COLOR_FIXUP_IDENTITY
;
1146 desc
->Flags
|= format_texture_info
[i
].flags
;
1147 desc
->heightscale
= 1.0f
;
1149 /* Texture conversion stuff */
1150 desc
->convert
= format_texture_info
[i
].convert
;
1151 desc
->conv_byte_count
= format_texture_info
[i
].conv_byte_count
;
1157 static BOOL
color_match(DWORD c1
, DWORD c2
, BYTE max_diff
)
1159 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
1161 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
1163 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
1165 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
1169 /* A context is provided by the caller */
1170 static BOOL
check_filter(const struct wined3d_gl_info
*gl_info
, GLenum internal
)
1172 GLuint tex
, fbo
, buffer
;
1173 const DWORD data
[] = {0x00000000, 0xffffffff};
1174 DWORD readback
[16 * 1];
1177 /* Render a filtered texture and see what happens. This is intended to detect the lack of
1178 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
1179 * falling back to software. If this changes in the future this code will get fooled and
1180 * apps might hit the software path due to incorrectly advertised caps.
1182 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
1183 * disable fallback, if Apple or ATI ever change the driver behavior they will break more
1184 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
1188 while(glGetError());
1190 glGenTextures(1, &buffer
);
1191 glBindTexture(GL_TEXTURE_2D
, buffer
);
1192 memset(readback
, 0x7e, sizeof(readback
));
1193 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA8
, 16, 1, 0, GL_RGBA
, GL_UNSIGNED_INT_8_8_8_8
, readback
);
1194 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
1195 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
1196 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
1197 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
1198 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_R
, GL_CLAMP_TO_EDGE
);
1200 glGenTextures(1, &tex
);
1201 glBindTexture(GL_TEXTURE_2D
, tex
);
1202 glTexImage2D(GL_TEXTURE_2D
, 0, internal
, 2, 1, 0, GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
, data
);
1203 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
1204 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
1205 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
1206 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
1207 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_R
, GL_CLAMP_TO_EDGE
);
1208 glEnable(GL_TEXTURE_2D
);
1210 gl_info
->fbo_ops
.glGenFramebuffers(1, &fbo
);
1211 gl_info
->fbo_ops
.glBindFramebuffer(GL_FRAMEBUFFER
, fbo
);
1212 gl_info
->fbo_ops
.glFramebufferTexture2D(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, buffer
, 0);
1213 glDrawBuffer(GL_COLOR_ATTACHMENT0
);
1215 glViewport(0, 0, 16, 1);
1216 glDisable(GL_LIGHTING
);
1217 glMatrixMode(GL_MODELVIEW
);
1219 glMatrixMode(GL_PROJECTION
);
1222 glClearColor(0, 1, 0, 0);
1223 glClear(GL_COLOR_BUFFER_BIT
);
1225 glBegin(GL_TRIANGLE_STRIP
);
1226 glTexCoord2f(0.0, 0.0);
1227 glVertex2f(-1.0f
, -1.0f
);
1228 glTexCoord2f(1.0, 0.0);
1229 glVertex2f(1.0f
, -1.0f
);
1230 glTexCoord2f(0.0, 1.0);
1231 glVertex2f(-1.0f
, 1.0f
);
1232 glTexCoord2f(1.0, 1.0);
1233 glVertex2f(1.0f
, 1.0f
);
1236 glBindTexture(GL_TEXTURE_2D
, buffer
);
1237 memset(readback
, 0x7f, sizeof(readback
));
1238 glGetTexImage(GL_TEXTURE_2D
, 0, GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
, readback
);
1239 if(color_match(readback
[6], 0xffffffff, 5) || color_match(readback
[6], 0x00000000, 5) ||
1240 color_match(readback
[9], 0xffffffff, 5) || color_match(readback
[9], 0x00000000, 5))
1242 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
1243 readback
[6], readback
[9]);
1248 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
1249 readback
[6], readback
[9]);
1253 gl_info
->fbo_ops
.glBindFramebuffer(GL_FRAMEBUFFER
, 0);
1254 gl_info
->fbo_ops
.glDeleteFramebuffers(1, &fbo
);
1255 glDeleteTextures(1, &tex
);
1256 glDeleteTextures(1, &buffer
);
1260 FIXME("Error during filtering test for format %x, returning no filtering\n", internal
);
1267 static void init_format_filter_info(struct wined3d_gl_info
*gl_info
, enum wined3d_pci_vendor vendor
)
1269 struct wined3d_format_desc
*desc
;
1270 unsigned int fmt_idx
, i
;
1271 WINED3DFORMAT fmts16
[] = {
1272 WINED3DFMT_R16_FLOAT
,
1273 WINED3DFMT_R16G16_FLOAT
,
1274 WINED3DFMT_R16G16B16A16_FLOAT
,
1278 if(wined3d_settings
.offscreen_rendering_mode
!= ORM_FBO
)
1280 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
1281 if (vendor
== HW_VENDOR_NVIDIA
&& gl_info
->supported
[ARB_TEXTURE_FLOAT
])
1283 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
1286 else if (gl_info
->limits
.glsl_varyings
> 44)
1288 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
1293 TRACE("Assuming no float16 blending\n");
1299 for(i
= 0; i
< (sizeof(fmts16
) / sizeof(*fmts16
)); i
++)
1301 fmt_idx
= getFmtIdx(fmts16
[i
]);
1302 gl_info
->gl_formats
[fmt_idx
].Flags
|= WINED3DFMT_FLAG_FILTERING
;
1308 for(i
= 0; i
< (sizeof(fmts16
) / sizeof(*fmts16
)); i
++)
1310 fmt_idx
= getFmtIdx(fmts16
[i
]);
1311 desc
= &gl_info
->gl_formats
[fmt_idx
];
1312 if(!desc
->glInternal
) continue; /* Not supported by GL */
1314 filtered
= check_filter(gl_info
, gl_info
->gl_formats
[fmt_idx
].glInternal
);
1317 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16
[i
]));
1318 desc
->Flags
|= WINED3DFMT_FLAG_FILTERING
;
1322 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16
[i
]));
1327 static void apply_format_fixups(struct wined3d_gl_info
*gl_info
)
1331 idx
= getFmtIdx(WINED3DFMT_R16_FLOAT
);
1332 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
1333 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_W
);
1335 idx
= getFmtIdx(WINED3DFMT_R32_FLOAT
);
1336 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
1337 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_W
);
1339 idx
= getFmtIdx(WINED3DFMT_R16G16_UNORM
);
1340 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
1341 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_W
);
1343 idx
= getFmtIdx(WINED3DFMT_R16G16_FLOAT
);
1344 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
1345 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_W
);
1347 idx
= getFmtIdx(WINED3DFMT_R32G32_FLOAT
);
1348 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
1349 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_W
);
1351 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
1352 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
1353 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
1354 * the only driver that implements it(fglrx) has a buggy implementation.
1356 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
1357 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
1358 * conversion for this format.
1360 if (!gl_info
->supported
[NV_TEXTURE_SHADER
])
1362 idx
= getFmtIdx(WINED3DFMT_R8G8_SNORM
);
1363 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
1364 1, CHANNEL_SOURCE_X
, 1, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
);
1365 idx
= getFmtIdx(WINED3DFMT_R16G16_SNORM
);
1366 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
1367 1, CHANNEL_SOURCE_X
, 1, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
);
1371 idx
= getFmtIdx(WINED3DFMT_R8G8_SNORM
);
1372 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
1373 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
);
1375 idx
= getFmtIdx(WINED3DFMT_R16G16_SNORM
);
1376 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
1377 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
);
1380 if (!gl_info
->supported
[NV_TEXTURE_SHADER
])
1382 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
1385 idx
= getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM
);
1386 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
1387 1, CHANNEL_SOURCE_X
, 1, CHANNEL_SOURCE_Z
, 0, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
);
1388 idx
= getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM
);
1389 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
1390 1, CHANNEL_SOURCE_X
, 1, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_Z
, 0, CHANNEL_SOURCE_W
);
1391 idx
= getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM
);
1392 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
1393 1, CHANNEL_SOURCE_X
, 1, CHANNEL_SOURCE_Y
, 1, CHANNEL_SOURCE_Z
, 1, CHANNEL_SOURCE_W
);
1397 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
1398 * are converted at surface loading time, but they do not need any modification in
1399 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
1400 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
1404 if (gl_info
->supported
[EXT_TEXTURE_COMPRESSION_RGTC
])
1406 idx
= getFmtIdx(WINED3DFMT_ATI2N
);
1407 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
1408 0, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
);
1410 else if (gl_info
->supported
[ATI_TEXTURE_COMPRESSION_3DC
])
1412 idx
= getFmtIdx(WINED3DFMT_ATI2N
);
1413 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
1414 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_W
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
);
1417 if (!gl_info
->supported
[APPLE_YCBCR_422
])
1419 idx
= getFmtIdx(WINED3DFMT_YUY2
);
1420 gl_info
->gl_formats
[idx
].color_fixup
= create_complex_fixup_desc(COMPLEX_FIXUP_YUY2
);
1422 idx
= getFmtIdx(WINED3DFMT_UYVY
);
1423 gl_info
->gl_formats
[idx
].color_fixup
= create_complex_fixup_desc(COMPLEX_FIXUP_UYVY
);
1426 idx
= getFmtIdx(WINED3DFMT_YV12
);
1427 gl_info
->gl_formats
[idx
].heightscale
= 1.5f
;
1428 gl_info
->gl_formats
[idx
].color_fixup
= create_complex_fixup_desc(COMPLEX_FIXUP_YV12
);
1430 if (gl_info
->supported
[EXT_PALETTED_TEXTURE
] || gl_info
->supported
[ARB_FRAGMENT_PROGRAM
])
1432 idx
= getFmtIdx(WINED3DFMT_P8_UINT
);
1433 gl_info
->gl_formats
[idx
].color_fixup
= create_complex_fixup_desc(COMPLEX_FIXUP_P8
);
1436 if (gl_info
->supported
[ARB_VERTEX_ARRAY_BGRA
])
1438 idx
= getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM
);
1439 gl_info
->gl_formats
[idx
].gl_vtx_format
= GL_BGRA
;
1442 if (gl_info
->supported
[ARB_HALF_FLOAT_VERTEX
])
1444 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
1445 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
1446 idx
= getFmtIdx(WINED3DFMT_R16G16_FLOAT
);
1447 gl_info
->gl_formats
[idx
].gl_vtx_type
= GL_HALF_FLOAT
; /* == GL_HALF_FLOAT_NV */
1449 idx
= getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT
);
1450 gl_info
->gl_formats
[idx
].gl_vtx_type
= GL_HALF_FLOAT
;
1454 static BOOL
init_format_vertex_info(struct wined3d_gl_info
*gl_info
)
1458 for (i
= 0; i
< (sizeof(format_vertex_info
) / sizeof(*format_vertex_info
)); ++i
)
1460 struct wined3d_format_desc
*format_desc
;
1461 int fmt_idx
= getFmtIdx(format_vertex_info
[i
].format
);
1465 ERR("Format %s (%#x) not found.\n",
1466 debug_d3dformat(format_vertex_info
[i
].format
), format_vertex_info
[i
].format
);
1470 format_desc
= &gl_info
->gl_formats
[fmt_idx
];
1471 format_desc
->emit_idx
= format_vertex_info
[i
].emit_idx
;
1472 format_desc
->component_count
= format_vertex_info
[i
].component_count
;
1473 format_desc
->gl_vtx_type
= format_vertex_info
[i
].gl_vtx_type
;
1474 format_desc
->gl_vtx_format
= format_vertex_info
[i
].gl_vtx_format
;
1475 format_desc
->gl_normalized
= format_vertex_info
[i
].gl_normalized
;
1476 format_desc
->component_size
= format_vertex_info
[i
].component_size
;
1482 BOOL
initPixelFormatsNoGL(struct wined3d_gl_info
*gl_info
)
1484 if (!init_format_base_info(gl_info
)) return FALSE
;
1486 if (!init_format_compression_info(gl_info
))
1488 HeapFree(GetProcessHeap(), 0, gl_info
->gl_formats
);
1489 gl_info
->gl_formats
= NULL
;
1496 /* Context activation is done by the caller. */
1497 BOOL
initPixelFormats(struct wined3d_gl_info
*gl_info
, enum wined3d_pci_vendor vendor
)
1499 if (!init_format_base_info(gl_info
)) return FALSE
;
1501 if (!init_format_compression_info(gl_info
)) goto fail
;
1502 if (!init_format_texture_info(gl_info
)) goto fail
;
1503 if (!init_format_vertex_info(gl_info
)) goto fail
;
1505 apply_format_fixups(gl_info
);
1506 init_format_fbo_compat_info(gl_info
);
1507 init_format_filter_info(gl_info
, vendor
);
1512 HeapFree(GetProcessHeap(), 0, gl_info
->gl_formats
);
1513 gl_info
->gl_formats
= NULL
;
1517 const struct wined3d_format_desc
*getFormatDescEntry(WINED3DFORMAT fmt
, const struct wined3d_gl_info
*gl_info
)
1519 int idx
= getFmtIdx(fmt
);
1522 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt
), fmt
);
1523 /* Get the caller a valid pointer */
1524 idx
= getFmtIdx(WINED3DFMT_UNKNOWN
);
1527 return &gl_info
->gl_formats
[idx
];
1530 /*****************************************************************************
1531 * Trace formatting of useful values
1533 const char* debug_d3dformat(WINED3DFORMAT fmt
) {
1535 #define FMT_TO_STR(fmt) case fmt: return #fmt
1536 FMT_TO_STR(WINED3DFMT_UNKNOWN
);
1537 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM
);
1538 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM
);
1539 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM
);
1540 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM
);
1541 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM
);
1542 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM
);
1543 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM
);
1544 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM
);
1545 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM
);
1546 FMT_TO_STR(WINED3DFMT_P8_UINT
);
1547 FMT_TO_STR(WINED3DFMT_L8_UNORM
);
1548 FMT_TO_STR(WINED3DFMT_L8A8_UNORM
);
1549 FMT_TO_STR(WINED3DFMT_L4A4_UNORM
);
1550 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM
);
1551 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM
);
1552 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM
);
1553 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM
);
1554 FMT_TO_STR(WINED3DFMT_UYVY
);
1555 FMT_TO_STR(WINED3DFMT_YUY2
);
1556 FMT_TO_STR(WINED3DFMT_YV12
);
1557 FMT_TO_STR(WINED3DFMT_DXT1
);
1558 FMT_TO_STR(WINED3DFMT_DXT2
);
1559 FMT_TO_STR(WINED3DFMT_DXT3
);
1560 FMT_TO_STR(WINED3DFMT_DXT4
);
1561 FMT_TO_STR(WINED3DFMT_DXT5
);
1562 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8
);
1563 FMT_TO_STR(WINED3DFMT_G8R8_G8B8
);
1564 FMT_TO_STR(WINED3DFMT_R8G8_B8G8
);
1565 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE
);
1566 FMT_TO_STR(WINED3DFMT_D32_UNORM
);
1567 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM
);
1568 FMT_TO_STR(WINED3DFMT_X8D24_UNORM
);
1569 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM
);
1570 FMT_TO_STR(WINED3DFMT_L16_UNORM
);
1571 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT
);
1572 FMT_TO_STR(WINED3DFMT_VERTEXDATA
);
1573 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx
);
1574 FMT_TO_STR(WINED3DFMT_ATI2N
);
1575 FMT_TO_STR(WINED3DFMT_NVHU
);
1576 FMT_TO_STR(WINED3DFMT_NVHS
);
1577 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS
);
1578 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT
);
1579 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT
);
1580 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT
);
1581 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS
);
1582 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT
);
1583 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT
);
1584 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT
);
1585 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS
);
1586 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT
);
1587 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM
);
1588 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT
);
1589 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM
);
1590 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT
);
1591 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS
);
1592 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT
);
1593 FMT_TO_STR(WINED3DFMT_R32G32_UINT
);
1594 FMT_TO_STR(WINED3DFMT_R32G32_SINT
);
1595 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS
);
1596 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT
);
1597 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS
);
1598 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT
);
1599 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS
);
1600 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM
);
1601 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT
);
1602 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM
);
1603 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT
);
1604 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS
);
1605 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM
);
1606 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB
);
1607 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT
);
1608 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM
);
1609 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT
);
1610 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS
);
1611 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT
);
1612 FMT_TO_STR(WINED3DFMT_R16G16_UNORM
);
1613 FMT_TO_STR(WINED3DFMT_R16G16_UINT
);
1614 FMT_TO_STR(WINED3DFMT_R16G16_SNORM
);
1615 FMT_TO_STR(WINED3DFMT_R16G16_SINT
);
1616 FMT_TO_STR(WINED3DFMT_R32_TYPELESS
);
1617 FMT_TO_STR(WINED3DFMT_D32_FLOAT
);
1618 FMT_TO_STR(WINED3DFMT_R32_FLOAT
);
1619 FMT_TO_STR(WINED3DFMT_R32_UINT
);
1620 FMT_TO_STR(WINED3DFMT_R32_SINT
);
1621 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS
);
1622 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT
);
1623 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS
);
1624 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT
);
1625 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS
);
1626 FMT_TO_STR(WINED3DFMT_R8G8_UNORM
);
1627 FMT_TO_STR(WINED3DFMT_R8G8_UINT
);
1628 FMT_TO_STR(WINED3DFMT_R8G8_SNORM
);
1629 FMT_TO_STR(WINED3DFMT_R8G8_SINT
);
1630 FMT_TO_STR(WINED3DFMT_R16_TYPELESS
);
1631 FMT_TO_STR(WINED3DFMT_R16_FLOAT
);
1632 FMT_TO_STR(WINED3DFMT_D16_UNORM
);
1633 FMT_TO_STR(WINED3DFMT_R16_UNORM
);
1634 FMT_TO_STR(WINED3DFMT_R16_UINT
);
1635 FMT_TO_STR(WINED3DFMT_R16_SNORM
);
1636 FMT_TO_STR(WINED3DFMT_R16_SINT
);
1637 FMT_TO_STR(WINED3DFMT_R8_TYPELESS
);
1638 FMT_TO_STR(WINED3DFMT_R8_UNORM
);
1639 FMT_TO_STR(WINED3DFMT_R8_UINT
);
1640 FMT_TO_STR(WINED3DFMT_R8_SNORM
);
1641 FMT_TO_STR(WINED3DFMT_R8_SINT
);
1642 FMT_TO_STR(WINED3DFMT_A8_UNORM
);
1643 FMT_TO_STR(WINED3DFMT_R1_UNORM
);
1644 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP
);
1645 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM
);
1646 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM
);
1647 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS
);
1648 FMT_TO_STR(WINED3DFMT_BC1_UNORM
);
1649 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB
);
1650 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS
);
1651 FMT_TO_STR(WINED3DFMT_BC2_UNORM
);
1652 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB
);
1653 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS
);
1654 FMT_TO_STR(WINED3DFMT_BC3_UNORM
);
1655 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB
);
1656 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS
);
1657 FMT_TO_STR(WINED3DFMT_BC4_UNORM
);
1658 FMT_TO_STR(WINED3DFMT_BC4_SNORM
);
1659 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS
);
1660 FMT_TO_STR(WINED3DFMT_BC5_UNORM
);
1661 FMT_TO_STR(WINED3DFMT_BC5_SNORM
);
1662 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM
);
1663 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM
);
1664 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM
);
1665 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM
);
1670 fourcc
[0] = (char)(fmt
);
1671 fourcc
[1] = (char)(fmt
>> 8);
1672 fourcc
[2] = (char)(fmt
>> 16);
1673 fourcc
[3] = (char)(fmt
>> 24);
1675 if( isprint(fourcc
[0]) && isprint(fourcc
[1]) && isprint(fourcc
[2]) && isprint(fourcc
[3]) )
1676 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt
, fourcc
);
1678 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt
);
1680 return "unrecognized";
1684 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype
) {
1686 #define DEVTYPE_TO_STR(dev) case dev: return #dev
1687 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL
);
1688 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF
);
1689 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW
);
1690 #undef DEVTYPE_TO_STR
1692 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype
);
1693 return "unrecognized";
1697 const char *debug_d3dusage(DWORD usage
)
1702 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
1703 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET
);
1704 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL
);
1705 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY
);
1706 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING
);
1707 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP
);
1708 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS
);
1709 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES
);
1710 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES
);
1711 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC
);
1712 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP
);
1713 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP
);
1714 #undef WINED3DUSAGE_TO_STR
1715 if (usage
) FIXME("Unrecognized usage flag(s) %#x\n", usage
);
1717 return buf
[0] ? wine_dbg_sprintf("%s", &buf
[3]) : "0";
1720 const char *debug_d3dusagequery(DWORD usagequery
)
1725 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
1726 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER
);
1727 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP
);
1728 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
);
1729 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD
);
1730 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE
);
1731 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE
);
1732 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP
);
1733 #undef WINED3DUSAGEQUERY_TO_STR
1734 if (usagequery
) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery
);
1736 return buf
[0] ? wine_dbg_sprintf("%s", &buf
[3]) : "0";
1739 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method
) {
1741 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
1742 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT
);
1743 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU
);
1744 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV
);
1745 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV
);
1746 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV
);
1747 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP
);
1748 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED
);
1749 #undef WINED3DDECLMETHOD_TO_STR
1751 FIXME("Unrecognized %u declaration method!\n", method
);
1752 return "unrecognized";
1756 const char* debug_d3ddeclusage(BYTE usage
) {
1758 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
1759 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION
);
1760 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT
);
1761 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES
);
1762 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL
);
1763 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE
);
1764 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD
);
1765 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT
);
1766 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL
);
1767 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR
);
1768 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT
);
1769 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR
);
1770 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG
);
1771 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH
);
1772 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE
);
1773 #undef WINED3DDECLUSAGE_TO_STR
1775 FIXME("Unrecognized %u declaration usage!\n", usage
);
1776 return "unrecognized";
1780 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res
) {
1782 #define RES_TO_STR(res) case res: return #res
1783 RES_TO_STR(WINED3DRTYPE_SURFACE
);
1784 RES_TO_STR(WINED3DRTYPE_VOLUME
);
1785 RES_TO_STR(WINED3DRTYPE_TEXTURE
);
1786 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE
);
1787 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE
);
1788 RES_TO_STR(WINED3DRTYPE_BUFFER
);
1791 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res
);
1792 return "unrecognized";
1796 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType
) {
1797 switch (PrimitiveType
) {
1798 #define PRIM_TO_STR(prim) case prim: return #prim
1799 PRIM_TO_STR(WINED3DPT_UNDEFINED
);
1800 PRIM_TO_STR(WINED3DPT_POINTLIST
);
1801 PRIM_TO_STR(WINED3DPT_LINELIST
);
1802 PRIM_TO_STR(WINED3DPT_LINESTRIP
);
1803 PRIM_TO_STR(WINED3DPT_TRIANGLELIST
);
1804 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP
);
1805 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN
);
1806 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ
);
1807 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ
);
1808 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ
);
1809 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ
);
1812 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType
);
1813 return "unrecognized";
1817 const char* debug_d3drenderstate(DWORD state
) {
1819 #define D3DSTATE_TO_STR(u) case u: return #u
1820 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS
);
1821 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE
);
1822 D3DSTATE_TO_STR(WINED3DRS_WRAPU
);
1823 D3DSTATE_TO_STR(WINED3DRS_WRAPV
);
1824 D3DSTATE_TO_STR(WINED3DRS_ZENABLE
);
1825 D3DSTATE_TO_STR(WINED3DRS_FILLMODE
);
1826 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE
);
1827 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN
);
1828 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE
);
1829 D3DSTATE_TO_STR(WINED3DRS_ROP2
);
1830 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK
);
1831 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE
);
1832 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE
);
1833 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL
);
1834 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND
);
1835 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND
);
1836 D3DSTATE_TO_STR(WINED3DRS_CULLMODE
);
1837 D3DSTATE_TO_STR(WINED3DRS_ZFUNC
);
1838 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF
);
1839 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC
);
1840 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE
);
1841 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE
);
1842 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE
);
1843 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE
);
1844 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE
);
1845 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL
);
1846 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX
);
1847 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA
);
1848 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR
);
1849 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE
);
1850 D3DSTATE_TO_STR(WINED3DRS_FOGSTART
);
1851 D3DSTATE_TO_STR(WINED3DRS_FOGEND
);
1852 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY
);
1853 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE
);
1854 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS
);
1855 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE
);
1856 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS
);
1857 D3DSTATE_TO_STR(WINED3DRS_ZBIAS
);
1858 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE
);
1859 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY
);
1860 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH
);
1861 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT
);
1862 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE
);
1863 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL
);
1864 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL
);
1865 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS
);
1866 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC
);
1867 D3DSTATE_TO_STR(WINED3DRS_STENCILREF
);
1868 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK
);
1869 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK
);
1870 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR
);
1871 D3DSTATE_TO_STR(WINED3DRS_WRAP0
);
1872 D3DSTATE_TO_STR(WINED3DRS_WRAP1
);
1873 D3DSTATE_TO_STR(WINED3DRS_WRAP2
);
1874 D3DSTATE_TO_STR(WINED3DRS_WRAP3
);
1875 D3DSTATE_TO_STR(WINED3DRS_WRAP4
);
1876 D3DSTATE_TO_STR(WINED3DRS_WRAP5
);
1877 D3DSTATE_TO_STR(WINED3DRS_WRAP6
);
1878 D3DSTATE_TO_STR(WINED3DRS_WRAP7
);
1879 D3DSTATE_TO_STR(WINED3DRS_CLIPPING
);
1880 D3DSTATE_TO_STR(WINED3DRS_LIGHTING
);
1881 D3DSTATE_TO_STR(WINED3DRS_EXTENTS
);
1882 D3DSTATE_TO_STR(WINED3DRS_AMBIENT
);
1883 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE
);
1884 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX
);
1885 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER
);
1886 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS
);
1887 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE
);
1888 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE
);
1889 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE
);
1890 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE
);
1891 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE
);
1892 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND
);
1893 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE
);
1894 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING
);
1895 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE
);
1896 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN
);
1897 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE
);
1898 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE
);
1899 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A
);
1900 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B
);
1901 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C
);
1902 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS
);
1903 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK
);
1904 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE
);
1905 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS
);
1906 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN
);
1907 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX
);
1908 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE
);
1909 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE
);
1910 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR
);
1911 D3DSTATE_TO_STR(WINED3DRS_BLENDOP
);
1912 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE
);
1913 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE
);
1914 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE
);
1915 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS
);
1916 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE
);
1917 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL
);
1918 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL
);
1919 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X
);
1920 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y
);
1921 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z
);
1922 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W
);
1923 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION
);
1924 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE
);
1925 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL
);
1926 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL
);
1927 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS
);
1928 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC
);
1929 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1
);
1930 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2
);
1931 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3
);
1932 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR
);
1933 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE
);
1934 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS
);
1935 D3DSTATE_TO_STR(WINED3DRS_WRAP8
);
1936 D3DSTATE_TO_STR(WINED3DRS_WRAP9
);
1937 D3DSTATE_TO_STR(WINED3DRS_WRAP10
);
1938 D3DSTATE_TO_STR(WINED3DRS_WRAP11
);
1939 D3DSTATE_TO_STR(WINED3DRS_WRAP12
);
1940 D3DSTATE_TO_STR(WINED3DRS_WRAP13
);
1941 D3DSTATE_TO_STR(WINED3DRS_WRAP14
);
1942 D3DSTATE_TO_STR(WINED3DRS_WRAP15
);
1943 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE
);
1944 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA
);
1945 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA
);
1946 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA
);
1947 #undef D3DSTATE_TO_STR
1949 FIXME("Unrecognized %u render state!\n", state
);
1950 return "unrecognized";
1954 const char* debug_d3dsamplerstate(DWORD state
) {
1956 #define D3DSTATE_TO_STR(u) case u: return #u
1957 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR
);
1958 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU
);
1959 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV
);
1960 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW
);
1961 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER
);
1962 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER
);
1963 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER
);
1964 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS
);
1965 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL
);
1966 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY
);
1967 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE
);
1968 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX
);
1969 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET
);
1970 #undef D3DSTATE_TO_STR
1972 FIXME("Unrecognized %u sampler state!\n", state
);
1973 return "unrecognized";
1977 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type
) {
1978 switch (filter_type
) {
1979 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1980 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE
);
1981 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT
);
1982 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR
);
1983 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC
);
1984 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC
);
1985 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC
);
1986 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD
);
1987 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD
);
1988 #undef D3DTEXTUREFILTERTYPE_TO_STR
1990 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type
);
1991 return "unrecognized";
1995 const char* debug_d3dtexturestate(DWORD state
) {
1997 #define D3DSTATE_TO_STR(u) case u: return #u
1998 D3DSTATE_TO_STR(WINED3DTSS_COLOROP
);
1999 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1
);
2000 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2
);
2001 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP
);
2002 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1
);
2003 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2
);
2004 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00
);
2005 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01
);
2006 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10
);
2007 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11
);
2008 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX
);
2009 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE
);
2010 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET
);
2011 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS
);
2012 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0
);
2013 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0
);
2014 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG
);
2015 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT
);
2016 #undef D3DSTATE_TO_STR
2018 FIXME("Unrecognized %u texture state!\n", state
);
2019 return "unrecognized";
2023 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop
) {
2025 #define D3DTOP_TO_STR(u) case u: return #u
2026 D3DTOP_TO_STR(WINED3DTOP_DISABLE
);
2027 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1
);
2028 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2
);
2029 D3DTOP_TO_STR(WINED3DTOP_MODULATE
);
2030 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X
);
2031 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X
);
2032 D3DTOP_TO_STR(WINED3DTOP_ADD
);
2033 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED
);
2034 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X
);
2035 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT
);
2036 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH
);
2037 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA
);
2038 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA
);
2039 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA
);
2040 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM
);
2041 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA
);
2042 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE
);
2043 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR
);
2044 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA
);
2045 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR
);
2046 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA
);
2047 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP
);
2048 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE
);
2049 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3
);
2050 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD
);
2051 D3DTOP_TO_STR(WINED3DTOP_LERP
);
2052 #undef D3DTOP_TO_STR
2054 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop
);
2055 return "unrecognized";
2059 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype
) {
2061 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
2062 TSTYPE_TO_STR(WINED3DTS_VIEW
);
2063 TSTYPE_TO_STR(WINED3DTS_PROJECTION
);
2064 TSTYPE_TO_STR(WINED3DTS_TEXTURE0
);
2065 TSTYPE_TO_STR(WINED3DTS_TEXTURE1
);
2066 TSTYPE_TO_STR(WINED3DTS_TEXTURE2
);
2067 TSTYPE_TO_STR(WINED3DTS_TEXTURE3
);
2068 TSTYPE_TO_STR(WINED3DTS_TEXTURE4
);
2069 TSTYPE_TO_STR(WINED3DTS_TEXTURE5
);
2070 TSTYPE_TO_STR(WINED3DTS_TEXTURE6
);
2071 TSTYPE_TO_STR(WINED3DTS_TEXTURE7
);
2072 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
2073 #undef TSTYPE_TO_STR
2075 if (tstype
> 256 && tstype
< 512) {
2076 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype
);
2077 return ("WINED3DTS_WORLDMATRIX > 0");
2079 FIXME("Unrecognized %u WINED3DTS\n", tstype
);
2080 return "unrecognized";
2084 const char *debug_d3dstate(DWORD state
)
2086 if (STATE_IS_RENDER(state
))
2087 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state
- STATE_RENDER(0)));
2088 if (STATE_IS_TEXTURESTAGE(state
))
2090 DWORD texture_stage
= (state
- STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE
+ 1);
2091 DWORD texture_state
= state
- STATE_TEXTURESTAGE(texture_stage
, 0);
2092 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
2093 texture_stage
, debug_d3dtexturestate(texture_state
));
2095 if (STATE_IS_SAMPLER(state
))
2096 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state
- STATE_SAMPLER(0));
2097 if (STATE_IS_PIXELSHADER(state
))
2098 return "STATE_PIXELSHADER";
2099 if (STATE_IS_TRANSFORM(state
))
2100 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state
- STATE_TRANSFORM(0)));
2101 if (STATE_IS_STREAMSRC(state
))
2102 return "STATE_STREAMSRC";
2103 if (STATE_IS_INDEXBUFFER(state
))
2104 return "STATE_INDEXBUFFER";
2105 if (STATE_IS_VDECL(state
))
2106 return "STATE_VDECL";
2107 if (STATE_IS_VSHADER(state
))
2108 return "STATE_VSHADER";
2109 if (STATE_IS_VIEWPORT(state
))
2110 return "STATE_VIEWPORT";
2111 if (STATE_IS_VERTEXSHADERCONSTANT(state
))
2112 return "STATE_VERTEXSHADERCONSTANT";
2113 if (STATE_IS_PIXELSHADERCONSTANT(state
))
2114 return "STATE_PIXELSHADERCONSTANT";
2115 if (STATE_IS_ACTIVELIGHT(state
))
2116 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state
- STATE_ACTIVELIGHT(0));
2117 if (STATE_IS_SCISSORRECT(state
))
2118 return "STATE_SCISSORRECT";
2119 if (STATE_IS_CLIPPLANE(state
))
2120 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state
- STATE_CLIPPLANE(0));
2121 if (STATE_IS_MATERIAL(state
))
2122 return "STATE_MATERIAL";
2123 if (STATE_IS_FRONTFACE(state
))
2124 return "STATE_FRONTFACE";
2126 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state
);
2129 const char* debug_d3dpool(WINED3DPOOL Pool
) {
2131 #define POOL_TO_STR(p) case p: return #p
2132 POOL_TO_STR(WINED3DPOOL_DEFAULT
);
2133 POOL_TO_STR(WINED3DPOOL_MANAGED
);
2134 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM
);
2135 POOL_TO_STR(WINED3DPOOL_SCRATCH
);
2138 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool
);
2139 return "unrecognized";
2143 const char *debug_fbostatus(GLenum status
) {
2145 #define FBOSTATUS_TO_STR(u) case u: return #u
2146 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE
);
2147 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
);
2148 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
);
2149 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
);
2150 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
);
2151 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER
);
2152 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER
);
2153 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
);
2154 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED
);
2155 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED
);
2156 #undef FBOSTATUS_TO_STR
2158 FIXME("Unrecognied FBO status 0x%08x\n", status
);
2159 return "unrecognized";
2163 const char *debug_glerror(GLenum error
) {
2165 #define GLERROR_TO_STR(u) case u: return #u
2166 GLERROR_TO_STR(GL_NO_ERROR
);
2167 GLERROR_TO_STR(GL_INVALID_ENUM
);
2168 GLERROR_TO_STR(GL_INVALID_VALUE
);
2169 GLERROR_TO_STR(GL_INVALID_OPERATION
);
2170 GLERROR_TO_STR(GL_STACK_OVERFLOW
);
2171 GLERROR_TO_STR(GL_STACK_UNDERFLOW
);
2172 GLERROR_TO_STR(GL_OUT_OF_MEMORY
);
2173 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION
);
2174 #undef GLERROR_TO_STR
2176 FIXME("Unrecognied GL error 0x%08x\n", error
);
2177 return "unrecognized";
2181 const char *debug_d3dbasis(WINED3DBASISTYPE basis
) {
2183 case WINED3DBASIS_BEZIER
: return "WINED3DBASIS_BEZIER";
2184 case WINED3DBASIS_BSPLINE
: return "WINED3DBASIS_BSPLINE";
2185 case WINED3DBASIS_INTERPOLATE
: return "WINED3DBASIS_INTERPOLATE";
2186 default: return "unrecognized";
2190 const char *debug_d3ddegree(WINED3DDEGREETYPE degree
) {
2192 case WINED3DDEGREE_LINEAR
: return "WINED3DDEGREE_LINEAR";
2193 case WINED3DDEGREE_QUADRATIC
: return "WINED3DDEGREE_QUADRATIC";
2194 case WINED3DDEGREE_CUBIC
: return "WINED3DDEGREE_CUBIC";
2195 case WINED3DDEGREE_QUINTIC
: return "WINED3DDEGREE_QUINTIC";
2196 default: return "unrecognized";
2200 static const char *debug_fixup_channel_source(enum fixup_channel_source source
)
2204 #define WINED3D_TO_STR(x) case x: return #x
2205 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO
);
2206 WINED3D_TO_STR(CHANNEL_SOURCE_ONE
);
2207 WINED3D_TO_STR(CHANNEL_SOURCE_X
);
2208 WINED3D_TO_STR(CHANNEL_SOURCE_Y
);
2209 WINED3D_TO_STR(CHANNEL_SOURCE_Z
);
2210 WINED3D_TO_STR(CHANNEL_SOURCE_W
);
2211 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0
);
2212 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1
);
2213 #undef WINED3D_TO_STR
2215 FIXME("Unrecognized fixup_channel_source %#x\n", source
);
2216 return "unrecognized";
2220 static const char *debug_complex_fixup(enum complex_fixup fixup
)
2224 #define WINED3D_TO_STR(x) case x: return #x
2225 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2
);
2226 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY
);
2227 WINED3D_TO_STR(COMPLEX_FIXUP_YV12
);
2228 WINED3D_TO_STR(COMPLEX_FIXUP_P8
);
2229 #undef WINED3D_TO_STR
2231 FIXME("Unrecognized complex fixup %#x\n", fixup
);
2232 return "unrecognized";
2236 void dump_color_fixup_desc(struct color_fixup_desc fixup
)
2238 if (is_complex_fixup(fixup
))
2240 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup
)));
2244 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup
.x_source
), fixup
.x_sign_fixup
? ", SIGN_FIXUP" : "");
2245 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup
.y_source
), fixup
.y_sign_fixup
? ", SIGN_FIXUP" : "");
2246 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup
.z_source
), fixup
.z_sign_fixup
? ", SIGN_FIXUP" : "");
2247 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup
.w_source
), fixup
.w_sign_fixup
? ", SIGN_FIXUP" : "");
2250 const char *debug_surflocation(DWORD flag
) {
2254 if(flag
& SFLAG_INSYSMEM
) strcat(buf
, " | SFLAG_INSYSMEM");
2255 if(flag
& SFLAG_INDRAWABLE
) strcat(buf
, " | SFLAG_INDRAWABLE");
2256 if(flag
& SFLAG_INTEXTURE
) strcat(buf
, " | SFLAG_INTEXTURE");
2257 if(flag
& SFLAG_INSRGBTEX
) strcat(buf
, " | SFLAG_INSRGBTEX");
2258 return wine_dbg_sprintf("%s", buf
[0] ? buf
+ 3 : "0");
2261 /*****************************************************************************
2262 * Useful functions mapping GL <-> D3D values
2264 GLenum
StencilOp(DWORD op
) {
2266 case WINED3DSTENCILOP_KEEP
: return GL_KEEP
;
2267 case WINED3DSTENCILOP_ZERO
: return GL_ZERO
;
2268 case WINED3DSTENCILOP_REPLACE
: return GL_REPLACE
;
2269 case WINED3DSTENCILOP_INCRSAT
: return GL_INCR
;
2270 case WINED3DSTENCILOP_DECRSAT
: return GL_DECR
;
2271 case WINED3DSTENCILOP_INVERT
: return GL_INVERT
;
2272 case WINED3DSTENCILOP_INCR
: return GL_INCR_WRAP_EXT
;
2273 case WINED3DSTENCILOP_DECR
: return GL_DECR_WRAP_EXT
;
2275 FIXME("Unrecognized stencil op %d\n", op
);
2280 GLenum
CompareFunc(DWORD func
) {
2281 switch ((WINED3DCMPFUNC
)func
) {
2282 case WINED3DCMP_NEVER
: return GL_NEVER
;
2283 case WINED3DCMP_LESS
: return GL_LESS
;
2284 case WINED3DCMP_EQUAL
: return GL_EQUAL
;
2285 case WINED3DCMP_LESSEQUAL
: return GL_LEQUAL
;
2286 case WINED3DCMP_GREATER
: return GL_GREATER
;
2287 case WINED3DCMP_NOTEQUAL
: return GL_NOTEQUAL
;
2288 case WINED3DCMP_GREATEREQUAL
: return GL_GEQUAL
;
2289 case WINED3DCMP_ALWAYS
: return GL_ALWAYS
;
2291 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func
);
2296 BOOL
is_invalid_op(IWineD3DDeviceImpl
*This
, int stage
, WINED3DTEXTUREOP op
, DWORD arg1
, DWORD arg2
, DWORD arg3
) {
2297 if (op
== WINED3DTOP_DISABLE
) return FALSE
;
2298 if (This
->stateBlock
->textures
[stage
]) return FALSE
;
2300 if ((arg1
& WINED3DTA_SELECTMASK
) == WINED3DTA_TEXTURE
2301 && op
!= WINED3DTOP_SELECTARG2
) return TRUE
;
2302 if ((arg2
& WINED3DTA_SELECTMASK
) == WINED3DTA_TEXTURE
2303 && op
!= WINED3DTOP_SELECTARG1
) return TRUE
;
2304 if ((arg3
& WINED3DTA_SELECTMASK
) == WINED3DTA_TEXTURE
2305 && (op
== WINED3DTOP_MULTIPLYADD
|| op
== WINED3DTOP_LERP
)) return TRUE
;
2310 /* Setup this textures matrix according to the texture flags*/
2311 /* GL locking is done by the caller (state handler) */
2312 void set_texture_matrix(const float *smat
, DWORD flags
, BOOL calculatedCoords
, BOOL transformed
,
2313 WINED3DFORMAT vtx_fmt
, BOOL ffp_proj_control
)
2317 glMatrixMode(GL_TEXTURE
);
2318 checkGLcall("glMatrixMode(GL_TEXTURE)");
2320 if (flags
== WINED3DTTFF_DISABLE
|| flags
== WINED3DTTFF_COUNT1
|| transformed
) {
2322 checkGLcall("glLoadIdentity()");
2326 if (flags
== (WINED3DTTFF_COUNT1
|WINED3DTTFF_PROJECTED
)) {
2327 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2331 memcpy(mat
, smat
, 16 * sizeof(float));
2333 if (flags
& WINED3DTTFF_PROJECTED
) {
2334 if(!ffp_proj_control
) {
2335 switch (flags
& ~WINED3DTTFF_PROJECTED
) {
2336 case WINED3DTTFF_COUNT2
:
2337 mat
[3] = mat
[1], mat
[7] = mat
[5], mat
[11] = mat
[9], mat
[15] = mat
[13];
2338 mat
[1] = mat
[5] = mat
[9] = mat
[13] = 0;
2340 case WINED3DTTFF_COUNT3
:
2341 mat
[3] = mat
[2], mat
[7] = mat
[6], mat
[11] = mat
[10], mat
[15] = mat
[14];
2342 mat
[2] = mat
[6] = mat
[10] = mat
[14] = 0;
2346 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2347 if(!calculatedCoords
) {
2350 case WINED3DFMT_R32_FLOAT
:
2351 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2352 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2353 * the input value to the transformation will be 0, so the matrix value is irrelevant
2360 case WINED3DFMT_R32G32_FLOAT
:
2361 /* See above, just 3rd and 4th coord
2368 case WINED3DFMT_R32G32B32_FLOAT
: /* Opengl defaults match dx defaults */
2369 case WINED3DFMT_R32G32B32A32_FLOAT
: /* No defaults apply, all app defined */
2371 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2372 * into a bad place. The division elimination below will apply to make sure the
2373 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2375 case WINED3DFMT_UNKNOWN
: /* No texture coords, 0/0/0/1 defaults are passed */
2378 FIXME("Unexpected fixed function texture coord input\n");
2381 if(!ffp_proj_control
) {
2382 switch (flags
& ~WINED3DTTFF_PROJECTED
) {
2383 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2384 case WINED3DTTFF_COUNT2
: mat
[2] = mat
[6] = mat
[10] = mat
[14] = 0;
2385 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2386 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2387 * the 4th coord evaluates to 1.0 to eliminate that.
2389 * If the fixed function pipeline is used, the 4th value remains unused,
2390 * so there is no danger in doing this. With vertex shaders we have a
2391 * problem. Should an app hit that problem, the code here would have to
2392 * check for pixel shaders, and the shader has to undo the default gl divide.
2394 * A more serious problem occurs if the app passes 4 coordinates in, and the
2395 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2396 * or a replacement shader
2398 default: mat
[3] = mat
[7] = mat
[11] = 0; mat
[15] = 1;
2404 checkGLcall("glLoadMatrixf(mat)");
2407 /* This small helper function is used to convert a bitmask into the number of masked bits */
2408 unsigned int count_bits(unsigned int mask
)
2411 for (count
= 0; mask
; ++count
)
2418 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2419 * The later function requires individual color components. */
2420 BOOL
getColorBits(const struct wined3d_format_desc
*format_desc
,
2421 short *redSize
, short *greenSize
, short *blueSize
, short *alphaSize
, short *totalSize
)
2423 TRACE("fmt: %s\n", debug_d3dformat(format_desc
->format
));
2424 switch(format_desc
->format
)
2426 case WINED3DFMT_B8G8R8X8_UNORM
:
2427 case WINED3DFMT_B8G8R8_UNORM
:
2428 case WINED3DFMT_B8G8R8A8_UNORM
:
2429 case WINED3DFMT_R8G8B8A8_UNORM
:
2430 case WINED3DFMT_B10G10R10A2_UNORM
:
2431 case WINED3DFMT_B5G5R5X1_UNORM
:
2432 case WINED3DFMT_B5G5R5A1_UNORM
:
2433 case WINED3DFMT_B5G6R5_UNORM
:
2434 case WINED3DFMT_B4G4R4X4_UNORM
:
2435 case WINED3DFMT_B4G4R4A4_UNORM
:
2436 case WINED3DFMT_B2G3R3_UNORM
:
2437 case WINED3DFMT_P8_UINT_A8_UNORM
:
2438 case WINED3DFMT_P8_UINT
:
2441 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc
->format
));
2445 *redSize
= count_bits(format_desc
->red_mask
);
2446 *greenSize
= count_bits(format_desc
->green_mask
);
2447 *blueSize
= count_bits(format_desc
->blue_mask
);
2448 *alphaSize
= count_bits(format_desc
->alpha_mask
);
2449 *totalSize
= *redSize
+ *greenSize
+ *blueSize
+ *alphaSize
;
2451 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
2452 *redSize
, *greenSize
, *blueSize
, *alphaSize
, *totalSize
, debug_d3dformat(format_desc
->format
));
2456 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2457 BOOL
getDepthStencilBits(const struct wined3d_format_desc
*format_desc
, short *depthSize
, short *stencilSize
)
2459 TRACE("fmt: %s\n", debug_d3dformat(format_desc
->format
));
2460 switch(format_desc
->format
)
2462 case WINED3DFMT_D16_LOCKABLE
:
2463 case WINED3DFMT_D16_UNORM
:
2464 case WINED3DFMT_S1_UINT_D15_UNORM
:
2465 case WINED3DFMT_X8D24_UNORM
:
2466 case WINED3DFMT_S4X4_UINT_D24_UNORM
:
2467 case WINED3DFMT_D24_UNORM_S8_UINT
:
2468 case WINED3DFMT_S8_UINT_D24_FLOAT
:
2469 case WINED3DFMT_D32_UNORM
:
2470 case WINED3DFMT_D32_FLOAT
:
2473 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc
->format
));
2477 *depthSize
= format_desc
->depth_size
;
2478 *stencilSize
= format_desc
->stencil_size
;
2480 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
2481 *depthSize
, *stencilSize
, debug_d3dformat(format_desc
->format
));
2485 DWORD
color_convert_argb_to_fmt(DWORD color
, WINED3DFORMAT destfmt
)
2487 unsigned int r
, g
, b
, a
;
2490 if (destfmt
== WINED3DFMT_B8G8R8A8_UNORM
2491 || destfmt
== WINED3DFMT_B8G8R8X8_UNORM
2492 || destfmt
== WINED3DFMT_B8G8R8_UNORM
)
2495 TRACE("Converting color %08x to format %s\n", color
, debug_d3dformat(destfmt
));
2497 a
= (color
& 0xff000000) >> 24;
2498 r
= (color
& 0x00ff0000) >> 16;
2499 g
= (color
& 0x0000ff00) >> 8;
2500 b
= (color
& 0x000000ff) >> 0;
2504 case WINED3DFMT_B5G6R5_UNORM
:
2505 if(r
== 0xff && g
== 0xff && b
== 0xff) return 0xffff;
2512 TRACE("Returning %08x\n", ret
);
2515 case WINED3DFMT_B5G5R5X1_UNORM
:
2516 case WINED3DFMT_B5G5R5A1_UNORM
:
2525 TRACE("Returning %08x\n", ret
);
2528 case WINED3DFMT_A8_UNORM
:
2529 TRACE("Returning %08x\n", a
);
2532 case WINED3DFMT_B4G4R4X4_UNORM
:
2533 case WINED3DFMT_B4G4R4A4_UNORM
:
2542 TRACE("Returning %08x\n", ret
);
2545 case WINED3DFMT_B2G3R3_UNORM
:
2552 TRACE("Returning %08x\n", ret
);
2555 case WINED3DFMT_R8G8B8X8_UNORM
:
2556 case WINED3DFMT_R8G8B8A8_UNORM
:
2561 TRACE("Returning %08x\n", ret
);
2564 case WINED3DFMT_B10G10R10A2_UNORM
:
2566 r
= (r
* 1024) / 256;
2567 g
= (g
* 1024) / 256;
2568 b
= (b
* 1024) / 256;
2573 TRACE("Returning %08x\n", ret
);
2576 case WINED3DFMT_R10G10B10A2_UNORM
:
2578 r
= (r
* 1024) / 256;
2579 g
= (g
* 1024) / 256;
2580 b
= (b
* 1024) / 256;
2585 TRACE("Returning %08x\n", ret
);
2589 FIXME("Add a COLORFILL conversion for format %s\n", debug_d3dformat(destfmt
));
2594 /* DirectDraw stuff */
2595 WINED3DFORMAT
pixelformat_for_depth(DWORD depth
) {
2597 case 8: return WINED3DFMT_P8_UINT
;
2598 case 15: return WINED3DFMT_B5G5R5X1_UNORM
;
2599 case 16: return WINED3DFMT_B5G6R5_UNORM
;
2600 case 24: return WINED3DFMT_B8G8R8X8_UNORM
; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
2601 case 32: return WINED3DFMT_B8G8R8X8_UNORM
; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
2602 default: return WINED3DFMT_UNKNOWN
;
2606 void multiply_matrix(WINED3DMATRIX
*dest
, const WINED3DMATRIX
*src1
, const WINED3DMATRIX
*src2
) {
2609 /* Now do the multiplication 'by hand'.
2610 I know that all this could be optimised, but this will be done later :-) */
2611 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
);
2612 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
);
2613 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
);
2614 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
);
2616 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
);
2617 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
);
2618 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
);
2619 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
);
2621 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
);
2622 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
);
2623 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
);
2624 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
);
2626 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
);
2627 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
);
2628 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
);
2629 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
);
2631 /* And copy the new matrix in the good storage.. */
2632 memcpy(dest
, &temp
, 16 * sizeof(float));
2635 DWORD
get_flexible_vertex_size(DWORD d3dvtVertexType
) {
2638 int numTextures
= (d3dvtVertexType
& WINED3DFVF_TEXCOUNT_MASK
) >> WINED3DFVF_TEXCOUNT_SHIFT
;
2640 if (d3dvtVertexType
& WINED3DFVF_NORMAL
) size
+= 3 * sizeof(float);
2641 if (d3dvtVertexType
& WINED3DFVF_DIFFUSE
) size
+= sizeof(DWORD
);
2642 if (d3dvtVertexType
& WINED3DFVF_SPECULAR
) size
+= sizeof(DWORD
);
2643 if (d3dvtVertexType
& WINED3DFVF_PSIZE
) size
+= sizeof(DWORD
);
2644 switch (d3dvtVertexType
& WINED3DFVF_POSITION_MASK
) {
2645 case WINED3DFVF_XYZ
: size
+= 3 * sizeof(float); break;
2646 case WINED3DFVF_XYZRHW
: size
+= 4 * sizeof(float); break;
2647 case WINED3DFVF_XYZB1
: size
+= 4 * sizeof(float); break;
2648 case WINED3DFVF_XYZB2
: size
+= 5 * sizeof(float); break;
2649 case WINED3DFVF_XYZB3
: size
+= 6 * sizeof(float); break;
2650 case WINED3DFVF_XYZB4
: size
+= 7 * sizeof(float); break;
2651 case WINED3DFVF_XYZB5
: size
+= 8 * sizeof(float); break;
2652 case WINED3DFVF_XYZW
: size
+= 4 * sizeof(float); break;
2653 default: ERR("Unexpected position mask\n");
2655 for (i
= 0; i
< numTextures
; i
++) {
2656 size
+= GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType
, i
) * sizeof(float);
2662 void gen_ffp_frag_op(IWineD3DStateBlockImpl
*stateblock
, struct ffp_frag_settings
*settings
, BOOL ignore_textype
) {
2666 static const unsigned char args
[WINED3DTOP_LERP
+ 1] = {
2668 /* D3DTOP_DISABLE */ 0,
2669 /* D3DTOP_SELECTARG1 */ ARG1
,
2670 /* D3DTOP_SELECTARG2 */ ARG2
,
2671 /* D3DTOP_MODULATE */ ARG1
| ARG2
,
2672 /* D3DTOP_MODULATE2X */ ARG1
| ARG2
,
2673 /* D3DTOP_MODULATE4X */ ARG1
| ARG2
,
2674 /* D3DTOP_ADD */ ARG1
| ARG2
,
2675 /* D3DTOP_ADDSIGNED */ ARG1
| ARG2
,
2676 /* D3DTOP_ADDSIGNED2X */ ARG1
| ARG2
,
2677 /* D3DTOP_SUBTRACT */ ARG1
| ARG2
,
2678 /* D3DTOP_ADDSMOOTH */ ARG1
| ARG2
,
2679 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1
| ARG2
,
2680 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1
| ARG2
,
2681 /* D3DTOP_BLENDFACTORALPHA */ ARG1
| ARG2
,
2682 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1
| ARG2
,
2683 /* D3DTOP_BLENDCURRENTALPHA */ ARG1
| ARG2
,
2684 /* D3DTOP_PREMODULATE */ ARG1
| ARG2
,
2685 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1
| ARG2
,
2686 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1
| ARG2
,
2687 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1
| ARG2
,
2688 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1
| ARG2
,
2689 /* D3DTOP_BUMPENVMAP */ ARG1
| ARG2
,
2690 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1
| ARG2
,
2691 /* D3DTOP_DOTPRODUCT3 */ ARG1
| ARG2
,
2692 /* D3DTOP_MULTIPLYADD */ ARG1
| ARG2
| ARG0
,
2693 /* D3DTOP_LERP */ ARG1
| ARG2
| ARG0
2697 DWORD cop
, aop
, carg0
, carg1
, carg2
, aarg0
, aarg1
, aarg2
;
2698 IWineD3DDeviceImpl
*device
= stateblock
->device
;
2699 const struct wined3d_gl_info
*gl_info
= &device
->adapter
->gl_info
;
2701 for (i
= 0; i
< gl_info
->limits
.texture_stages
; ++i
)
2703 IWineD3DBaseTextureImpl
*texture
;
2704 settings
->op
[i
].padding
= 0;
2705 if(stateblock
->textureState
[i
][WINED3DTSS_COLOROP
] == WINED3DTOP_DISABLE
) {
2706 settings
->op
[i
].cop
= WINED3DTOP_DISABLE
;
2707 settings
->op
[i
].aop
= WINED3DTOP_DISABLE
;
2708 settings
->op
[i
].carg0
= settings
->op
[i
].carg1
= settings
->op
[i
].carg2
= ARG_UNUSED
;
2709 settings
->op
[i
].aarg0
= settings
->op
[i
].aarg1
= settings
->op
[i
].aarg2
= ARG_UNUSED
;
2710 settings
->op
[i
].color_fixup
= COLOR_FIXUP_IDENTITY
;
2711 settings
->op
[i
].dst
= resultreg
;
2712 settings
->op
[i
].tex_type
= tex_1d
;
2713 settings
->op
[i
].projected
= proj_none
;
2718 texture
= (IWineD3DBaseTextureImpl
*) stateblock
->textures
[i
];
2720 settings
->op
[i
].color_fixup
= texture
->resource
.format_desc
->color_fixup
;
2721 if(ignore_textype
) {
2722 settings
->op
[i
].tex_type
= tex_1d
;
2724 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture
*)texture
)) {
2726 settings
->op
[i
].tex_type
= tex_1d
;
2729 settings
->op
[i
].tex_type
= tex_2d
;
2732 settings
->op
[i
].tex_type
= tex_3d
;
2734 case GL_TEXTURE_CUBE_MAP_ARB
:
2735 settings
->op
[i
].tex_type
= tex_cube
;
2737 case GL_TEXTURE_RECTANGLE_ARB
:
2738 settings
->op
[i
].tex_type
= tex_rect
;
2743 settings
->op
[i
].color_fixup
= COLOR_FIXUP_IDENTITY
;
2744 settings
->op
[i
].tex_type
= tex_1d
;
2747 cop
= stateblock
->textureState
[i
][WINED3DTSS_COLOROP
];
2748 aop
= stateblock
->textureState
[i
][WINED3DTSS_ALPHAOP
];
2750 carg1
= (args
[cop
] & ARG1
) ? stateblock
->textureState
[i
][WINED3DTSS_COLORARG1
] : ARG_UNUSED
;
2751 carg2
= (args
[cop
] & ARG2
) ? stateblock
->textureState
[i
][WINED3DTSS_COLORARG2
] : ARG_UNUSED
;
2752 carg0
= (args
[cop
] & ARG0
) ? stateblock
->textureState
[i
][WINED3DTSS_COLORARG0
] : ARG_UNUSED
;
2754 if(is_invalid_op(device
, i
, cop
, carg1
, carg2
, carg0
)) {
2757 carg1
= WINED3DTA_CURRENT
;
2758 cop
= WINED3DTOP_SELECTARG1
;
2761 if(cop
== WINED3DTOP_DOTPRODUCT3
) {
2762 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2763 * the color result to the alpha component of the destination
2770 aarg1
= (args
[aop
] & ARG1
) ? stateblock
->textureState
[i
][WINED3DTSS_ALPHAARG1
] : ARG_UNUSED
;
2771 aarg2
= (args
[aop
] & ARG2
) ? stateblock
->textureState
[i
][WINED3DTSS_ALPHAARG2
] : ARG_UNUSED
;
2772 aarg0
= (args
[aop
] & ARG0
) ? stateblock
->textureState
[i
][WINED3DTSS_ALPHAARG0
] : ARG_UNUSED
;
2775 if (i
== 0 && stateblock
->textures
[0] && stateblock
->renderState
[WINED3DRS_COLORKEYENABLE
])
2777 UINT texture_dimensions
= IWineD3DBaseTexture_GetTextureDimensions(stateblock
->textures
[0]);
2779 if (texture_dimensions
== GL_TEXTURE_2D
|| texture_dimensions
== GL_TEXTURE_RECTANGLE_ARB
)
2781 IWineD3DBaseTextureImpl
*texture
= (IWineD3DBaseTextureImpl
*)stateblock
->textures
[0];
2782 IWineD3DSurfaceImpl
*surf
= (IWineD3DSurfaceImpl
*)texture
->baseTexture
.sub_resources
[0];
2784 if (surf
->CKeyFlags
& WINEDDSD_CKSRCBLT
&& !surf
->resource
.format_desc
->alpha_mask
)
2786 if (aop
== WINED3DTOP_DISABLE
)
2788 aarg1
= WINED3DTA_TEXTURE
;
2789 aop
= WINED3DTOP_SELECTARG1
;
2791 else if (aop
== WINED3DTOP_SELECTARG1
&& aarg1
!= WINED3DTA_TEXTURE
)
2793 if (stateblock
->renderState
[WINED3DRS_ALPHABLENDENABLE
])
2795 aarg2
= WINED3DTA_TEXTURE
;
2796 aop
= WINED3DTOP_MODULATE
;
2798 else aarg1
= WINED3DTA_TEXTURE
;
2800 else if (aop
== WINED3DTOP_SELECTARG2
&& aarg2
!= WINED3DTA_TEXTURE
)
2802 if (stateblock
->renderState
[WINED3DRS_ALPHABLENDENABLE
])
2804 aarg1
= WINED3DTA_TEXTURE
;
2805 aop
= WINED3DTOP_MODULATE
;
2807 else aarg2
= WINED3DTA_TEXTURE
;
2813 if(is_invalid_op(device
, i
, aop
, aarg1
, aarg2
, aarg0
)) {
2816 aarg1
= WINED3DTA_CURRENT
;
2817 aop
= WINED3DTOP_SELECTARG1
;
2820 if(carg1
== WINED3DTA_TEXTURE
|| carg2
== WINED3DTA_TEXTURE
|| carg0
== WINED3DTA_TEXTURE
||
2821 aarg1
== WINED3DTA_TEXTURE
|| aarg2
== WINED3DTA_TEXTURE
|| aarg0
== WINED3DTA_TEXTURE
) {
2822 ttff
= stateblock
->textureState
[i
][WINED3DTSS_TEXTURETRANSFORMFLAGS
];
2823 if(ttff
== (WINED3DTTFF_PROJECTED
| WINED3DTTFF_COUNT3
)) {
2824 settings
->op
[i
].projected
= proj_count3
;
2825 } else if(ttff
== (WINED3DTTFF_PROJECTED
| WINED3DTTFF_COUNT4
)) {
2826 settings
->op
[i
].projected
= proj_count4
;
2828 settings
->op
[i
].projected
= proj_none
;
2831 settings
->op
[i
].projected
= proj_none
;
2834 settings
->op
[i
].cop
= cop
;
2835 settings
->op
[i
].aop
= aop
;
2836 settings
->op
[i
].carg0
= carg0
;
2837 settings
->op
[i
].carg1
= carg1
;
2838 settings
->op
[i
].carg2
= carg2
;
2839 settings
->op
[i
].aarg0
= aarg0
;
2840 settings
->op
[i
].aarg1
= aarg1
;
2841 settings
->op
[i
].aarg2
= aarg2
;
2843 if(stateblock
->textureState
[i
][WINED3DTSS_RESULTARG
] == WINED3DTA_TEMP
) {
2844 settings
->op
[i
].dst
= tempreg
;
2846 settings
->op
[i
].dst
= resultreg
;
2850 /* Clear unsupported stages */
2851 for(; i
< MAX_TEXTURES
; i
++) {
2852 memset(&settings
->op
[i
], 0xff, sizeof(settings
->op
[i
]));
2855 if(stateblock
->renderState
[WINED3DRS_FOGENABLE
] == FALSE
) {
2856 settings
->fog
= FOG_OFF
;
2857 } else if(stateblock
->renderState
[WINED3DRS_FOGTABLEMODE
] == WINED3DFOG_NONE
) {
2858 if(use_vs(stateblock
) || ((IWineD3DVertexDeclarationImpl
*) stateblock
->vertexDecl
)->position_transformed
) {
2859 settings
->fog
= FOG_LINEAR
;
2861 switch(stateblock
->renderState
[WINED3DRS_FOGVERTEXMODE
]) {
2862 case WINED3DFOG_NONE
:
2863 case WINED3DFOG_LINEAR
:
2864 settings
->fog
= FOG_LINEAR
;
2866 case WINED3DFOG_EXP
:
2867 settings
->fog
= FOG_EXP
;
2869 case WINED3DFOG_EXP2
:
2870 settings
->fog
= FOG_EXP2
;
2875 switch(stateblock
->renderState
[WINED3DRS_FOGTABLEMODE
]) {
2876 case WINED3DFOG_LINEAR
:
2877 settings
->fog
= FOG_LINEAR
;
2879 case WINED3DFOG_EXP
:
2880 settings
->fog
= FOG_EXP
;
2882 case WINED3DFOG_EXP2
:
2883 settings
->fog
= FOG_EXP2
;
2887 if(stateblock
->renderState
[WINED3DRS_SRGBWRITEENABLE
]) {
2888 settings
->sRGB_write
= 1;
2890 settings
->sRGB_write
= 0;
2892 if(device
->vs_clipping
|| !use_vs(stateblock
) || !stateblock
->renderState
[WINED3DRS_CLIPPING
] ||
2893 !stateblock
->renderState
[WINED3DRS_CLIPPLANEENABLE
]) {
2894 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
2895 * the fixed function vertex pipeline is used(which always supports clipplanes), or
2896 * if no clipplane is enabled
2898 settings
->emul_clipplanes
= 0;
2900 settings
->emul_clipplanes
= 1;
2904 const struct ffp_frag_desc
*find_ffp_frag_shader(const struct wine_rb_tree
*fragment_shaders
,
2905 const struct ffp_frag_settings
*settings
)
2907 struct wine_rb_entry
*entry
= wine_rb_get(fragment_shaders
, settings
);
2908 return entry
? WINE_RB_ENTRY_VALUE(entry
, struct ffp_frag_desc
, entry
) : NULL
;
2911 void add_ffp_frag_shader(struct wine_rb_tree
*shaders
, struct ffp_frag_desc
*desc
)
2913 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2914 * whereas desc points to an extended structure with implementation specific parts. */
2915 if (wine_rb_put(shaders
, &desc
->settings
, &desc
->entry
) == -1)
2917 ERR("Failed to insert ffp frag shader.\n");
2921 /* Activates the texture dimension according to the bound D3D texture.
2922 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2923 * Requires the caller to activate the correct unit before
2925 /* GL locking is done by the caller (state handler) */
2926 void texture_activate_dimensions(DWORD stage
, IWineD3DStateBlockImpl
*stateblock
, struct wined3d_context
*context
)
2928 const struct wined3d_gl_info
*gl_info
= context
->gl_info
;
2930 if (stateblock
->textures
[stage
])
2932 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock
->textures
[stage
])) {
2934 glDisable(GL_TEXTURE_3D
);
2935 checkGLcall("glDisable(GL_TEXTURE_3D)");
2936 if (gl_info
->supported
[ARB_TEXTURE_CUBE_MAP
])
2938 glDisable(GL_TEXTURE_CUBE_MAP_ARB
);
2939 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2941 if (gl_info
->supported
[ARB_TEXTURE_RECTANGLE
])
2943 glDisable(GL_TEXTURE_RECTANGLE_ARB
);
2944 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2946 glEnable(GL_TEXTURE_2D
);
2947 checkGLcall("glEnable(GL_TEXTURE_2D)");
2949 case GL_TEXTURE_RECTANGLE_ARB
:
2950 glDisable(GL_TEXTURE_2D
);
2951 checkGLcall("glDisable(GL_TEXTURE_2D)");
2952 glDisable(GL_TEXTURE_3D
);
2953 checkGLcall("glDisable(GL_TEXTURE_3D)");
2954 if (gl_info
->supported
[ARB_TEXTURE_CUBE_MAP
])
2956 glDisable(GL_TEXTURE_CUBE_MAP_ARB
);
2957 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2959 glEnable(GL_TEXTURE_RECTANGLE_ARB
);
2960 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2963 if (gl_info
->supported
[ARB_TEXTURE_CUBE_MAP
])
2965 glDisable(GL_TEXTURE_CUBE_MAP_ARB
);
2966 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2968 if (gl_info
->supported
[ARB_TEXTURE_RECTANGLE
])
2970 glDisable(GL_TEXTURE_RECTANGLE_ARB
);
2971 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2973 glDisable(GL_TEXTURE_2D
);
2974 checkGLcall("glDisable(GL_TEXTURE_2D)");
2975 glEnable(GL_TEXTURE_3D
);
2976 checkGLcall("glEnable(GL_TEXTURE_3D)");
2978 case GL_TEXTURE_CUBE_MAP_ARB
:
2979 glDisable(GL_TEXTURE_2D
);
2980 checkGLcall("glDisable(GL_TEXTURE_2D)");
2981 glDisable(GL_TEXTURE_3D
);
2982 checkGLcall("glDisable(GL_TEXTURE_3D)");
2983 if (gl_info
->supported
[ARB_TEXTURE_RECTANGLE
])
2985 glDisable(GL_TEXTURE_RECTANGLE_ARB
);
2986 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2988 glEnable(GL_TEXTURE_CUBE_MAP_ARB
);
2989 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2993 glEnable(GL_TEXTURE_2D
);
2994 checkGLcall("glEnable(GL_TEXTURE_2D)");
2995 glDisable(GL_TEXTURE_3D
);
2996 checkGLcall("glDisable(GL_TEXTURE_3D)");
2997 if (gl_info
->supported
[ARB_TEXTURE_CUBE_MAP
])
2999 glDisable(GL_TEXTURE_CUBE_MAP_ARB
);
3000 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3002 if (gl_info
->supported
[ARB_TEXTURE_RECTANGLE
])
3004 glDisable(GL_TEXTURE_RECTANGLE_ARB
);
3005 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3007 /* Binding textures is done by samplers. A dummy texture will be bound */
3011 /* GL locking is done by the caller (state handler) */
3012 void sampler_texdim(DWORD state
, IWineD3DStateBlockImpl
*stateblock
, struct wined3d_context
*context
)
3014 DWORD sampler
= state
- STATE_SAMPLER(0);
3015 DWORD mapped_stage
= stateblock
->device
->texUnitMap
[sampler
];
3017 /* No need to enable / disable anything here for unused samplers. The tex_colorop
3018 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3019 * will take care of this business
3021 if (mapped_stage
== WINED3D_UNMAPPED_STAGE
|| mapped_stage
>= context
->gl_info
->limits
.textures
) return;
3022 if(sampler
>= stateblock
->lowest_disabled_stage
) return;
3023 if(isStateDirty(context
, STATE_TEXTURESTAGE(sampler
, WINED3DTSS_COLOROP
))) return;
3025 texture_activate_dimensions(sampler
, stateblock
, context
);
3028 void *wined3d_rb_alloc(size_t size
)
3030 return HeapAlloc(GetProcessHeap(), 0, size
);
3033 void *wined3d_rb_realloc(void *ptr
, size_t size
)
3035 return HeapReAlloc(GetProcessHeap(), 0, ptr
, size
);
3038 void wined3d_rb_free(void *ptr
)
3040 HeapFree(GetProcessHeap(), 0, ptr
);
3043 static int ffp_frag_program_key_compare(const void *key
, const struct wine_rb_entry
*entry
)
3045 const struct ffp_frag_settings
*ka
= key
;
3046 const struct ffp_frag_settings
*kb
= &WINE_RB_ENTRY_VALUE(entry
, const struct ffp_frag_desc
, entry
)->settings
;
3048 return memcmp(ka
, kb
, sizeof(*ka
));
3051 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions
=
3056 ffp_frag_program_key_compare
,
3059 UINT
wined3d_log2i(UINT32 x
)
3061 static const UINT l
[] =
3063 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3064 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3065 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3066 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3067 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3068 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3069 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3070 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
3071 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3072 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3073 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3074 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3075 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3076 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3077 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3078 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3082 return (i
= x
>> 16) ? (x
= i
>> 8) ? l
[x
] + 24 : l
[i
] + 16 : (i
= x
>> 8) ? l
[i
] + 8 : l
[x
];
3085 /* Set the shader type for this device, depending on the given capabilities
3086 * and the user preferences in wined3d_settings. */
3087 void select_shader_mode(const struct wined3d_gl_info
*gl_info
, int *ps_selected
, int *vs_selected
)
3089 BOOL glsl
= wined3d_settings
.glslRequested
&& gl_info
->glsl_version
>= MAKEDWORD_VERSION(1, 20);
3091 if (wined3d_settings
.vs_mode
== VS_NONE
) *vs_selected
= SHADER_NONE
;
3092 else if (gl_info
->supported
[ARB_VERTEX_SHADER
] && glsl
)
3094 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
3095 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
3096 * shaders only on this card. */
3097 if (gl_info
->supported
[NV_VERTEX_PROGRAM
] && !gl_info
->supported
[NV_VERTEX_PROGRAM2
]) *vs_selected
= SHADER_ARB
;
3098 else *vs_selected
= SHADER_GLSL
;
3100 else if (gl_info
->supported
[ARB_VERTEX_PROGRAM
]) *vs_selected
= SHADER_ARB
;
3101 else *vs_selected
= SHADER_NONE
;
3103 if (wined3d_settings
.ps_mode
== PS_NONE
) *ps_selected
= SHADER_NONE
;
3104 else if (gl_info
->supported
[ARB_FRAGMENT_SHADER
] && glsl
) *ps_selected
= SHADER_GLSL
;
3105 else if (gl_info
->supported
[ARB_FRAGMENT_PROGRAM
]) *ps_selected
= SHADER_ARB
;
3106 else if (gl_info
->supported
[ATI_FRAGMENT_SHADER
]) *ps_selected
= SHADER_ATI
;
3107 else *ps_selected
= SHADER_NONE
;