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
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wined3d_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
31 struct StaticPixelFormatDesc
34 DWORD alphaMask
, redMask
, greenMask
, blueMask
;
36 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 isFourcc */
53 {WINED3DFMT_UNKNOWN
, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, FALSE
},
54 /* FourCC formats, kept here to have WINED3DFMT_R8G8B8(=20) at position 20 */
55 {WINED3DFMT_UYVY
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE
},
56 {WINED3DFMT_YUY2
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE
},
57 {WINED3DFMT_YV12
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE
},
58 {WINED3DFMT_DXT1
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE
},
59 {WINED3DFMT_DXT2
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE
},
60 {WINED3DFMT_DXT3
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE
},
61 {WINED3DFMT_DXT4
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE
},
62 {WINED3DFMT_DXT5
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE
},
63 {WINED3DFMT_MULTI2_ARGB8
, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE
},
64 {WINED3DFMT_G8R8_G8B8
, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE
},
65 {WINED3DFMT_R8G8_B8G8
, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0, TRUE
},
67 {WINED3DFMT_R32_FLOAT
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE
},
68 {WINED3DFMT_R32G32_FLOAT
, 0x0, 0x0, 0x0, 0x0, 8, 0, 0, FALSE
},
69 {WINED3DFMT_R32G32B32_FLOAT
, 0x0, 0x0, 0x0, 0x0, 12, 0, 0, FALSE
},
70 {WINED3DFMT_R32G32B32A32_FLOAT
, 0x1, 0x0, 0x0, 0x0, 16, 0, 0, FALSE
},
72 {WINED3DFMT_CxV8U8
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE
},
74 {WINED3DFMT_R16_FLOAT
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE
},
75 {WINED3DFMT_R16G16_FLOAT
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE
},
76 {WINED3DFMT_R16G16_SINT
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE
},
77 {WINED3DFMT_R16G16B16A16_FLOAT
, 0x1, 0x0, 0x0, 0x0, 8, 0, 0, FALSE
},
78 {WINED3DFMT_R16G16B16A16_SINT
, 0x1, 0x0, 0x0, 0x0, 8, 0, 0, FALSE
},
79 /* Palettized formats */
80 {WINED3DFMT_A8P8
, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0, FALSE
},
81 {WINED3DFMT_P8
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE
},
82 /* Standard ARGB formats. */
83 {WINED3DFMT_R8G8B8
, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0, FALSE
},
84 {WINED3DFMT_A8R8G8B8
, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0, FALSE
},
85 {WINED3DFMT_X8R8G8B8
, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0, FALSE
},
86 {WINED3DFMT_R5G6B5
, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0, FALSE
},
87 {WINED3DFMT_X1R5G5B5
, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0, FALSE
},
88 {WINED3DFMT_A1R5G5B5
, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0, FALSE
},
89 {WINED3DFMT_A4R4G4B4
, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0, FALSE
},
90 {WINED3DFMT_R3G3B2
, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0, FALSE
},
91 {WINED3DFMT_A8_UNORM
, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0, FALSE
},
92 {WINED3DFMT_A8R3G3B2
, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0, FALSE
},
93 {WINED3DFMT_X4R4G4B4
, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0, FALSE
},
94 {WINED3DFMT_R10G10B10A2_UNORM
, 0xb0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE
},
95 {WINED3DFMT_R10G10B10A2_UINT
, 0xb0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE
},
96 {WINED3DFMT_R10G10B10A2_SNORM
, 0xb0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0, FALSE
},
97 {WINED3DFMT_R8G8B8A8_UNORM
, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE
},
98 {WINED3DFMT_R8G8B8A8_UINT
, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE
},
99 {WINED3DFMT_X8B8G8R8
, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0, FALSE
},
100 {WINED3DFMT_R16G16_UNORM
, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0, FALSE
},
101 {WINED3DFMT_A2R10G10B10
, 0xb0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0, FALSE
},
102 {WINED3DFMT_R16G16B16A16_UNORM
, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0, FALSE
},
104 {WINED3DFMT_L8
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE
},
105 {WINED3DFMT_A8L8
, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0, FALSE
},
106 {WINED3DFMT_A4L4
, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0, FALSE
},
107 /* Bump mapping stuff */
108 {WINED3DFMT_R8G8_SNORM
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE
},
109 {WINED3DFMT_L6V5U5
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE
},
110 {WINED3DFMT_X8L8V8U8
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE
},
111 {WINED3DFMT_R8G8B8A8_SNORM
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE
},
112 {WINED3DFMT_R16G16_SNORM
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE
},
113 {WINED3DFMT_W11V11U10
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE
},
114 {WINED3DFMT_A2W10V10U10
, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0, FALSE
},
115 /* Depth stencil formats */
116 {WINED3DFMT_D16_LOCKABLE
, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE
},
117 {WINED3DFMT_D32
, 0x0, 0x0, 0x0, 0x0, 4, 32, 0, FALSE
},
118 {WINED3DFMT_D15S1
, 0x0, 0x0, 0x0, 0x0, 2, 15, 1, FALSE
},
119 {WINED3DFMT_D24S8
, 0x0, 0x0, 0x0, 0x0, 4, 24, 8, FALSE
},
120 {WINED3DFMT_D24X8
, 0x0, 0x0, 0x0, 0x0, 4, 24, 0, FALSE
},
121 {WINED3DFMT_D24X4S4
, 0x0, 0x0, 0x0, 0x0, 4, 24, 4, FALSE
},
122 {WINED3DFMT_D16_UNORM
, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE
},
123 {WINED3DFMT_L16
, 0x0, 0x0, 0x0, 0x0, 2, 16, 0, FALSE
},
124 {WINED3DFMT_D32F_LOCKABLE
, 0x0, 0x0, 0x0, 0x0, 4, 32, 0, FALSE
},
125 {WINED3DFMT_D24FS8
, 0x0, 0x0, 0x0, 0x0, 4, 24, 8, FALSE
},
126 /* Is this a vertex buffer? */
127 {WINED3DFMT_VERTEXDATA
, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, FALSE
},
128 {WINED3DFMT_R16_UINT
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, FALSE
},
129 {WINED3DFMT_R32_UINT
, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE
},
130 {WINED3DFMT_R16G16B16A16_SNORM
, 0x0, 0x0, 0x0, 0x0, 8, 0, 0, FALSE
},
131 /* Vendor-specific formats */
132 {WINED3DFMT_ATI2N
, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE
},
133 {WINED3DFMT_NVHU
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE
},
134 {WINED3DFMT_NVHS
, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE
},
137 struct wined3d_format_vertex_info
139 WINED3DFORMAT format
;
140 enum wined3d_ffp_emit_idx emit_idx
;
141 GLint component_count
;
144 GLboolean gl_normalized
;
145 unsigned int component_size
;
148 static const struct wined3d_format_vertex_info format_vertex_info
[] =
150 {WINED3DFMT_R32_FLOAT
, WINED3D_FFP_EMIT_FLOAT1
, 1, GL_FLOAT
, 1, GL_FALSE
, sizeof(float)},
151 {WINED3DFMT_R32G32_FLOAT
, WINED3D_FFP_EMIT_FLOAT2
, 2, GL_FLOAT
, 2, GL_FALSE
, sizeof(float)},
152 {WINED3DFMT_R32G32B32_FLOAT
, WINED3D_FFP_EMIT_FLOAT3
, 3, GL_FLOAT
, 3, GL_FALSE
, sizeof(float)},
153 {WINED3DFMT_R32G32B32A32_FLOAT
, WINED3D_FFP_EMIT_FLOAT4
, 4, GL_FLOAT
, 4, GL_FALSE
, sizeof(float)},
154 {WINED3DFMT_A8R8G8B8
, WINED3D_FFP_EMIT_D3DCOLOR
, 4, GL_UNSIGNED_BYTE
, 4, GL_TRUE
, sizeof(BYTE
)},
155 {WINED3DFMT_R8G8B8A8_UINT
, WINED3D_FFP_EMIT_UBYTE4
, 4, GL_UNSIGNED_BYTE
, 4, GL_FALSE
, sizeof(BYTE
)},
156 {WINED3DFMT_R16G16_SINT
, WINED3D_FFP_EMIT_SHORT2
, 2, GL_SHORT
, 2, GL_FALSE
, sizeof(short int)},
157 {WINED3DFMT_R16G16B16A16_SINT
, WINED3D_FFP_EMIT_SHORT4
, 4, GL_SHORT
, 4, GL_FALSE
, sizeof(short int)},
158 {WINED3DFMT_R8G8B8A8_UNORM
, WINED3D_FFP_EMIT_UBYTE4N
, 4, GL_UNSIGNED_BYTE
, 4, GL_TRUE
, sizeof(BYTE
)},
159 {WINED3DFMT_R16G16_SNORM
, WINED3D_FFP_EMIT_SHORT2N
, 2, GL_SHORT
, 2, GL_TRUE
, sizeof(short int)},
160 {WINED3DFMT_R16G16B16A16_SNORM
, WINED3D_FFP_EMIT_SHORT4N
, 4, GL_SHORT
, 4, GL_TRUE
, sizeof(short int)},
161 {WINED3DFMT_R16G16_UNORM
, WINED3D_FFP_EMIT_USHORT2N
, 2, GL_UNSIGNED_SHORT
, 2, GL_TRUE
, sizeof(short int)},
162 {WINED3DFMT_R16G16B16A16_UNORM
, WINED3D_FFP_EMIT_USHORT4N
, 4, GL_UNSIGNED_SHORT
, 4, GL_TRUE
, sizeof(short int)},
163 {WINED3DFMT_R10G10B10A2_UINT
, WINED3D_FFP_EMIT_UDEC3
, 3, GL_UNSIGNED_SHORT
, 3, GL_FALSE
, sizeof(short int)},
164 {WINED3DFMT_R10G10B10A2_SNORM
, WINED3D_FFP_EMIT_DEC3N
, 3, GL_SHORT
, 3, GL_TRUE
, sizeof(short int)},
165 {WINED3DFMT_R16G16_FLOAT
, WINED3D_FFP_EMIT_FLOAT16_2
, 2, GL_FLOAT
, 2, GL_FALSE
, sizeof(GLhalfNV
)},
166 {WINED3DFMT_R16G16B16A16_FLOAT
, WINED3D_FFP_EMIT_FLOAT16_4
, 4, GL_FLOAT
, 4, GL_FALSE
, sizeof(GLhalfNV
)}
171 GLint glInternal
, glGammaInternal
, rtInternal
, glFormat
, glType
;
173 } GlPixelFormatDescTemplate
;
175 /*****************************************************************************
176 * OpenGL format template. Contains unexciting formats which do not need
177 * extension checks. The order in this table is independent of the order in
178 * the table StaticPixelFormatDesc above. Not all formats have to be in this
181 static const GlPixelFormatDescTemplate gl_formats_template
[] = {
182 /* WINED3DFORMAT internal srgbInternal rtInternal
185 {WINED3DFMT_UNKNOWN
, 0, 0, 0,
189 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
190 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
191 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
192 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
195 {WINED3DFMT_UYVY
, GL_RGB
, GL_RGB
, 0,
196 GL_YCBCR_422_APPLE
, UNSIGNED_SHORT_8_8_APPLE
,
197 WINED3DFMT_FLAG_FILTERING
},
198 {WINED3DFMT_YUY2
, GL_RGB
, GL_RGB
, 0,
199 GL_YCBCR_422_APPLE
, UNSIGNED_SHORT_8_8_REV_APPLE
,
200 WINED3DFMT_FLAG_FILTERING
},
201 {WINED3DFMT_YV12
, GL_ALPHA
, GL_ALPHA
, 0,
202 GL_ALPHA
, GL_UNSIGNED_BYTE
,
203 WINED3DFMT_FLAG_FILTERING
},
204 {WINED3DFMT_DXT1
, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
, 0,
205 GL_RGBA
, GL_UNSIGNED_BYTE
,
206 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
207 {WINED3DFMT_DXT2
, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
, 0,
208 GL_RGBA
, GL_UNSIGNED_BYTE
,
209 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
210 {WINED3DFMT_DXT3
, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
, 0,
211 GL_RGBA
, GL_UNSIGNED_BYTE
,
212 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
213 {WINED3DFMT_DXT4
, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
, 0,
214 GL_RGBA
, GL_UNSIGNED_BYTE
,
215 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
216 {WINED3DFMT_DXT5
, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
, 0,
217 GL_RGBA
, GL_UNSIGNED_BYTE
,
218 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
219 {WINED3DFMT_MULTI2_ARGB8
, 0, 0, 0,
222 {WINED3DFMT_G8R8_G8B8
, 0, 0, 0,
225 {WINED3DFMT_R8G8_B8G8
, 0, 0, 0,
229 {WINED3DFMT_R32_FLOAT
, GL_RGB32F_ARB
, GL_RGB32F_ARB
, 0,
231 WINED3DFMT_FLAG_RENDERTARGET
},
232 {WINED3DFMT_R32G32_FLOAT
, GL_RG32F
, GL_RG32F
, 0,
234 WINED3DFMT_FLAG_RENDERTARGET
},
235 {WINED3DFMT_R32G32B32A32_FLOAT
, GL_RGBA32F_ARB
, GL_RGBA32F_ARB
, 0,
237 WINED3DFMT_FLAG_RENDERTARGET
},
239 {WINED3DFMT_CxV8U8
, 0, 0, 0,
243 {WINED3DFMT_R16_FLOAT
, GL_RGB16F_ARB
, GL_RGB16F_ARB
, 0,
244 GL_RED
, GL_HALF_FLOAT_ARB
,
245 WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_RENDERTARGET
},
246 {WINED3DFMT_R16G16_FLOAT
, GL_RG16F
, GL_RG16F
, 0,
247 GL_RG
, GL_HALF_FLOAT_ARB
,
248 WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_RENDERTARGET
},
249 {WINED3DFMT_R16G16B16A16_FLOAT
, GL_RGBA16F_ARB
, GL_RGBA16F_ARB
, 0,
250 GL_RGBA
, GL_HALF_FLOAT_ARB
,
251 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_RENDERTARGET
},
252 /* Palettized formats */
253 {WINED3DFMT_A8P8
, 0, 0, 0,
256 {WINED3DFMT_P8
, GL_COLOR_INDEX8_EXT
, GL_COLOR_INDEX8_EXT
, 0,
257 GL_COLOR_INDEX
, GL_UNSIGNED_BYTE
,
259 /* Standard ARGB formats */
260 {WINED3DFMT_R8G8B8
, GL_RGB8
, GL_RGB8
, 0,
261 GL_BGR
, GL_UNSIGNED_BYTE
,
262 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_RENDERTARGET
},
263 {WINED3DFMT_A8R8G8B8
, GL_RGBA8
, GL_SRGB8_ALPHA8_EXT
, 0,
264 GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
,
265 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_RENDERTARGET
},
266 {WINED3DFMT_X8R8G8B8
, GL_RGB8
, GL_SRGB8_EXT
, 0,
267 GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
,
268 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_RENDERTARGET
},
269 {WINED3DFMT_R5G6B5
, GL_RGB5
, GL_RGB5
, GL_RGB8
,
270 GL_RGB
, GL_UNSIGNED_SHORT_5_6_5
,
271 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_RENDERTARGET
},
272 {WINED3DFMT_X1R5G5B5
, GL_RGB5
, GL_RGB5_A1
, 0,
273 GL_BGRA
, GL_UNSIGNED_SHORT_1_5_5_5_REV
,
274 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
275 {WINED3DFMT_A1R5G5B5
, GL_RGB5_A1
, GL_RGB5_A1
, 0,
276 GL_BGRA
, GL_UNSIGNED_SHORT_1_5_5_5_REV
,
277 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
278 {WINED3DFMT_A4R4G4B4
, GL_RGBA4
, GL_SRGB8_ALPHA8_EXT
, 0,
279 GL_BGRA
, GL_UNSIGNED_SHORT_4_4_4_4_REV
,
280 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
281 {WINED3DFMT_R3G3B2
, GL_R3_G3_B2
, GL_R3_G3_B2
, 0,
282 GL_RGB
, GL_UNSIGNED_BYTE_3_3_2
,
283 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
},
284 {WINED3DFMT_A8_UNORM
, GL_ALPHA8
, GL_ALPHA8
, 0,
285 GL_ALPHA
, GL_UNSIGNED_BYTE
,
286 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
},
287 {WINED3DFMT_A8R3G3B2
, 0, 0, 0,
290 {WINED3DFMT_X4R4G4B4
, GL_RGB4
, GL_RGB4
, 0,
291 GL_BGRA
, GL_UNSIGNED_SHORT_4_4_4_4_REV
,
292 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
293 {WINED3DFMT_R10G10B10A2_UNORM
, GL_RGB10_A2
, GL_RGB10_A2
, 0,
294 GL_RGBA
, GL_UNSIGNED_INT_2_10_10_10_REV
,
295 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
296 {WINED3DFMT_R8G8B8A8_UNORM
, GL_RGBA8
, GL_RGBA8
, 0,
297 GL_RGBA
, GL_UNSIGNED_INT_8_8_8_8_REV
,
298 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
299 {WINED3DFMT_X8B8G8R8
, GL_RGB8
, GL_RGB8
, 0,
300 GL_RGBA
, GL_UNSIGNED_INT_8_8_8_8_REV
,
301 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
302 {WINED3DFMT_R16G16_UNORM
, GL_RGB16_EXT
, GL_RGB16_EXT
, 0,
303 GL_RGB
, GL_UNSIGNED_SHORT
,
304 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
305 {WINED3DFMT_A2R10G10B10
, GL_RGB10_A2
, GL_RGB10_A2
, 0,
306 GL_BGRA
, GL_UNSIGNED_INT_2_10_10_10_REV
,
307 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
308 {WINED3DFMT_R16G16B16A16_UNORM
, GL_RGBA16_EXT
, GL_RGBA16_EXT
, 0,
309 GL_RGBA
, GL_UNSIGNED_SHORT
,
310 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_RENDERTARGET
},
312 {WINED3DFMT_L8
, GL_LUMINANCE8
, GL_SLUMINANCE8_EXT
, 0,
313 GL_LUMINANCE
, GL_UNSIGNED_BYTE
,
314 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
315 {WINED3DFMT_A8L8
, GL_LUMINANCE8_ALPHA8
, GL_SLUMINANCE8_ALPHA8_EXT
, 0,
316 GL_LUMINANCE_ALPHA
, GL_UNSIGNED_BYTE
,
317 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
318 {WINED3DFMT_A4L4
, GL_LUMINANCE4_ALPHA4
, GL_LUMINANCE4_ALPHA4
, 0,
319 GL_LUMINANCE_ALPHA
, GL_UNSIGNED_BYTE
,
321 /* Bump mapping stuff */
322 {WINED3DFMT_R8G8_SNORM
, GL_DSDT8_NV
, GL_DSDT8_NV
, 0,
324 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
325 {WINED3DFMT_L6V5U5
, GL_DSDT8_MAG8_NV
, GL_DSDT8_MAG8_NV
, 0,
326 GL_DSDT_MAG_NV
, GL_BYTE
,
327 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
328 {WINED3DFMT_X8L8V8U8
, GL_DSDT8_MAG8_INTENSITY8_NV
, GL_DSDT8_MAG8_INTENSITY8_NV
, 0,
329 GL_DSDT_MAG_VIB_NV
, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV
,
330 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
331 {WINED3DFMT_R8G8B8A8_SNORM
, GL_SIGNED_RGBA8_NV
, GL_SIGNED_RGBA8_NV
, 0,
333 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
334 {WINED3DFMT_R16G16_SNORM
, GL_SIGNED_HILO16_NV
, GL_SIGNED_HILO16_NV
, 0,
335 GL_HILO_NV
, GL_SHORT
,
336 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
337 {WINED3DFMT_W11V11U10
, 0, 0, 0,
340 {WINED3DFMT_A2W10V10U10
, 0, 0, 0,
343 /* Depth stencil formats */
344 {WINED3DFMT_D16_LOCKABLE
, GL_DEPTH_COMPONENT24_ARB
, GL_DEPTH_COMPONENT24_ARB
, 0,
345 GL_DEPTH_COMPONENT
, GL_UNSIGNED_SHORT
,
346 WINED3DFMT_FLAG_DEPTH
},
347 {WINED3DFMT_D32
, GL_DEPTH_COMPONENT32_ARB
, GL_DEPTH_COMPONENT32_ARB
, 0,
348 GL_DEPTH_COMPONENT
, GL_UNSIGNED_INT
,
349 WINED3DFMT_FLAG_DEPTH
},
350 {WINED3DFMT_D15S1
, GL_DEPTH_COMPONENT24_ARB
, GL_DEPTH_COMPONENT24_ARB
, 0,
351 GL_DEPTH_COMPONENT
, GL_UNSIGNED_SHORT
,
352 WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_STENCIL
},
353 {WINED3DFMT_D24S8
, GL_DEPTH_COMPONENT24_ARB
, GL_DEPTH_COMPONENT24_ARB
, 0,
354 GL_DEPTH_COMPONENT
, GL_UNSIGNED_INT
,
355 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_STENCIL
},
356 {WINED3DFMT_D24X8
, GL_DEPTH_COMPONENT24_ARB
, GL_DEPTH_COMPONENT24_ARB
, 0,
357 GL_DEPTH_COMPONENT
, GL_UNSIGNED_INT
,
358 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_DEPTH
},
359 {WINED3DFMT_D24X4S4
, GL_DEPTH_COMPONENT24_ARB
, GL_DEPTH_COMPONENT24_ARB
, 0,
360 GL_DEPTH_COMPONENT
, GL_UNSIGNED_INT
,
361 WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_STENCIL
},
362 {WINED3DFMT_D16_UNORM
, GL_DEPTH_COMPONENT24_ARB
, GL_DEPTH_COMPONENT24_ARB
, 0,
363 GL_DEPTH_COMPONENT
, GL_UNSIGNED_SHORT
,
364 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_DEPTH
},
365 {WINED3DFMT_L16
, GL_LUMINANCE16_EXT
, GL_LUMINANCE16_EXT
, 0,
366 GL_LUMINANCE
, GL_UNSIGNED_SHORT
,
367 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
| WINED3DFMT_FLAG_FILTERING
},
368 {WINED3DFMT_D32F_LOCKABLE
, GL_DEPTH_COMPONENT32_ARB
, GL_DEPTH_COMPONENT32_ARB
, 0,
369 GL_DEPTH_COMPONENT
, GL_FLOAT
,
370 WINED3DFMT_FLAG_DEPTH
},
371 {WINED3DFMT_D24FS8
, GL_DEPTH_COMPONENT24_ARB
, GL_DEPTH_COMPONENT24_ARB
, 0,
372 GL_DEPTH_COMPONENT
, GL_FLOAT
,
373 WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_STENCIL
},
374 /* Is this a vertex buffer? */
375 {WINED3DFMT_VERTEXDATA
, 0, 0, 0,
378 {WINED3DFMT_R16_UINT
, 0, 0, 0,
381 {WINED3DFMT_R32_UINT
, 0, 0, 0,
384 {WINED3DFMT_R16G16B16A16_SNORM
, GL_COLOR_INDEX
, GL_COLOR_INDEX
, 0,
385 GL_COLOR_INDEX
, GL_UNSIGNED_SHORT
,
387 /* Vendor-specific formats */
388 {WINED3DFMT_ATI2N
, 0, 0, 0,
389 GL_LUMINANCE_ALPHA
, GL_UNSIGNED_BYTE
,
391 {WINED3DFMT_NVHU
, 0, 0, 0,
392 GL_LUMINANCE_ALPHA
, GL_UNSIGNED_BYTE
,
394 {WINED3DFMT_NVHS
, 0, 0, 0,
395 GL_LUMINANCE_ALPHA
, GL_UNSIGNED_BYTE
,
399 static inline int getFmtIdx(WINED3DFORMAT fmt
) {
400 /* First check if the format is at the position of its value.
401 * This will catch the argb formats before the loop is entered
403 if(fmt
< (sizeof(formats
) / sizeof(formats
[0])) && formats
[fmt
].format
== fmt
) {
407 for(i
= 0; i
< (sizeof(formats
) / sizeof(formats
[0])); i
++) {
408 if(formats
[i
].format
== fmt
) {
416 static BOOL
init_format_base_info(WineD3D_GL_Info
*gl_info
)
418 UINT format_count
= sizeof(formats
) / sizeof(*formats
);
421 gl_info
->gl_formats
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, format_count
* sizeof(*gl_info
->gl_formats
));
422 if (!gl_info
->gl_formats
)
424 ERR("Failed to allocate memory.\n");
428 for (i
= 0; i
< format_count
; ++i
)
430 struct GlPixelFormatDesc
*desc
= &gl_info
->gl_formats
[i
];
431 desc
->format
= formats
[i
].format
;
432 desc
->red_mask
= formats
[i
].redMask
;
433 desc
->green_mask
= formats
[i
].greenMask
;
434 desc
->blue_mask
= formats
[i
].blueMask
;
435 desc
->alpha_mask
= formats
[i
].alphaMask
;
436 desc
->byte_count
= formats
[i
].bpp
;
437 desc
->depth_size
= formats
[i
].depthSize
;
438 desc
->stencil_size
= formats
[i
].stencilSize
;
439 if (formats
[i
].isFourcc
) desc
->Flags
|= WINED3DFMT_FLAG_FOURCC
;
445 #define GLINFO_LOCATION (*gl_info)
447 static BOOL
check_fbo_compat(const WineD3D_GL_Info
*gl_info
, GLint internal_format
)
455 glGenTextures(1, &tex
);
456 glBindTexture(GL_TEXTURE_2D
, tex
);
457 glTexImage2D(GL_TEXTURE_2D
, 0, internal_format
, 16, 16, 0, GL_RGBA
, GL_UNSIGNED_BYTE
, NULL
);
459 GL_EXTCALL(glGenFramebuffersEXT(1, &fb
));
460 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, fb
));
461 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT
, GL_COLOR_ATTACHMENT0_EXT
, GL_TEXTURE_2D
, tex
, 0));
463 status
= GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT
));
464 GL_EXTCALL(glDeleteFramebuffersEXT(1, &fb
));
465 glDeleteTextures(1, &tex
);
467 checkGLcall("Framebuffer format check");
471 return status
== GL_FRAMEBUFFER_COMPLETE_EXT
;
474 static BOOL
init_format_texture_info(WineD3D_GL_Info
*gl_info
)
478 for (i
= 0; i
< sizeof(gl_formats_template
) / sizeof(gl_formats_template
[0]); ++i
)
480 int fmt_idx
= getFmtIdx(gl_formats_template
[i
].fmt
);
481 struct GlPixelFormatDesc
*desc
;
485 ERR("Format %s (%#x) not found.\n",
486 debug_d3dformat(gl_formats_template
[i
].fmt
), gl_formats_template
[i
].fmt
);
490 desc
= &gl_info
->gl_formats
[fmt_idx
];
491 desc
->glInternal
= gl_formats_template
[i
].glInternal
;
492 desc
->glGammaInternal
= gl_formats_template
[i
].glGammaInternal
;
493 desc
->glFormat
= gl_formats_template
[i
].glFormat
;
494 desc
->glType
= gl_formats_template
[i
].glType
;
495 desc
->color_fixup
= COLOR_FIXUP_IDENTITY
;
496 desc
->Flags
|= gl_formats_template
[i
].Flags
;
497 desc
->heightscale
= 1.0;
499 if (wined3d_settings
.offscreen_rendering_mode
== ORM_FBO
&& gl_formats_template
[i
].rtInternal
)
501 /* Check if the default internal format is supported as a frame buffer target, otherwise
502 * fall back to the render target internal.
504 * Try to stick to the standard format if possible, this limits precision differences */
505 if (!check_fbo_compat(gl_info
, gl_formats_template
[i
].glInternal
))
507 TRACE("Internal format of %s not supported as FBO target, using render target internal instead\n",
508 debug_d3dformat(gl_formats_template
[i
].fmt
));
509 desc
->rtInternal
= gl_formats_template
[i
].rtInternal
;
513 TRACE("Format %s is supported as fbo target\n", debug_d3dformat(gl_formats_template
[i
].fmt
));
514 desc
->rtInternal
= gl_formats_template
[i
].glInternal
;
519 desc
->rtInternal
= gl_formats_template
[i
].glInternal
;
526 static void apply_format_fixups(WineD3D_GL_Info
*gl_info
)
530 idx
= getFmtIdx(WINED3DFMT_R16_FLOAT
);
531 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
532 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_W
);
533 /* When ARB_texture_rg is supported we only require 16-bit for R16F instead of 64-bit RGBA16F */
534 if (GL_SUPPORT(ARB_TEXTURE_RG
))
536 gl_info
->gl_formats
[idx
].glInternal
= GL_R16F
;
537 gl_info
->gl_formats
[idx
].glGammaInternal
= GL_R16F
;
540 idx
= getFmtIdx(WINED3DFMT_R32_FLOAT
);
541 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
542 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_W
);
543 /* When ARB_texture_rg is supported we only require 32-bit for R32F instead of 128-bit RGBA32F */
544 if (GL_SUPPORT(ARB_TEXTURE_RG
))
546 gl_info
->gl_formats
[idx
].glInternal
= GL_R32F
;
547 gl_info
->gl_formats
[idx
].glGammaInternal
= GL_R32F
;
550 idx
= getFmtIdx(WINED3DFMT_R16G16_UNORM
);
551 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
552 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_W
);
554 idx
= getFmtIdx(WINED3DFMT_R16G16_FLOAT
);
555 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
556 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_W
);
558 idx
= getFmtIdx(WINED3DFMT_R32G32_FLOAT
);
559 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
560 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_W
);
562 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
563 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
564 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
565 * the only driver that implements it(fglrx) has a buggy implementation.
567 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
568 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
569 * conversion for this format.
571 if (!GL_SUPPORT(NV_TEXTURE_SHADER
))
573 idx
= getFmtIdx(WINED3DFMT_R8G8_SNORM
);
574 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
575 1, CHANNEL_SOURCE_X
, 1, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
);
576 idx
= getFmtIdx(WINED3DFMT_R16G16_SNORM
);
577 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
578 1, CHANNEL_SOURCE_X
, 1, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
);
582 idx
= getFmtIdx(WINED3DFMT_R8G8_SNORM
);
583 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
584 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
);
585 idx
= getFmtIdx(WINED3DFMT_R16G16_SNORM
);
586 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
587 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
);
590 if (!GL_SUPPORT(NV_TEXTURE_SHADER
))
592 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
595 idx
= getFmtIdx(WINED3DFMT_L6V5U5
);
596 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
597 1, CHANNEL_SOURCE_X
, 1, CHANNEL_SOURCE_Z
, 0, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_ONE
);
598 idx
= getFmtIdx(WINED3DFMT_X8L8V8U8
);
599 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
600 1, CHANNEL_SOURCE_X
, 1, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_Z
, 0, CHANNEL_SOURCE_W
);
601 idx
= getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM
);
602 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
603 1, CHANNEL_SOURCE_X
, 1, CHANNEL_SOURCE_Y
, 1, CHANNEL_SOURCE_Z
, 1, CHANNEL_SOURCE_W
);
607 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
608 * are converted at surface loading time, but they do not need any modification in
609 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
610 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
614 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC
))
616 idx
= getFmtIdx(WINED3DFMT_ATI2N
);
617 gl_info
->gl_formats
[idx
].glInternal
= GL_COMPRESSED_RED_GREEN_RGTC2_EXT
;
618 gl_info
->gl_formats
[idx
].glGammaInternal
= GL_COMPRESSED_RED_GREEN_RGTC2_EXT
;
619 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
620 0, CHANNEL_SOURCE_Y
, 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
);
622 else if (GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC
))
624 idx
= getFmtIdx(WINED3DFMT_ATI2N
);
625 gl_info
->gl_formats
[idx
].glInternal
= GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI
;
626 gl_info
->gl_formats
[idx
].glGammaInternal
= GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI
;
627 gl_info
->gl_formats
[idx
].color_fixup
= create_color_fixup_desc(
628 0, CHANNEL_SOURCE_X
, 0, CHANNEL_SOURCE_W
, 0, CHANNEL_SOURCE_ONE
, 0, CHANNEL_SOURCE_ONE
);
631 if (!GL_SUPPORT(APPLE_YCBCR_422
))
633 idx
= getFmtIdx(WINED3DFMT_YUY2
);
634 gl_info
->gl_formats
[idx
].glInternal
= GL_LUMINANCE_ALPHA
;
635 gl_info
->gl_formats
[idx
].glGammaInternal
= GL_LUMINANCE_ALPHA
; /* not srgb */
636 gl_info
->gl_formats
[idx
].glFormat
= GL_LUMINANCE_ALPHA
;
637 gl_info
->gl_formats
[idx
].glType
= GL_UNSIGNED_BYTE
;
638 gl_info
->gl_formats
[idx
].color_fixup
= create_yuv_fixup_desc(YUV_FIXUP_YUY2
);
640 idx
= getFmtIdx(WINED3DFMT_UYVY
);
641 gl_info
->gl_formats
[idx
].glInternal
= GL_LUMINANCE_ALPHA
;
642 gl_info
->gl_formats
[idx
].glGammaInternal
= GL_LUMINANCE_ALPHA
; /* not srgb */
643 gl_info
->gl_formats
[idx
].glFormat
= GL_LUMINANCE_ALPHA
;
644 gl_info
->gl_formats
[idx
].glType
= GL_UNSIGNED_BYTE
;
645 gl_info
->gl_formats
[idx
].color_fixup
= create_yuv_fixup_desc(YUV_FIXUP_UYVY
);
648 idx
= getFmtIdx(WINED3DFMT_YV12
);
649 gl_info
->gl_formats
[idx
].heightscale
= 1.5;
650 gl_info
->gl_formats
[idx
].color_fixup
= create_yuv_fixup_desc(YUV_FIXUP_YV12
);
652 if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA
))
654 idx
= getFmtIdx(WINED3DFMT_A8R8G8B8
);
655 gl_info
->gl_formats
[idx
].gl_vtx_format
= GL_BGRA
;
658 if (GL_SUPPORT(ARB_HALF_FLOAT_VERTEX
))
660 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
661 * It is the job of the vertex buffer code to make sure that the vbos have the right format */
662 idx
= getFmtIdx(WINED3DFMT_R16G16_FLOAT
);
663 gl_info
->gl_formats
[idx
].gl_vtx_type
= GL_HALF_FLOAT
; /* == GL_HALF_FLOAT_NV */
665 idx
= getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT
);
666 gl_info
->gl_formats
[idx
].gl_vtx_type
= GL_HALF_FLOAT
;
670 static BOOL
init_format_vertex_info(WineD3D_GL_Info
*gl_info
)
674 for (i
= 0; i
< (sizeof(format_vertex_info
) / sizeof(*format_vertex_info
)); ++i
)
676 struct GlPixelFormatDesc
*format_desc
;
677 int fmt_idx
= getFmtIdx(format_vertex_info
[i
].format
);
681 ERR("Format %s (%#x) not found.\n",
682 debug_d3dformat(format_vertex_info
[i
].format
), format_vertex_info
[i
].format
);
686 format_desc
= &gl_info
->gl_formats
[fmt_idx
];
687 format_desc
->emit_idx
= format_vertex_info
[i
].emit_idx
;
688 format_desc
->component_count
= format_vertex_info
[i
].component_count
;
689 format_desc
->gl_vtx_type
= format_vertex_info
[i
].gl_vtx_type
;
690 format_desc
->gl_vtx_format
= format_vertex_info
[i
].gl_vtx_format
;
691 format_desc
->gl_normalized
= format_vertex_info
[i
].gl_normalized
;
692 format_desc
->component_size
= format_vertex_info
[i
].component_size
;
698 BOOL
initPixelFormatsNoGL(WineD3D_GL_Info
*gl_info
)
700 return init_format_base_info(gl_info
);
703 BOOL
initPixelFormats(WineD3D_GL_Info
*gl_info
)
705 if (!init_format_base_info(gl_info
)) return FALSE
;
707 if (!init_format_texture_info(gl_info
))
709 HeapFree(GetProcessHeap(), 0, gl_info
->gl_formats
);
713 if (!init_format_vertex_info(gl_info
))
715 HeapFree(GetProcessHeap(), 0, gl_info
->gl_formats
);
719 apply_format_fixups(gl_info
);
724 #undef GLINFO_LOCATION
726 #define GLINFO_LOCATION This->adapter->gl_info
728 const struct GlPixelFormatDesc
*getFormatDescEntry(WINED3DFORMAT fmt
, const WineD3D_GL_Info
*gl_info
)
730 int idx
= getFmtIdx(fmt
);
733 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt
), fmt
);
734 /* Get the caller a valid pointer */
735 idx
= getFmtIdx(WINED3DFMT_UNKNOWN
);
738 return &gl_info
->gl_formats
[idx
];
741 /*****************************************************************************
742 * Trace formatting of useful values
744 const char* debug_d3dformat(WINED3DFORMAT fmt
) {
746 #define FMT_TO_STR(fmt) case fmt: return #fmt
747 FMT_TO_STR(WINED3DFMT_UNKNOWN
);
748 FMT_TO_STR(WINED3DFMT_R8G8B8
);
749 FMT_TO_STR(WINED3DFMT_A8R8G8B8
);
750 FMT_TO_STR(WINED3DFMT_X8R8G8B8
);
751 FMT_TO_STR(WINED3DFMT_R5G6B5
);
752 FMT_TO_STR(WINED3DFMT_X1R5G5B5
);
753 FMT_TO_STR(WINED3DFMT_A1R5G5B5
);
754 FMT_TO_STR(WINED3DFMT_A4R4G4B4
);
755 FMT_TO_STR(WINED3DFMT_R3G3B2
);
756 FMT_TO_STR(WINED3DFMT_A8R3G3B2
);
757 FMT_TO_STR(WINED3DFMT_X4R4G4B4
);
758 FMT_TO_STR(WINED3DFMT_X8B8G8R8
);
759 FMT_TO_STR(WINED3DFMT_A2R10G10B10
);
760 FMT_TO_STR(WINED3DFMT_A8P8
);
761 FMT_TO_STR(WINED3DFMT_P8
);
762 FMT_TO_STR(WINED3DFMT_L8
);
763 FMT_TO_STR(WINED3DFMT_A8L8
);
764 FMT_TO_STR(WINED3DFMT_A4L4
);
765 FMT_TO_STR(WINED3DFMT_L6V5U5
);
766 FMT_TO_STR(WINED3DFMT_X8L8V8U8
);
767 FMT_TO_STR(WINED3DFMT_W11V11U10
);
768 FMT_TO_STR(WINED3DFMT_A2W10V10U10
);
769 FMT_TO_STR(WINED3DFMT_UYVY
);
770 FMT_TO_STR(WINED3DFMT_YUY2
);
771 FMT_TO_STR(WINED3DFMT_YV12
);
772 FMT_TO_STR(WINED3DFMT_DXT1
);
773 FMT_TO_STR(WINED3DFMT_DXT2
);
774 FMT_TO_STR(WINED3DFMT_DXT3
);
775 FMT_TO_STR(WINED3DFMT_DXT4
);
776 FMT_TO_STR(WINED3DFMT_DXT5
);
777 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8
);
778 FMT_TO_STR(WINED3DFMT_G8R8_G8B8
);
779 FMT_TO_STR(WINED3DFMT_R8G8_B8G8
);
780 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE
);
781 FMT_TO_STR(WINED3DFMT_D32
);
782 FMT_TO_STR(WINED3DFMT_D15S1
);
783 FMT_TO_STR(WINED3DFMT_D24S8
);
784 FMT_TO_STR(WINED3DFMT_D24X8
);
785 FMT_TO_STR(WINED3DFMT_D24X4S4
);
786 FMT_TO_STR(WINED3DFMT_L16
);
787 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE
);
788 FMT_TO_STR(WINED3DFMT_D24FS8
);
789 FMT_TO_STR(WINED3DFMT_VERTEXDATA
);
790 FMT_TO_STR(WINED3DFMT_CxV8U8
);
791 FMT_TO_STR(WINED3DFMT_ATI2N
);
792 FMT_TO_STR(WINED3DFMT_NVHU
);
793 FMT_TO_STR(WINED3DFMT_NVHS
);
794 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS
);
795 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT
);
796 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT
);
797 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT
);
798 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS
);
799 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT
);
800 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT
);
801 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT
);
802 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS
);
803 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT
);
804 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM
);
805 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT
);
806 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM
);
807 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT
);
808 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS
);
809 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT
);
810 FMT_TO_STR(WINED3DFMT_R32G32_UINT
);
811 FMT_TO_STR(WINED3DFMT_R32G32_SINT
);
812 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS
);
813 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT
);
814 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS
);
815 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT
);
816 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS
);
817 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM
);
818 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT
);
819 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM
);
820 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT
);
821 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS
);
822 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM
);
823 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB
);
824 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT
);
825 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM
);
826 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT
);
827 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS
);
828 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT
);
829 FMT_TO_STR(WINED3DFMT_R16G16_UNORM
);
830 FMT_TO_STR(WINED3DFMT_R16G16_UINT
);
831 FMT_TO_STR(WINED3DFMT_R16G16_SNORM
);
832 FMT_TO_STR(WINED3DFMT_R16G16_SINT
);
833 FMT_TO_STR(WINED3DFMT_R32_TYPELESS
);
834 FMT_TO_STR(WINED3DFMT_D32_FLOAT
);
835 FMT_TO_STR(WINED3DFMT_R32_FLOAT
);
836 FMT_TO_STR(WINED3DFMT_R32_UINT
);
837 FMT_TO_STR(WINED3DFMT_R32_SINT
);
838 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS
);
839 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT
);
840 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS
);
841 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT
);
842 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS
);
843 FMT_TO_STR(WINED3DFMT_R8G8_UNORM
);
844 FMT_TO_STR(WINED3DFMT_R8G8_UINT
);
845 FMT_TO_STR(WINED3DFMT_R8G8_SNORM
);
846 FMT_TO_STR(WINED3DFMT_R8G8_SINT
);
847 FMT_TO_STR(WINED3DFMT_R16_TYPELESS
);
848 FMT_TO_STR(WINED3DFMT_R16_FLOAT
);
849 FMT_TO_STR(WINED3DFMT_D16_UNORM
);
850 FMT_TO_STR(WINED3DFMT_R16_UNORM
);
851 FMT_TO_STR(WINED3DFMT_R16_UINT
);
852 FMT_TO_STR(WINED3DFMT_R16_SNORM
);
853 FMT_TO_STR(WINED3DFMT_R16_SINT
);
854 FMT_TO_STR(WINED3DFMT_R8_TYPELESS
);
855 FMT_TO_STR(WINED3DFMT_R8_UNORM
);
856 FMT_TO_STR(WINED3DFMT_R8_UINT
);
857 FMT_TO_STR(WINED3DFMT_R8_SNORM
);
858 FMT_TO_STR(WINED3DFMT_R8_SINT
);
859 FMT_TO_STR(WINED3DFMT_A8_UNORM
);
860 FMT_TO_STR(WINED3DFMT_R1_UNORM
);
861 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP
);
862 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM
);
863 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM
);
864 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS
);
865 FMT_TO_STR(WINED3DFMT_BC1_UNORM
);
866 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB
);
867 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS
);
868 FMT_TO_STR(WINED3DFMT_BC2_UNORM
);
869 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB
);
870 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS
);
871 FMT_TO_STR(WINED3DFMT_BC3_UNORM
);
872 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB
);
873 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS
);
874 FMT_TO_STR(WINED3DFMT_BC4_UNORM
);
875 FMT_TO_STR(WINED3DFMT_BC4_SNORM
);
876 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS
);
877 FMT_TO_STR(WINED3DFMT_BC5_UNORM
);
878 FMT_TO_STR(WINED3DFMT_BC5_SNORM
);
879 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM
);
880 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM
);
881 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM
);
882 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM
);
887 fourcc
[0] = (char)(fmt
);
888 fourcc
[1] = (char)(fmt
>> 8);
889 fourcc
[2] = (char)(fmt
>> 16);
890 fourcc
[3] = (char)(fmt
>> 24);
892 if( isprint(fourcc
[0]) && isprint(fourcc
[1]) && isprint(fourcc
[2]) && isprint(fourcc
[3]) )
893 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt
, fourcc
);
895 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt
);
897 return "unrecognized";
901 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype
) {
903 #define DEVTYPE_TO_STR(dev) case dev: return #dev
904 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL
);
905 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF
);
906 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW
);
907 #undef DEVTYPE_TO_STR
909 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype
);
910 return "unrecognized";
914 const char *debug_d3dusage(DWORD usage
)
919 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
920 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET
);
921 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL
);
922 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY
);
923 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING
);
924 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP
);
925 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS
);
926 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES
);
927 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES
);
928 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC
);
929 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP
);
930 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP
);
931 #undef WINED3DUSAGE_TO_STR
932 if (usage
) FIXME("Unrecognized usage flag(s) %#x\n", usage
);
934 return buf
[0] ? wine_dbg_sprintf("%s", &buf
[3]) : "0";
937 const char *debug_d3dusagequery(DWORD usagequery
)
942 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
943 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER
);
944 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP
);
945 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
);
946 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD
);
947 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE
);
948 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE
);
949 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP
);
950 #undef WINED3DUSAGEQUERY_TO_STR
951 if (usagequery
) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery
);
953 return buf
[0] ? wine_dbg_sprintf("%s", &buf
[3]) : "0";
956 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method
) {
958 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
959 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT
);
960 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU
);
961 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV
);
962 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV
);
963 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV
);
964 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP
);
965 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED
);
966 #undef WINED3DDECLMETHOD_TO_STR
968 FIXME("Unrecognized %u declaration method!\n", method
);
969 return "unrecognized";
973 const char* debug_d3ddeclusage(BYTE usage
) {
975 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
976 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION
);
977 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT
);
978 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES
);
979 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL
);
980 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE
);
981 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD
);
982 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT
);
983 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL
);
984 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR
);
985 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT
);
986 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR
);
987 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG
);
988 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH
);
989 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE
);
990 #undef WINED3DDECLUSAGE_TO_STR
992 FIXME("Unrecognized %u declaration usage!\n", usage
);
993 return "unrecognized";
997 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res
) {
999 #define RES_TO_STR(res) case res: return #res
1000 RES_TO_STR(WINED3DRTYPE_SURFACE
);
1001 RES_TO_STR(WINED3DRTYPE_VOLUME
);
1002 RES_TO_STR(WINED3DRTYPE_TEXTURE
);
1003 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE
);
1004 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE
);
1005 RES_TO_STR(WINED3DRTYPE_BUFFER
);
1008 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res
);
1009 return "unrecognized";
1013 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType
) {
1014 switch (PrimitiveType
) {
1015 #define PRIM_TO_STR(prim) case prim: return #prim
1016 PRIM_TO_STR(WINED3DPT_UNDEFINED
);
1017 PRIM_TO_STR(WINED3DPT_POINTLIST
);
1018 PRIM_TO_STR(WINED3DPT_LINELIST
);
1019 PRIM_TO_STR(WINED3DPT_LINESTRIP
);
1020 PRIM_TO_STR(WINED3DPT_TRIANGLELIST
);
1021 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP
);
1022 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN
);
1023 PRIM_TO_STR(WINED3DPT_LINELIST_ADJ
);
1024 PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ
);
1025 PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ
);
1026 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ
);
1029 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType
);
1030 return "unrecognized";
1034 const char* debug_d3drenderstate(DWORD state
) {
1036 #define D3DSTATE_TO_STR(u) case u: return #u
1037 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE
);
1038 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS
);
1039 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS
);
1040 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE
);
1041 D3DSTATE_TO_STR(WINED3DRS_WRAPU
);
1042 D3DSTATE_TO_STR(WINED3DRS_WRAPV
);
1043 D3DSTATE_TO_STR(WINED3DRS_ZENABLE
);
1044 D3DSTATE_TO_STR(WINED3DRS_FILLMODE
);
1045 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE
);
1046 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN
);
1047 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE
);
1048 D3DSTATE_TO_STR(WINED3DRS_ROP2
);
1049 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK
);
1050 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE
);
1051 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE
);
1052 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL
);
1053 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG
);
1054 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN
);
1055 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND
);
1056 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND
);
1057 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND
);
1058 D3DSTATE_TO_STR(WINED3DRS_CULLMODE
);
1059 D3DSTATE_TO_STR(WINED3DRS_ZFUNC
);
1060 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF
);
1061 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC
);
1062 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE
);
1063 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE
);
1064 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE
);
1065 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE
);
1066 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE
);
1067 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL
);
1068 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX
);
1069 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA
);
1070 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR
);
1071 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE
);
1072 D3DSTATE_TO_STR(WINED3DRS_FOGSTART
);
1073 D3DSTATE_TO_STR(WINED3DRS_FOGEND
);
1074 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY
);
1075 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE
);
1076 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS
);
1077 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE
);
1078 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR
);
1079 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU
);
1080 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV
);
1081 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS
);
1082 D3DSTATE_TO_STR(WINED3DRS_ZBIAS
);
1083 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE
);
1084 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY
);
1085 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH
);
1086 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT
);
1087 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE
);
1088 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL
);
1089 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL
);
1090 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS
);
1091 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC
);
1092 D3DSTATE_TO_STR(WINED3DRS_STENCILREF
);
1093 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK
);
1094 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK
);
1095 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR
);
1096 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00
);
1097 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01
);
1098 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02
);
1099 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03
);
1100 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04
);
1101 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05
);
1102 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06
);
1103 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07
);
1104 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08
);
1105 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09
);
1106 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10
);
1107 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11
);
1108 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12
);
1109 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13
);
1110 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14
);
1111 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15
);
1112 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16
);
1113 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17
);
1114 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18
);
1115 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19
);
1116 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20
);
1117 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21
);
1118 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22
);
1119 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23
);
1120 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24
);
1121 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25
);
1122 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26
);
1123 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27
);
1124 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28
);
1125 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29
);
1126 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30
);
1127 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31
);
1128 D3DSTATE_TO_STR(WINED3DRS_WRAP0
);
1129 D3DSTATE_TO_STR(WINED3DRS_WRAP1
);
1130 D3DSTATE_TO_STR(WINED3DRS_WRAP2
);
1131 D3DSTATE_TO_STR(WINED3DRS_WRAP3
);
1132 D3DSTATE_TO_STR(WINED3DRS_WRAP4
);
1133 D3DSTATE_TO_STR(WINED3DRS_WRAP5
);
1134 D3DSTATE_TO_STR(WINED3DRS_WRAP6
);
1135 D3DSTATE_TO_STR(WINED3DRS_WRAP7
);
1136 D3DSTATE_TO_STR(WINED3DRS_CLIPPING
);
1137 D3DSTATE_TO_STR(WINED3DRS_LIGHTING
);
1138 D3DSTATE_TO_STR(WINED3DRS_EXTENTS
);
1139 D3DSTATE_TO_STR(WINED3DRS_AMBIENT
);
1140 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE
);
1141 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX
);
1142 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER
);
1143 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS
);
1144 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE
);
1145 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE
);
1146 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE
);
1147 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE
);
1148 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE
);
1149 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND
);
1150 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE
);
1151 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING
);
1152 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE
);
1153 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN
);
1154 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE
);
1155 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE
);
1156 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A
);
1157 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B
);
1158 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C
);
1159 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS
);
1160 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK
);
1161 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE
);
1162 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS
);
1163 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN
);
1164 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX
);
1165 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE
);
1166 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE
);
1167 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR
);
1168 D3DSTATE_TO_STR(WINED3DRS_BLENDOP
);
1169 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE
);
1170 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE
);
1171 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE
);
1172 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS
);
1173 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE
);
1174 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL
);
1175 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL
);
1176 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X
);
1177 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y
);
1178 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z
);
1179 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W
);
1180 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION
);
1181 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE
);
1182 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL
);
1183 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL
);
1184 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS
);
1185 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC
);
1186 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1
);
1187 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2
);
1188 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3
);
1189 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR
);
1190 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE
);
1191 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS
);
1192 D3DSTATE_TO_STR(WINED3DRS_WRAP8
);
1193 D3DSTATE_TO_STR(WINED3DRS_WRAP9
);
1194 D3DSTATE_TO_STR(WINED3DRS_WRAP10
);
1195 D3DSTATE_TO_STR(WINED3DRS_WRAP11
);
1196 D3DSTATE_TO_STR(WINED3DRS_WRAP12
);
1197 D3DSTATE_TO_STR(WINED3DRS_WRAP13
);
1198 D3DSTATE_TO_STR(WINED3DRS_WRAP14
);
1199 D3DSTATE_TO_STR(WINED3DRS_WRAP15
);
1200 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE
);
1201 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA
);
1202 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA
);
1203 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA
);
1204 #undef D3DSTATE_TO_STR
1206 FIXME("Unrecognized %u render state!\n", state
);
1207 return "unrecognized";
1211 const char* debug_d3dsamplerstate(DWORD state
) {
1213 #define D3DSTATE_TO_STR(u) case u: return #u
1214 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR
);
1215 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU
);
1216 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV
);
1217 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW
);
1218 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER
);
1219 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER
);
1220 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER
);
1221 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS
);
1222 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL
);
1223 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY
);
1224 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE
);
1225 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX
);
1226 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET
);
1227 #undef D3DSTATE_TO_STR
1229 FIXME("Unrecognized %u sampler state!\n", state
);
1230 return "unrecognized";
1234 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type
) {
1235 switch (filter_type
) {
1236 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1237 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE
);
1238 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT
);
1239 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR
);
1240 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC
);
1241 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC
);
1242 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC
);
1243 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD
);
1244 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD
);
1245 #undef D3DTEXTUREFILTERTYPE_TO_STR
1247 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type
);
1248 return "unrecognized";
1252 const char* debug_d3dtexturestate(DWORD state
) {
1254 #define D3DSTATE_TO_STR(u) case u: return #u
1255 D3DSTATE_TO_STR(WINED3DTSS_COLOROP
);
1256 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1
);
1257 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2
);
1258 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP
);
1259 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1
);
1260 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2
);
1261 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00
);
1262 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01
);
1263 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10
);
1264 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11
);
1265 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX
);
1266 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE
);
1267 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET
);
1268 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS
);
1269 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0
);
1270 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0
);
1271 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG
);
1272 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT
);
1273 #undef D3DSTATE_TO_STR
1275 FIXME("Unrecognized %u texture state!\n", state
);
1276 return "unrecognized";
1280 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop
) {
1282 #define D3DTOP_TO_STR(u) case u: return #u
1283 D3DTOP_TO_STR(WINED3DTOP_DISABLE
);
1284 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1
);
1285 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2
);
1286 D3DTOP_TO_STR(WINED3DTOP_MODULATE
);
1287 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X
);
1288 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X
);
1289 D3DTOP_TO_STR(WINED3DTOP_ADD
);
1290 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED
);
1291 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X
);
1292 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT
);
1293 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH
);
1294 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA
);
1295 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA
);
1296 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA
);
1297 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM
);
1298 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA
);
1299 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE
);
1300 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR
);
1301 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA
);
1302 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR
);
1303 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA
);
1304 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP
);
1305 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE
);
1306 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3
);
1307 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD
);
1308 D3DTOP_TO_STR(WINED3DTOP_LERP
);
1309 #undef D3DTOP_TO_STR
1311 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop
);
1312 return "unrecognized";
1316 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype
) {
1318 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1319 TSTYPE_TO_STR(WINED3DTS_VIEW
);
1320 TSTYPE_TO_STR(WINED3DTS_PROJECTION
);
1321 TSTYPE_TO_STR(WINED3DTS_TEXTURE0
);
1322 TSTYPE_TO_STR(WINED3DTS_TEXTURE1
);
1323 TSTYPE_TO_STR(WINED3DTS_TEXTURE2
);
1324 TSTYPE_TO_STR(WINED3DTS_TEXTURE3
);
1325 TSTYPE_TO_STR(WINED3DTS_TEXTURE4
);
1326 TSTYPE_TO_STR(WINED3DTS_TEXTURE5
);
1327 TSTYPE_TO_STR(WINED3DTS_TEXTURE6
);
1328 TSTYPE_TO_STR(WINED3DTS_TEXTURE7
);
1329 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1330 #undef TSTYPE_TO_STR
1332 if (tstype
> 256 && tstype
< 512) {
1333 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype
);
1334 return ("WINED3DTS_WORLDMATRIX > 0");
1336 FIXME("Unrecognized %u WINED3DTS\n", tstype
);
1337 return "unrecognized";
1341 const char* debug_d3dpool(WINED3DPOOL Pool
) {
1343 #define POOL_TO_STR(p) case p: return #p
1344 POOL_TO_STR(WINED3DPOOL_DEFAULT
);
1345 POOL_TO_STR(WINED3DPOOL_MANAGED
);
1346 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM
);
1347 POOL_TO_STR(WINED3DPOOL_SCRATCH
);
1350 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool
);
1351 return "unrecognized";
1355 const char *debug_fbostatus(GLenum status
) {
1357 #define FBOSTATUS_TO_STR(u) case u: return #u
1358 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT
);
1359 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
);
1360 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT
);
1361 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
);
1362 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
);
1363 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT
);
1364 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT
);
1365 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT
);
1366 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT
);
1367 #undef FBOSTATUS_TO_STR
1369 FIXME("Unrecognied FBO status 0x%08x\n", status
);
1370 return "unrecognized";
1374 const char *debug_glerror(GLenum error
) {
1376 #define GLERROR_TO_STR(u) case u: return #u
1377 GLERROR_TO_STR(GL_NO_ERROR
);
1378 GLERROR_TO_STR(GL_INVALID_ENUM
);
1379 GLERROR_TO_STR(GL_INVALID_VALUE
);
1380 GLERROR_TO_STR(GL_INVALID_OPERATION
);
1381 GLERROR_TO_STR(GL_STACK_OVERFLOW
);
1382 GLERROR_TO_STR(GL_STACK_UNDERFLOW
);
1383 GLERROR_TO_STR(GL_OUT_OF_MEMORY
);
1384 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT
);
1385 #undef GLERROR_TO_STR
1387 FIXME("Unrecognied GL error 0x%08x\n", error
);
1388 return "unrecognized";
1392 const char *debug_d3dbasis(WINED3DBASISTYPE basis
) {
1394 case WINED3DBASIS_BEZIER
: return "WINED3DBASIS_BEZIER";
1395 case WINED3DBASIS_BSPLINE
: return "WINED3DBASIS_BSPLINE";
1396 case WINED3DBASIS_INTERPOLATE
: return "WINED3DBASIS_INTERPOLATE";
1397 default: return "unrecognized";
1401 const char *debug_d3ddegree(WINED3DDEGREETYPE degree
) {
1403 case WINED3DDEGREE_LINEAR
: return "WINED3DDEGREE_LINEAR";
1404 case WINED3DDEGREE_QUADRATIC
: return "WINED3DDEGREE_QUADRATIC";
1405 case WINED3DDEGREE_CUBIC
: return "WINED3DDEGREE_CUBIC";
1406 case WINED3DDEGREE_QUINTIC
: return "WINED3DDEGREE_QUINTIC";
1407 default: return "unrecognized";
1411 static const char *debug_fixup_channel_source(enum fixup_channel_source source
)
1415 #define WINED3D_TO_STR(x) case x: return #x
1416 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO
);
1417 WINED3D_TO_STR(CHANNEL_SOURCE_ONE
);
1418 WINED3D_TO_STR(CHANNEL_SOURCE_X
);
1419 WINED3D_TO_STR(CHANNEL_SOURCE_Y
);
1420 WINED3D_TO_STR(CHANNEL_SOURCE_Z
);
1421 WINED3D_TO_STR(CHANNEL_SOURCE_W
);
1422 WINED3D_TO_STR(CHANNEL_SOURCE_YUV0
);
1423 WINED3D_TO_STR(CHANNEL_SOURCE_YUV1
);
1424 #undef WINED3D_TO_STR
1426 FIXME("Unrecognized fixup_channel_source %#x\n", source
);
1427 return "unrecognized";
1431 static const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup
)
1435 #define WINED3D_TO_STR(x) case x: return #x
1436 WINED3D_TO_STR(YUV_FIXUP_YUY2
);
1437 WINED3D_TO_STR(YUV_FIXUP_UYVY
);
1438 WINED3D_TO_STR(YUV_FIXUP_YV12
);
1439 #undef WINED3D_TO_STR
1441 FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup
);
1442 return "unrecognized";
1446 void dump_color_fixup_desc(struct color_fixup_desc fixup
)
1448 if (is_yuv_fixup(fixup
))
1450 TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup
)));
1454 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup
.x_source
), fixup
.x_sign_fixup
? ", SIGN_FIXUP" : "");
1455 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup
.y_source
), fixup
.y_sign_fixup
? ", SIGN_FIXUP" : "");
1456 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup
.z_source
), fixup
.z_sign_fixup
? ", SIGN_FIXUP" : "");
1457 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup
.w_source
), fixup
.w_sign_fixup
? ", SIGN_FIXUP" : "");
1460 const char *debug_surflocation(DWORD flag
) {
1464 if(flag
& SFLAG_INSYSMEM
) strcat(buf
, " | SFLAG_INSYSMEM");
1465 if(flag
& SFLAG_INDRAWABLE
) strcat(buf
, " | SFLAG_INDRAWABLE");
1466 if(flag
& SFLAG_INTEXTURE
) strcat(buf
, " | SFLAG_INTEXTURE");
1467 if(flag
& SFLAG_INSRGBTEX
) strcat(buf
, " | SFLAG_INSRGBTEX");
1468 return wine_dbg_sprintf("%s", buf
[0] ? buf
+ 3 : "0");
1471 /*****************************************************************************
1472 * Useful functions mapping GL <-> D3D values
1474 GLenum
StencilOp(DWORD op
) {
1476 case WINED3DSTENCILOP_KEEP
: return GL_KEEP
;
1477 case WINED3DSTENCILOP_ZERO
: return GL_ZERO
;
1478 case WINED3DSTENCILOP_REPLACE
: return GL_REPLACE
;
1479 case WINED3DSTENCILOP_INCRSAT
: return GL_INCR
;
1480 case WINED3DSTENCILOP_DECRSAT
: return GL_DECR
;
1481 case WINED3DSTENCILOP_INVERT
: return GL_INVERT
;
1482 case WINED3DSTENCILOP_INCR
: return GL_INCR_WRAP_EXT
;
1483 case WINED3DSTENCILOP_DECR
: return GL_DECR_WRAP_EXT
;
1485 FIXME("Unrecognized stencil op %d\n", op
);
1490 GLenum
CompareFunc(DWORD func
) {
1491 switch ((WINED3DCMPFUNC
)func
) {
1492 case WINED3DCMP_NEVER
: return GL_NEVER
;
1493 case WINED3DCMP_LESS
: return GL_LESS
;
1494 case WINED3DCMP_EQUAL
: return GL_EQUAL
;
1495 case WINED3DCMP_LESSEQUAL
: return GL_LEQUAL
;
1496 case WINED3DCMP_GREATER
: return GL_GREATER
;
1497 case WINED3DCMP_NOTEQUAL
: return GL_NOTEQUAL
;
1498 case WINED3DCMP_GREATEREQUAL
: return GL_GEQUAL
;
1499 case WINED3DCMP_ALWAYS
: return GL_ALWAYS
;
1501 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func
);
1506 BOOL
is_invalid_op(IWineD3DDeviceImpl
*This
, int stage
, WINED3DTEXTUREOP op
, DWORD arg1
, DWORD arg2
, DWORD arg3
) {
1507 if (op
== WINED3DTOP_DISABLE
) return FALSE
;
1508 if (This
->stateBlock
->textures
[stage
]) return FALSE
;
1510 if ((arg1
& WINED3DTA_SELECTMASK
) == WINED3DTA_TEXTURE
1511 && op
!= WINED3DTOP_SELECTARG2
) return TRUE
;
1512 if ((arg2
& WINED3DTA_SELECTMASK
) == WINED3DTA_TEXTURE
1513 && op
!= WINED3DTOP_SELECTARG1
) return TRUE
;
1514 if ((arg3
& WINED3DTA_SELECTMASK
) == WINED3DTA_TEXTURE
1515 && (op
== WINED3DTOP_MULTIPLYADD
|| op
== WINED3DTOP_LERP
)) return TRUE
;
1520 /* Setup this textures matrix according to the texture flags*/
1521 /* GL locking is done by the caller (state handler) */
1522 void set_texture_matrix(const float *smat
, DWORD flags
, BOOL calculatedCoords
, BOOL transformed
,
1523 WINED3DFORMAT vtx_fmt
, BOOL ffp_proj_control
)
1527 glMatrixMode(GL_TEXTURE
);
1528 checkGLcall("glMatrixMode(GL_TEXTURE)");
1530 if (flags
== WINED3DTTFF_DISABLE
|| flags
== WINED3DTTFF_COUNT1
|| transformed
) {
1532 checkGLcall("glLoadIdentity()");
1536 if (flags
== (WINED3DTTFF_COUNT1
|WINED3DTTFF_PROJECTED
)) {
1537 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1541 memcpy(mat
, smat
, 16 * sizeof(float));
1543 if (flags
& WINED3DTTFF_PROJECTED
) {
1544 if(!ffp_proj_control
) {
1545 switch (flags
& ~WINED3DTTFF_PROJECTED
) {
1546 case WINED3DTTFF_COUNT2
:
1547 mat
[3] = mat
[1], mat
[7] = mat
[5], mat
[11] = mat
[9], mat
[15] = mat
[13];
1548 mat
[1] = mat
[5] = mat
[9] = mat
[13] = 0;
1550 case WINED3DTTFF_COUNT3
:
1551 mat
[3] = mat
[2], mat
[7] = mat
[6], mat
[11] = mat
[10], mat
[15] = mat
[14];
1552 mat
[2] = mat
[6] = mat
[10] = mat
[14] = 0;
1556 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1557 if(!calculatedCoords
) {
1560 case WINED3DFMT_R32_FLOAT
:
1561 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1562 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1563 * the input value to the transformation will be 0, so the matrix value is irrelevant
1570 case WINED3DFMT_R32G32_FLOAT
:
1571 /* See above, just 3rd and 4th coord
1578 case WINED3DFMT_R32G32B32_FLOAT
: /* Opengl defaults match dx defaults */
1579 case WINED3DFMT_R32G32B32A32_FLOAT
: /* No defaults apply, all app defined */
1581 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1582 * into a bad place. The division elimination below will apply to make sure the
1583 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1585 case WINED3DFMT_UNKNOWN
: /* No texture coords, 0/0/0/1 defaults are passed */
1588 FIXME("Unexpected fixed function texture coord input\n");
1591 if(!ffp_proj_control
) {
1592 switch (flags
& ~WINED3DTTFF_PROJECTED
) {
1593 /* case WINED3DTTFF_COUNT1: Won't ever get here */
1594 case WINED3DTTFF_COUNT2
: mat
[2] = mat
[6] = mat
[10] = mat
[14] = 0;
1595 /* OpenGL divides the first 3 vertex coord by the 4th by default,
1596 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
1597 * the 4th coord evaluates to 1.0 to eliminate that.
1599 * If the fixed function pipeline is used, the 4th value remains unused,
1600 * so there is no danger in doing this. With vertex shaders we have a
1601 * problem. Should an app hit that problem, the code here would have to
1602 * check for pixel shaders, and the shader has to undo the default gl divide.
1604 * A more serious problem occurs if the app passes 4 coordinates in, and the
1605 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
1606 * or a replacement shader
1608 default: mat
[3] = mat
[7] = mat
[11] = 0; mat
[15] = 1;
1614 checkGLcall("glLoadMatrixf(mat)");
1616 #undef GLINFO_LOCATION
1618 /* This small helper function is used to convert a bitmask into the number of masked bits */
1619 unsigned int count_bits(unsigned int mask
)
1622 for (count
= 0; mask
; ++count
)
1629 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
1630 * The later function requires individual color components. */
1631 BOOL
getColorBits(const struct GlPixelFormatDesc
*format_desc
,
1632 short *redSize
, short *greenSize
, short *blueSize
, short *alphaSize
, short *totalSize
)
1634 TRACE("fmt: %s\n", debug_d3dformat(format_desc
->format
));
1635 switch(format_desc
->format
)
1637 case WINED3DFMT_X8R8G8B8
:
1638 case WINED3DFMT_R8G8B8
:
1639 case WINED3DFMT_A8R8G8B8
:
1640 case WINED3DFMT_R8G8B8A8_UNORM
:
1641 case WINED3DFMT_A2R10G10B10
:
1642 case WINED3DFMT_X1R5G5B5
:
1643 case WINED3DFMT_A1R5G5B5
:
1644 case WINED3DFMT_R5G6B5
:
1645 case WINED3DFMT_X4R4G4B4
:
1646 case WINED3DFMT_A4R4G4B4
:
1647 case WINED3DFMT_R3G3B2
:
1648 case WINED3DFMT_A8P8
:
1652 ERR("Unsupported format: %s\n", debug_d3dformat(format_desc
->format
));
1656 *redSize
= count_bits(format_desc
->red_mask
);
1657 *greenSize
= count_bits(format_desc
->green_mask
);
1658 *blueSize
= count_bits(format_desc
->blue_mask
);
1659 *alphaSize
= count_bits(format_desc
->alpha_mask
);
1660 *totalSize
= *redSize
+ *greenSize
+ *blueSize
+ *alphaSize
;
1662 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n",
1663 *redSize
, *greenSize
, *blueSize
, *alphaSize
, *totalSize
, debug_d3dformat(format_desc
->format
));
1667 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
1668 BOOL
getDepthStencilBits(const struct GlPixelFormatDesc
*format_desc
, short *depthSize
, short *stencilSize
)
1670 TRACE("fmt: %s\n", debug_d3dformat(format_desc
->format
));
1671 switch(format_desc
->format
)
1673 case WINED3DFMT_D16_LOCKABLE
:
1674 case WINED3DFMT_D16_UNORM
:
1675 case WINED3DFMT_D15S1
:
1676 case WINED3DFMT_D24X8
:
1677 case WINED3DFMT_D24X4S4
:
1678 case WINED3DFMT_D24S8
:
1679 case WINED3DFMT_D24FS8
:
1680 case WINED3DFMT_D32
:
1681 case WINED3DFMT_D32F_LOCKABLE
:
1684 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(format_desc
->format
));
1688 *depthSize
= format_desc
->depth_size
;
1689 *stencilSize
= format_desc
->stencil_size
;
1691 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n",
1692 *depthSize
, *stencilSize
, debug_d3dformat(format_desc
->format
));
1696 /* DirectDraw stuff */
1697 WINED3DFORMAT
pixelformat_for_depth(DWORD depth
) {
1699 case 8: return WINED3DFMT_P8
;
1700 case 15: return WINED3DFMT_X1R5G5B5
;
1701 case 16: return WINED3DFMT_R5G6B5
;
1702 case 24: return WINED3DFMT_X8R8G8B8
; /* Robots needs 24bit to be X8R8G8B8 */
1703 case 32: return WINED3DFMT_X8R8G8B8
; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
1704 default: return WINED3DFMT_UNKNOWN
;
1708 void multiply_matrix(WINED3DMATRIX
*dest
, const WINED3DMATRIX
*src1
, const WINED3DMATRIX
*src2
) {
1711 /* Now do the multiplication 'by hand'.
1712 I know that all this could be optimised, but this will be done later :-) */
1713 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
);
1714 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
);
1715 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
);
1716 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
);
1718 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
);
1719 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
);
1720 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
);
1721 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
);
1723 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
);
1724 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
);
1725 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
);
1726 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
);
1728 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
);
1729 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
);
1730 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
);
1731 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
);
1733 /* And copy the new matrix in the good storage.. */
1734 memcpy(dest
, &temp
, 16 * sizeof(float));
1737 DWORD
get_flexible_vertex_size(DWORD d3dvtVertexType
) {
1740 int numTextures
= (d3dvtVertexType
& WINED3DFVF_TEXCOUNT_MASK
) >> WINED3DFVF_TEXCOUNT_SHIFT
;
1742 if (d3dvtVertexType
& WINED3DFVF_NORMAL
) size
+= 3 * sizeof(float);
1743 if (d3dvtVertexType
& WINED3DFVF_DIFFUSE
) size
+= sizeof(DWORD
);
1744 if (d3dvtVertexType
& WINED3DFVF_SPECULAR
) size
+= sizeof(DWORD
);
1745 if (d3dvtVertexType
& WINED3DFVF_PSIZE
) size
+= sizeof(DWORD
);
1746 switch (d3dvtVertexType
& WINED3DFVF_POSITION_MASK
) {
1747 case WINED3DFVF_XYZ
: size
+= 3 * sizeof(float); break;
1748 case WINED3DFVF_XYZRHW
: size
+= 4 * sizeof(float); break;
1749 case WINED3DFVF_XYZB1
: size
+= 4 * sizeof(float); break;
1750 case WINED3DFVF_XYZB2
: size
+= 5 * sizeof(float); break;
1751 case WINED3DFVF_XYZB3
: size
+= 6 * sizeof(float); break;
1752 case WINED3DFVF_XYZB4
: size
+= 7 * sizeof(float); break;
1753 case WINED3DFVF_XYZB5
: size
+= 8 * sizeof(float); break;
1754 case WINED3DFVF_XYZW
: size
+= 4 * sizeof(float); break;
1755 default: ERR("Unexpected position mask\n");
1757 for (i
= 0; i
< numTextures
; i
++) {
1758 size
+= GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType
, i
) * sizeof(float);
1764 /***********************************************************************
1767 * Calculates the dimensions of the opengl texture used for blits.
1768 * Handled oversized opengl textures and updates the source rectangle
1772 * This: Surface to operate on
1773 * Rect: Requested rectangle
1776 * TRUE if the texture part can be loaded,
1779 *********************************************************************/
1780 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
1782 BOOL
CalculateTexRect(IWineD3DSurfaceImpl
*This
, RECT
*Rect
, float glTexCoord
[4]) {
1783 int x1
= Rect
->left
, x2
= Rect
->right
;
1784 int y1
= Rect
->top
, y2
= Rect
->bottom
;
1785 GLint maxSize
= GL_LIMITS(texture_size
);
1787 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This
,
1788 Rect
->left
, Rect
->top
, Rect
->right
, Rect
->bottom
);
1790 /* The sizes might be reversed */
1791 if(Rect
->left
> Rect
->right
) {
1795 if(Rect
->top
> Rect
->bottom
) {
1800 /* No oversized texture? This is easy */
1801 if(!(This
->Flags
& SFLAG_OVERSIZE
)) {
1802 /* Which rect from the texture do I need? */
1803 if(This
->glDescription
.target
== GL_TEXTURE_RECTANGLE_ARB
) {
1804 glTexCoord
[0] = (float) Rect
->left
;
1805 glTexCoord
[2] = (float) Rect
->top
;
1806 glTexCoord
[1] = (float) Rect
->right
;
1807 glTexCoord
[3] = (float) Rect
->bottom
;
1809 glTexCoord
[0] = (float) Rect
->left
/ (float) This
->pow2Width
;
1810 glTexCoord
[2] = (float) Rect
->top
/ (float) This
->pow2Height
;
1811 glTexCoord
[1] = (float) Rect
->right
/ (float) This
->pow2Width
;
1812 glTexCoord
[3] = (float) Rect
->bottom
/ (float) This
->pow2Height
;
1817 /* Check if we can succeed at all */
1818 if( (x2
- x1
) > maxSize
||
1819 (y2
- y1
) > maxSize
) {
1820 TRACE("Requested rectangle is too large for gl\n");
1824 /* A part of the texture has to be picked. First, check if
1825 * some texture part is loaded already, if yes try to re-use it.
1826 * If the texture is dirty, or the part can't be used,
1827 * re-position the part to load
1829 if(This
->Flags
& SFLAG_INTEXTURE
) {
1830 if(This
->glRect
.left
<= x1
&& This
->glRect
.right
>= x2
&&
1831 This
->glRect
.top
<= y1
&& This
->glRect
.bottom
>= x2
) {
1832 /* Ok, the rectangle is ok, re-use it */
1833 TRACE("Using existing gl Texture\n");
1835 /* Rectangle is not ok, dirtify the texture to reload it */
1836 TRACE("Dirtifying texture to force reload\n");
1837 This
->Flags
&= ~SFLAG_INTEXTURE
;
1841 /* Now if we are dirty(no else if!) */
1842 if(!(This
->Flags
& SFLAG_INTEXTURE
)) {
1843 /* Set the new rectangle. Use the following strategy:
1844 * 1) Use as big textures as possible.
1845 * 2) Place the texture part in the way that the requested
1846 * part is in the middle of the texture(well, almost)
1847 * 3) If the texture is moved over the edges of the
1848 * surface, replace it nicely
1849 * 4) If the coord is not limiting the texture size,
1850 * use the whole size
1852 if((This
->pow2Width
) > maxSize
) {
1853 This
->glRect
.left
= x1
- maxSize
/ 2;
1854 if(This
->glRect
.left
< 0) {
1855 This
->glRect
.left
= 0;
1857 This
->glRect
.right
= This
->glRect
.left
+ maxSize
;
1858 if(This
->glRect
.right
> This
->currentDesc
.Width
) {
1859 This
->glRect
.right
= This
->currentDesc
.Width
;
1860 This
->glRect
.left
= This
->glRect
.right
- maxSize
;
1863 This
->glRect
.left
= 0;
1864 This
->glRect
.right
= This
->pow2Width
;
1867 if(This
->pow2Height
> maxSize
) {
1868 This
->glRect
.top
= x1
- GL_LIMITS(texture_size
) / 2;
1869 if(This
->glRect
.top
< 0) This
->glRect
.top
= 0;
1870 This
->glRect
.bottom
= This
->glRect
.left
+ maxSize
;
1871 if(This
->glRect
.bottom
> This
->currentDesc
.Height
) {
1872 This
->glRect
.bottom
= This
->currentDesc
.Height
;
1873 This
->glRect
.top
= This
->glRect
.bottom
- maxSize
;
1876 This
->glRect
.top
= 0;
1877 This
->glRect
.bottom
= This
->pow2Height
;
1879 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This
,
1880 This
->glRect
.left
, This
->glRect
.top
, This
->glRect
.right
, This
->glRect
.bottom
);
1883 /* Re-calculate the rect to draw */
1884 Rect
->left
-= This
->glRect
.left
;
1885 Rect
->right
-= This
->glRect
.left
;
1886 Rect
->top
-= This
->glRect
.top
;
1887 Rect
->bottom
-= This
->glRect
.top
;
1889 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
1890 * or the pow2Width / pow2Height of the surface.
1892 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
1893 * as regular GL_TEXTURE_2D.
1895 glTexCoord
[0] = (float) Rect
->left
/ (float) (This
->glRect
.right
- This
->glRect
.left
);
1896 glTexCoord
[2] = (float) Rect
->top
/ (float) (This
->glRect
.bottom
- This
->glRect
.top
);
1897 glTexCoord
[1] = (float) Rect
->right
/ (float) (This
->glRect
.right
- This
->glRect
.left
);
1898 glTexCoord
[3] = (float) Rect
->bottom
/ (float) (This
->glRect
.bottom
- This
->glRect
.top
);
1902 #undef GLINFO_LOCATION
1904 /* Hash table functions */
1906 struct hash_table_t
*hash_table_create(hash_function_t
*hash_function
, compare_function_t
*compare_function
)
1908 struct hash_table_t
*table
;
1909 unsigned int initial_size
= 8;
1911 table
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct hash_table_t
) + (initial_size
* sizeof(struct list
)));
1914 ERR("Failed to allocate table, returning NULL.\n");
1918 table
->hash_function
= hash_function
;
1919 table
->compare_function
= compare_function
;
1921 table
->grow_size
= initial_size
- (initial_size
>> 2);
1922 table
->shrink_size
= 0;
1924 table
->buckets
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, initial_size
* sizeof(struct list
));
1925 if (!table
->buckets
)
1927 ERR("Failed to allocate table buckets, returning NULL.\n");
1928 HeapFree(GetProcessHeap(), 0, table
);
1931 table
->bucket_count
= initial_size
;
1933 table
->entries
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, table
->grow_size
* sizeof(struct hash_table_entry_t
));
1934 if (!table
->entries
)
1936 ERR("Failed to allocate table entries, returning NULL.\n");
1937 HeapFree(GetProcessHeap(), 0, table
->buckets
);
1938 HeapFree(GetProcessHeap(), 0, table
);
1941 table
->entry_count
= 0;
1943 list_init(&table
->free_entries
);
1949 void hash_table_destroy(struct hash_table_t
*table
, void (*free_value
)(void *value
, void *cb
), void *cb
)
1953 for (i
= 0; i
< table
->entry_count
; ++i
)
1956 free_value(table
->entries
[i
].value
, cb
);
1958 HeapFree(GetProcessHeap(), 0, table
->entries
[i
].key
);
1961 HeapFree(GetProcessHeap(), 0, table
->entries
);
1962 HeapFree(GetProcessHeap(), 0, table
->buckets
);
1963 HeapFree(GetProcessHeap(), 0, table
);
1966 void hash_table_for_each_entry(struct hash_table_t
*table
, void (*callback
)(void *value
, void *context
), void *context
)
1970 for (i
= 0; i
< table
->entry_count
; ++i
)
1972 callback(table
->entries
[i
].value
, context
);
1976 static inline struct hash_table_entry_t
*hash_table_get_by_idx(const struct hash_table_t
*table
, const void *key
,
1979 struct hash_table_entry_t
*entry
;
1981 if (table
->buckets
[idx
].next
)
1982 LIST_FOR_EACH_ENTRY(entry
, &(table
->buckets
[idx
]), struct hash_table_entry_t
, entry
)
1983 if (table
->compare_function(entry
->key
, key
)) return entry
;
1988 static BOOL
hash_table_resize(struct hash_table_t
*table
, unsigned int new_bucket_count
)
1990 unsigned int new_entry_count
= 0;
1991 struct hash_table_entry_t
*new_entries
;
1992 struct list
*new_buckets
;
1993 unsigned int grow_size
= new_bucket_count
- (new_bucket_count
>> 2);
1996 new_buckets
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, new_bucket_count
* sizeof(struct list
));
1999 ERR("Failed to allocate new buckets, returning FALSE.\n");
2003 new_entries
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, grow_size
* sizeof(struct hash_table_entry_t
));
2006 ERR("Failed to allocate new entries, returning FALSE.\n");
2007 HeapFree(GetProcessHeap(), 0, new_buckets
);
2011 for (i
= 0; i
< table
->bucket_count
; ++i
)
2013 if (table
->buckets
[i
].next
)
2015 struct hash_table_entry_t
*entry
, *entry2
;
2017 LIST_FOR_EACH_ENTRY_SAFE(entry
, entry2
, &table
->buckets
[i
], struct hash_table_entry_t
, entry
)
2020 struct hash_table_entry_t
*new_entry
= new_entries
+ (new_entry_count
++);
2021 *new_entry
= *entry
;
2023 j
= new_entry
->hash
& (new_bucket_count
- 1);
2025 if (!new_buckets
[j
].next
) list_init(&new_buckets
[j
]);
2026 list_add_head(&new_buckets
[j
], &new_entry
->entry
);
2031 HeapFree(GetProcessHeap(), 0, table
->buckets
);
2032 table
->buckets
= new_buckets
;
2034 HeapFree(GetProcessHeap(), 0, table
->entries
);
2035 table
->entries
= new_entries
;
2037 table
->entry_count
= new_entry_count
;
2038 list_init(&table
->free_entries
);
2040 table
->bucket_count
= new_bucket_count
;
2041 table
->grow_size
= grow_size
;
2042 table
->shrink_size
= new_bucket_count
> 8 ? new_bucket_count
>> 2 : 0;
2047 void hash_table_put(struct hash_table_t
*table
, void *key
, void *value
)
2051 struct hash_table_entry_t
*entry
;
2053 hash
= table
->hash_function(key
);
2054 idx
= hash
& (table
->bucket_count
- 1);
2055 entry
= hash_table_get_by_idx(table
, key
, idx
);
2059 HeapFree(GetProcessHeap(), 0, key
);
2060 entry
->value
= value
;
2064 HeapFree(GetProcessHeap(), 0, entry
->key
);
2067 /* Remove the entry */
2068 list_remove(&entry
->entry
);
2069 list_add_head(&table
->free_entries
, &entry
->entry
);
2073 /* Shrink if necessary */
2074 if (table
->count
< table
->shrink_size
) {
2075 if (!hash_table_resize(table
, table
->bucket_count
>> 1))
2077 ERR("Failed to shrink the table...\n");
2087 /* Grow if necessary */
2088 if (table
->count
>= table
->grow_size
)
2090 if (!hash_table_resize(table
, table
->bucket_count
<< 1))
2092 ERR("Failed to grow the table, returning.\n");
2096 idx
= hash
& (table
->bucket_count
- 1);
2099 /* Find an entry to insert */
2100 if (!list_empty(&table
->free_entries
))
2102 struct list
*elem
= list_head(&table
->free_entries
);
2105 entry
= LIST_ENTRY(elem
, struct hash_table_entry_t
, entry
);
2107 entry
= table
->entries
+ (table
->entry_count
++);
2110 /* Insert the entry */
2112 entry
->value
= value
;
2114 if (!table
->buckets
[idx
].next
) list_init(&table
->buckets
[idx
]);
2115 list_add_head(&table
->buckets
[idx
], &entry
->entry
);
2120 void hash_table_remove(struct hash_table_t
*table
, void *key
)
2122 hash_table_put(table
, key
, NULL
);
2125 void *hash_table_get(const struct hash_table_t
*table
, const void *key
)
2128 struct hash_table_entry_t
*entry
;
2130 idx
= table
->hash_function(key
) & (table
->bucket_count
- 1);
2131 entry
= hash_table_get_by_idx(table
, key
, idx
);
2133 return entry
? entry
->value
: NULL
;
2136 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2137 void gen_ffp_frag_op(IWineD3DStateBlockImpl
*stateblock
, struct ffp_frag_settings
*settings
, BOOL ignore_textype
) {
2141 static const unsigned char args
[WINED3DTOP_LERP
+ 1] = {
2143 /* D3DTOP_DISABLE */ 0,
2144 /* D3DTOP_SELECTARG1 */ ARG1
,
2145 /* D3DTOP_SELECTARG2 */ ARG2
,
2146 /* D3DTOP_MODULATE */ ARG1
| ARG2
,
2147 /* D3DTOP_MODULATE2X */ ARG1
| ARG2
,
2148 /* D3DTOP_MODULATE4X */ ARG1
| ARG2
,
2149 /* D3DTOP_ADD */ ARG1
| ARG2
,
2150 /* D3DTOP_ADDSIGNED */ ARG1
| ARG2
,
2151 /* D3DTOP_ADDSIGNED2X */ ARG1
| ARG2
,
2152 /* D3DTOP_SUBTRACT */ ARG1
| ARG2
,
2153 /* D3DTOP_ADDSMOOTH */ ARG1
| ARG2
,
2154 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1
| ARG2
,
2155 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1
| ARG2
,
2156 /* D3DTOP_BLENDFACTORALPHA */ ARG1
| ARG2
,
2157 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1
| ARG2
,
2158 /* D3DTOP_BLENDCURRENTALPHA */ ARG1
| ARG2
,
2159 /* D3DTOP_PREMODULATE */ ARG1
| ARG2
,
2160 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1
| ARG2
,
2161 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1
| ARG2
,
2162 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1
| ARG2
,
2163 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1
| ARG2
,
2164 /* D3DTOP_BUMPENVMAP */ ARG1
| ARG2
,
2165 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1
| ARG2
,
2166 /* D3DTOP_DOTPRODUCT3 */ ARG1
| ARG2
,
2167 /* D3DTOP_MULTIPLYADD */ ARG1
| ARG2
| ARG0
,
2168 /* D3DTOP_LERP */ ARG1
| ARG2
| ARG0
2172 DWORD cop
, aop
, carg0
, carg1
, carg2
, aarg0
, aarg1
, aarg2
;
2174 for(i
= 0; i
< GL_LIMITS(texture_stages
); i
++) {
2175 IWineD3DBaseTextureImpl
*texture
;
2176 settings
->op
[i
].padding
= 0;
2177 if(stateblock
->textureState
[i
][WINED3DTSS_COLOROP
] == WINED3DTOP_DISABLE
) {
2178 settings
->op
[i
].cop
= WINED3DTOP_DISABLE
;
2179 settings
->op
[i
].aop
= WINED3DTOP_DISABLE
;
2180 settings
->op
[i
].carg0
= settings
->op
[i
].carg1
= settings
->op
[i
].carg2
= ARG_UNUSED
;
2181 settings
->op
[i
].aarg0
= settings
->op
[i
].aarg1
= settings
->op
[i
].aarg2
= ARG_UNUSED
;
2182 settings
->op
[i
].color_fixup
= COLOR_FIXUP_IDENTITY
;
2183 settings
->op
[i
].dst
= resultreg
;
2184 settings
->op
[i
].tex_type
= tex_1d
;
2185 settings
->op
[i
].projected
= proj_none
;
2190 texture
= (IWineD3DBaseTextureImpl
*) stateblock
->textures
[i
];
2192 settings
->op
[i
].color_fixup
= texture
->resource
.format_desc
->color_fixup
;
2193 if(ignore_textype
) {
2194 settings
->op
[i
].tex_type
= tex_1d
;
2196 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture
*)texture
)) {
2198 settings
->op
[i
].tex_type
= tex_1d
;
2201 settings
->op
[i
].tex_type
= tex_2d
;
2204 settings
->op
[i
].tex_type
= tex_3d
;
2206 case GL_TEXTURE_CUBE_MAP_ARB
:
2207 settings
->op
[i
].tex_type
= tex_cube
;
2209 case GL_TEXTURE_RECTANGLE_ARB
:
2210 settings
->op
[i
].tex_type
= tex_rect
;
2215 settings
->op
[i
].color_fixup
= COLOR_FIXUP_IDENTITY
;
2216 settings
->op
[i
].tex_type
= tex_1d
;
2219 cop
= stateblock
->textureState
[i
][WINED3DTSS_COLOROP
];
2220 aop
= stateblock
->textureState
[i
][WINED3DTSS_ALPHAOP
];
2222 carg1
= (args
[cop
] & ARG1
) ? stateblock
->textureState
[i
][WINED3DTSS_COLORARG1
] : ARG_UNUSED
;
2223 carg2
= (args
[cop
] & ARG2
) ? stateblock
->textureState
[i
][WINED3DTSS_COLORARG2
] : ARG_UNUSED
;
2224 carg0
= (args
[cop
] & ARG0
) ? stateblock
->textureState
[i
][WINED3DTSS_COLORARG0
] : ARG_UNUSED
;
2226 if(is_invalid_op(stateblock
->wineD3DDevice
, i
, cop
,
2227 carg1
, carg2
, carg0
)) {
2230 carg1
= WINED3DTA_CURRENT
;
2231 cop
= WINED3DTOP_SELECTARG1
;
2234 if(cop
== WINED3DTOP_DOTPRODUCT3
) {
2235 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2236 * the color result to the alpha component of the destination
2243 aarg1
= (args
[aop
] & ARG1
) ? stateblock
->textureState
[i
][WINED3DTSS_ALPHAARG1
] : ARG_UNUSED
;
2244 aarg2
= (args
[aop
] & ARG2
) ? stateblock
->textureState
[i
][WINED3DTSS_ALPHAARG2
] : ARG_UNUSED
;
2245 aarg0
= (args
[aop
] & ARG0
) ? stateblock
->textureState
[i
][WINED3DTSS_ALPHAARG0
] : ARG_UNUSED
;
2248 if (i
== 0 && stateblock
->textures
[0] && stateblock
->renderState
[WINED3DRS_COLORKEYENABLE
])
2250 UINT texture_dimensions
= IWineD3DBaseTexture_GetTextureDimensions(stateblock
->textures
[0]);
2252 if (texture_dimensions
== GL_TEXTURE_2D
|| texture_dimensions
== GL_TEXTURE_RECTANGLE_ARB
)
2254 IWineD3DSurfaceImpl
*surf
;
2255 surf
= (IWineD3DSurfaceImpl
*) ((IWineD3DTextureImpl
*) stateblock
->textures
[0])->surfaces
[0];
2257 if (surf
->CKeyFlags
& WINEDDSD_CKSRCBLT
&& !surf
->resource
.format_desc
->alpha_mask
)
2259 if (aop
== WINED3DTOP_DISABLE
)
2261 aarg1
= WINED3DTA_TEXTURE
;
2262 aop
= WINED3DTOP_SELECTARG1
;
2264 else if (aop
== WINED3DTOP_SELECTARG1
&& aarg1
!= WINED3DTA_TEXTURE
)
2266 if (stateblock
->renderState
[WINED3DRS_ALPHABLENDENABLE
])
2268 aarg2
= WINED3DTA_TEXTURE
;
2269 aop
= WINED3DTOP_MODULATE
;
2271 else aarg1
= WINED3DTA_TEXTURE
;
2273 else if (aop
== WINED3DTOP_SELECTARG2
&& aarg2
!= WINED3DTA_TEXTURE
)
2275 if (stateblock
->renderState
[WINED3DRS_ALPHABLENDENABLE
])
2277 aarg1
= WINED3DTA_TEXTURE
;
2278 aop
= WINED3DTOP_MODULATE
;
2280 else aarg2
= WINED3DTA_TEXTURE
;
2286 if(is_invalid_op(stateblock
->wineD3DDevice
, i
, aop
,
2287 aarg1
, aarg2
, aarg0
)) {
2290 aarg1
= WINED3DTA_CURRENT
;
2291 aop
= WINED3DTOP_SELECTARG1
;
2294 if(carg1
== WINED3DTA_TEXTURE
|| carg2
== WINED3DTA_TEXTURE
|| carg0
== WINED3DTA_TEXTURE
||
2295 aarg1
== WINED3DTA_TEXTURE
|| aarg2
== WINED3DTA_TEXTURE
|| aarg0
== WINED3DTA_TEXTURE
) {
2296 ttff
= stateblock
->textureState
[i
][WINED3DTSS_TEXTURETRANSFORMFLAGS
];
2297 if(ttff
== (WINED3DTTFF_PROJECTED
| WINED3DTTFF_COUNT3
)) {
2298 settings
->op
[i
].projected
= proj_count3
;
2299 } else if(ttff
== (WINED3DTTFF_PROJECTED
| WINED3DTTFF_COUNT4
)) {
2300 settings
->op
[i
].projected
= proj_count4
;
2302 settings
->op
[i
].projected
= proj_none
;
2305 settings
->op
[i
].projected
= proj_none
;
2308 settings
->op
[i
].cop
= cop
;
2309 settings
->op
[i
].aop
= aop
;
2310 settings
->op
[i
].carg0
= carg0
;
2311 settings
->op
[i
].carg1
= carg1
;
2312 settings
->op
[i
].carg2
= carg2
;
2313 settings
->op
[i
].aarg0
= aarg0
;
2314 settings
->op
[i
].aarg1
= aarg1
;
2315 settings
->op
[i
].aarg2
= aarg2
;
2317 if(stateblock
->textureState
[i
][WINED3DTSS_RESULTARG
] == WINED3DTA_TEMP
) {
2318 settings
->op
[i
].dst
= tempreg
;
2320 settings
->op
[i
].dst
= resultreg
;
2324 /* Clear unsupported stages */
2325 for(; i
< MAX_TEXTURES
; i
++) {
2326 memset(&settings
->op
[i
], 0xff, sizeof(settings
->op
[i
]));
2329 if(stateblock
->renderState
[WINED3DRS_FOGENABLE
] == FALSE
) {
2330 settings
->fog
= FOG_OFF
;
2331 } else if(stateblock
->renderState
[WINED3DRS_FOGTABLEMODE
] == WINED3DFOG_NONE
) {
2332 if(use_vs(stateblock
) || ((IWineD3DVertexDeclarationImpl
*) stateblock
->vertexDecl
)->position_transformed
) {
2333 settings
->fog
= FOG_LINEAR
;
2335 switch(stateblock
->renderState
[WINED3DRS_FOGVERTEXMODE
]) {
2336 case WINED3DFOG_NONE
:
2337 case WINED3DFOG_LINEAR
:
2338 settings
->fog
= FOG_LINEAR
;
2340 case WINED3DFOG_EXP
:
2341 settings
->fog
= FOG_EXP
;
2343 case WINED3DFOG_EXP2
:
2344 settings
->fog
= FOG_EXP2
;
2349 switch(stateblock
->renderState
[WINED3DRS_FOGTABLEMODE
]) {
2350 case WINED3DFOG_LINEAR
:
2351 settings
->fog
= FOG_LINEAR
;
2353 case WINED3DFOG_EXP
:
2354 settings
->fog
= FOG_EXP
;
2356 case WINED3DFOG_EXP2
:
2357 settings
->fog
= FOG_EXP2
;
2361 if(stateblock
->renderState
[WINED3DRS_SRGBWRITEENABLE
]) {
2362 settings
->sRGB_write
= 1;
2364 settings
->sRGB_write
= 0;
2367 #undef GLINFO_LOCATION
2369 const struct ffp_frag_desc
*find_ffp_frag_shader(const struct hash_table_t
*fragment_shaders
,
2370 const struct ffp_frag_settings
*settings
)
2372 return hash_table_get(fragment_shaders
, settings
);
2375 void add_ffp_frag_shader(struct hash_table_t
*shaders
, struct ffp_frag_desc
*desc
) {
2376 struct ffp_frag_settings
*key
= HeapAlloc(GetProcessHeap(), 0, sizeof(*key
));
2377 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2378 * whereas desc points to an extended structure with implementation specific parts.
2379 * Make a copy of the key because hash_table_put takes ownership of it
2381 *key
= desc
->settings
;
2382 hash_table_put(shaders
, key
, desc
);
2385 /* Activates the texture dimension according to the bound D3D texture.
2386 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2387 * Requires the caller to activate the correct unit before
2389 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2390 /* GL locking is done by the caller (state handler) */
2391 void texture_activate_dimensions(DWORD stage
, IWineD3DStateBlockImpl
*stateblock
, WineD3DContext
*context
) {
2392 if(stateblock
->textures
[stage
]) {
2393 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock
->textures
[stage
])) {
2395 glDisable(GL_TEXTURE_3D
);
2396 checkGLcall("glDisable(GL_TEXTURE_3D)");
2397 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP
)) {
2398 glDisable(GL_TEXTURE_CUBE_MAP_ARB
);
2399 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2401 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE
)) {
2402 glDisable(GL_TEXTURE_RECTANGLE_ARB
);
2403 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2405 glEnable(GL_TEXTURE_2D
);
2406 checkGLcall("glEnable(GL_TEXTURE_2D)");
2408 case GL_TEXTURE_RECTANGLE_ARB
:
2409 glDisable(GL_TEXTURE_2D
);
2410 checkGLcall("glDisable(GL_TEXTURE_2D)");
2411 glDisable(GL_TEXTURE_3D
);
2412 checkGLcall("glDisable(GL_TEXTURE_3D)");
2413 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP
)) {
2414 glDisable(GL_TEXTURE_CUBE_MAP_ARB
);
2415 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2417 glEnable(GL_TEXTURE_RECTANGLE_ARB
);
2418 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2421 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP
)) {
2422 glDisable(GL_TEXTURE_CUBE_MAP_ARB
);
2423 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2425 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE
)) {
2426 glDisable(GL_TEXTURE_RECTANGLE_ARB
);
2427 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2429 glDisable(GL_TEXTURE_2D
);
2430 checkGLcall("glDisable(GL_TEXTURE_2D)");
2431 glEnable(GL_TEXTURE_3D
);
2432 checkGLcall("glEnable(GL_TEXTURE_3D)");
2434 case GL_TEXTURE_CUBE_MAP_ARB
:
2435 glDisable(GL_TEXTURE_2D
);
2436 checkGLcall("glDisable(GL_TEXTURE_2D)");
2437 glDisable(GL_TEXTURE_3D
);
2438 checkGLcall("glDisable(GL_TEXTURE_3D)");
2439 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE
)) {
2440 glDisable(GL_TEXTURE_RECTANGLE_ARB
);
2441 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2443 glEnable(GL_TEXTURE_CUBE_MAP_ARB
);
2444 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2448 glEnable(GL_TEXTURE_2D
);
2449 checkGLcall("glEnable(GL_TEXTURE_2D)");
2450 glDisable(GL_TEXTURE_3D
);
2451 checkGLcall("glDisable(GL_TEXTURE_3D)");
2452 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP
)) {
2453 glDisable(GL_TEXTURE_CUBE_MAP_ARB
);
2454 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2456 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE
)) {
2457 glDisable(GL_TEXTURE_RECTANGLE_ARB
);
2458 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2460 /* Binding textures is done by samplers. A dummy texture will be bound */
2464 /* GL locking is done by the caller (state handler) */
2465 void sampler_texdim(DWORD state
, IWineD3DStateBlockImpl
*stateblock
, WineD3DContext
*context
) {
2466 DWORD sampler
= state
- STATE_SAMPLER(0);
2467 DWORD mapped_stage
= stateblock
->wineD3DDevice
->texUnitMap
[sampler
];
2469 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2470 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2471 * will take care of this business
2473 if(mapped_stage
== WINED3D_UNMAPPED_STAGE
|| mapped_stage
>= GL_LIMITS(textures
)) return;
2474 if(sampler
>= stateblock
->lowest_disabled_stage
) return;
2475 if(isStateDirty(context
, STATE_TEXTURESTAGE(sampler
, WINED3DTSS_COLOROP
))) return;
2477 texture_activate_dimensions(sampler
, stateblock
, context
);
2479 #undef GLINFO_LOCATION
2481 unsigned int ffp_frag_program_key_hash(const void *key
)
2483 const struct ffp_frag_settings
*k
= key
;
2484 unsigned int hash
= 0, i
;
2487 /* This takes the texture op settings of stage 0 and 1 into account.
2488 * how exactly depends on the memory laybout of the compiler, but it
2489 * should not matter too much. Stages > 1 are used rarely, so there's
2490 * no need to process them. Even if they're used it is likely that
2491 * the ffp setup has distinct stage 0 and 1 settings.
2493 for(i
= 0; i
< 2; i
++) {
2494 blob
= (const DWORD
*)&k
->op
[i
];
2495 hash
^= blob
[0] ^ blob
[1];
2498 hash
+= ~(hash
<< 15);
2499 hash
^= (hash
>> 10);
2500 hash
+= (hash
<< 3);
2501 hash
^= (hash
>> 6);
2502 hash
+= ~(hash
<< 11);
2503 hash
^= (hash
>> 16);
2508 BOOL
ffp_frag_program_key_compare(const void *keya
, const void *keyb
)
2510 const struct ffp_frag_settings
*ka
= keya
;
2511 const struct ffp_frag_settings
*kb
= keyb
;
2513 return memcmp(ka
, kb
, sizeof(*ka
)) == 0;
2516 UINT
wined3d_log2i(UINT32 x
)
2518 static const BYTE l
[] =
2520 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2521 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2522 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2523 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2524 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2525 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2526 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2527 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2528 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2529 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2530 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2531 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2532 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2533 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2534 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2535 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2539 return (i
= x
>> 16) ? (x
= i
>> 8) ? l
[x
] + 24 : l
[i
] + 16 : (i
= x
>> 8) ? l
[i
] + 8 : l
[x
];