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 /*****************************************************************************
34 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
35 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
36 * high masks do not fit into the 32 bit values needed for ddraw. It is only
37 * used for ddraw mostly, and to figure out if the format has alpha at all, so
38 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
39 * formats are not usable in 2D rendering because ddraw doesn't support them.
41 static const StaticPixelFormatDesc formats[] = {
42 /*{WINED3DFORMAT ,alphamask ,redmask ,greenmask ,bluemask ,bpp ,depth ,stencil, isFourcc*/
43 {WINED3DFMT_UNKNOWN ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
44 /* FourCC formats, kept here to have WINED3DFMT_R8G8B8(=20) at position 20 */
45 {WINED3DFMT_UYVY ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,TRUE },
46 {WINED3DFMT_YUY2 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,TRUE },
47 {WINED3DFMT_YV12 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
48 {WINED3DFMT_DXT1 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
49 {WINED3DFMT_DXT2 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
50 {WINED3DFMT_DXT3 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
51 {WINED3DFMT_DXT4 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
52 {WINED3DFMT_DXT5 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
53 {WINED3DFMT_MULTI2_ARGB8,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
54 {WINED3DFMT_G8R8_G8B8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
55 {WINED3DFMT_R8G8_B8G8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
57 {WINED3DFMT_R32F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
58 {WINED3DFMT_G32R32F ,0x0 ,0x0 ,0x0 ,0x0 ,8 ,0 ,0 ,FALSE },
59 {WINED3DFMT_A32B32G32R32F,0x1 ,0x0 ,0x0 ,0x0 ,16 ,0 ,0 ,FALSE },
61 {WINED3DFMT_CxV8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
63 {WINED3DFMT_R16F ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
64 {WINED3DFMT_G16R16F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
65 {WINED3DFMT_A16B16G16R16F,0x1 ,0x0 ,0x0 ,0x0 ,8 ,0 ,0 ,FALSE },
66 /* Palettized formats */
67 {WINED3DFMT_A8P8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
68 {WINED3DFMT_P8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
69 /* Standard ARGB formats. Keep WINED3DFMT_R8G8B8(=20) at position 20 */
70 {WINED3DFMT_R8G8B8 ,0x0 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,3 ,0 ,0 ,FALSE },
71 {WINED3DFMT_A8R8G8B8 ,0xff000000 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,0 ,0 ,FALSE },
72 {WINED3DFMT_X8R8G8B8 ,0x0 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,0 ,0 ,FALSE },
73 {WINED3DFMT_R5G6B5 ,0x0 ,0x0000F800 ,0x000007e0 ,0x0000001f ,2 ,0 ,0 ,FALSE },
74 {WINED3DFMT_X1R5G5B5 ,0x0 ,0x00007c00 ,0x000003e0 ,0x0000001f ,2 ,0 ,0 ,FALSE },
75 {WINED3DFMT_A1R5G5B5 ,0x00008000 ,0x00007c00 ,0x000003e0 ,0x0000001f ,2 ,0 ,0 ,FALSE },
76 {WINED3DFMT_A4R4G4B4 ,0x0000f000 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,0 ,0 ,FALSE },
77 {WINED3DFMT_R3G3B2 ,0x0 ,0x000000e0 ,0x0000001c ,0x00000003 ,1 ,0 ,0 ,FALSE },
78 {WINED3DFMT_A8 ,0x000000ff ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
79 {WINED3DFMT_A8R3G3B2 ,0x0000ff00 ,0x000000e0 ,0x0000001c ,0x00000003 ,2 ,0 ,0 ,FALSE },
80 {WINED3DFMT_X4R4G4B4 ,0x0 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,0 ,0 ,FALSE },
81 {WINED3DFMT_A2B10G10R10 ,0xb0000000 ,0x000003ff ,0x000ffc00 ,0x3ff00000 ,4 ,0 ,0 ,FALSE },
82 {WINED3DFMT_A8B8G8R8 ,0xff000000 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,0 ,0 ,FALSE },
83 {WINED3DFMT_X8B8G8R8 ,0x0 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,0 ,0 ,FALSE },
84 {WINED3DFMT_G16R16 ,0x0 ,0x0000ffff ,0xffff0000 ,0x0 ,4 ,0 ,0 ,FALSE },
85 {WINED3DFMT_A2R10G10B10 ,0xb0000000 ,0x3ff00000 ,0x000ffc00 ,0x000003ff ,4 ,0 ,0 ,FALSE },
86 {WINED3DFMT_A16B16G16R16,0x1 ,0x0000ffff ,0xffff0000 ,0x0 ,8 ,0 ,0 ,FALSE },
88 {WINED3DFMT_L8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
89 {WINED3DFMT_A8L8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
90 {WINED3DFMT_A4L4 ,0x000000f0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
91 /* Bump mapping stuff */
92 {WINED3DFMT_V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
93 {WINED3DFMT_L6V5U5 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
94 {WINED3DFMT_X8L8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
95 {WINED3DFMT_Q8W8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
96 {WINED3DFMT_V16U16 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
97 {WINED3DFMT_W11V11U10 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
98 {WINED3DFMT_A2W10V10U10 ,0xb0000000 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
99 /* Depth stencil formats */
100 {WINED3DFMT_D16_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,2 ,16 ,0 ,FALSE },
101 {WINED3DFMT_D32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,32 ,0 ,FALSE },
102 {WINED3DFMT_D15S1 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,15 ,1 ,FALSE },
103 {WINED3DFMT_D24S8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,8 ,FALSE },
104 {WINED3DFMT_D24X8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,0 ,FALSE },
105 {WINED3DFMT_D24X4S4 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,4 ,FALSE },
106 {WINED3DFMT_D16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,16 ,0 ,FALSE },
107 {WINED3DFMT_L16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,16 ,0 ,FALSE },
108 {WINED3DFMT_D32F_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,4 ,32 ,0 ,FALSE },
109 {WINED3DFMT_D24FS8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,8 ,FALSE },
110 /* Is this a vertex buffer? */
111 {WINED3DFMT_VERTEXDATA ,0x0 ,0x0 ,0x0 ,0x0 ,0 ,0 ,0 ,FALSE },
112 {WINED3DFMT_INDEX16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
113 {WINED3DFMT_INDEX32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
114 {WINED3DFMT_Q16W16V16U16,0x0 ,0x0 ,0x0 ,0x0 ,8 ,0 ,0 ,FALSE },
115 /* Vendor-specific formats */
116 {WINED3DFMT_ATI2N ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
117 {WINED3DFMT_NVHU ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,TRUE },
118 {WINED3DFMT_NVHS ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,TRUE },
123 GLint glInternal, glGammaInternal, rtInternal, glFormat, glType;
125 } GlPixelFormatDescTemplate;
127 /*****************************************************************************
128 * OpenGL format template. Contains unexciting formats which do not need
129 * extension checks. The order in this table is independent of the order in
130 * the table StaticPixelFormatDesc above. Not all formats have to be in this
133 static const GlPixelFormatDescTemplate gl_formats_template[] = {
134 /*{ internal ,srgbInternal , rtInternal, format ,type \
136 {WINED3DFMT_UNKNOWN ,0 ,0 , 0, 0 ,0
139 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
140 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
141 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
142 * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
145 {WINED3DFMT_UYVY ,GL_RGB ,GL_RGB , 0, GL_YCBCR_422_APPLE ,UNSIGNED_SHORT_8_8_APPLE
146 ,WINED3DFMT_FLAG_FILTERING },
147 {WINED3DFMT_YUY2 ,GL_RGB ,GL_RGB , 0, GL_YCBCR_422_APPLE ,UNSIGNED_SHORT_8_8_REV_APPLE
148 ,WINED3DFMT_FLAG_FILTERING },
149 {WINED3DFMT_YV12 ,GL_ALPHA ,GL_ALPHA , 0, GL_ALPHA ,GL_UNSIGNED_BYTE
150 ,WINED3DFMT_FLAG_FILTERING },
151 {WINED3DFMT_DXT1 ,GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT , 0, GL_RGBA ,GL_UNSIGNED_BYTE
152 ,WINED3DFMT_FLAG_FILTERING },
153 {WINED3DFMT_DXT2 ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT , 0, GL_RGBA ,GL_UNSIGNED_BYTE
154 ,WINED3DFMT_FLAG_FILTERING },
155 {WINED3DFMT_DXT3 ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT , 0, GL_RGBA ,GL_UNSIGNED_BYTE
156 ,WINED3DFMT_FLAG_FILTERING },
157 {WINED3DFMT_DXT4 ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT , 0, GL_RGBA ,GL_UNSIGNED_BYTE
158 ,WINED3DFMT_FLAG_FILTERING },
159 {WINED3DFMT_DXT5 ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT , 0, GL_RGBA ,GL_UNSIGNED_BYTE
160 ,WINED3DFMT_FLAG_FILTERING },
161 {WINED3DFMT_MULTI2_ARGB8 ,0 ,0 , 0, 0 ,0
163 {WINED3DFMT_G8R8_G8B8 ,0 ,0 , 0, 0 ,0
165 {WINED3DFMT_R8G8_B8G8 ,0 ,0 , 0, 0 ,0
168 {WINED3DFMT_R32F ,GL_RGB32F_ARB ,GL_RGB32F_ARB , 0, GL_RED ,GL_FLOAT
169 ,WINED3DFMT_FLAG_RENDERTARGET },
170 {WINED3DFMT_G32R32F ,0 ,0 , 0, 0 ,0
171 ,WINED3DFMT_FLAG_RENDERTARGET },
172 {WINED3DFMT_A32B32G32R32F ,GL_RGBA32F_ARB ,GL_RGBA32F_ARB , 0, GL_RGBA ,GL_FLOAT
173 ,WINED3DFMT_FLAG_RENDERTARGET },
175 {WINED3DFMT_CxV8U8 ,0 ,0 , 0, 0 ,0
178 {WINED3DFMT_R16F ,GL_RGB16F_ARB ,GL_RGB16F_ARB , 0, GL_RED ,GL_HALF_FLOAT_ARB
179 ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
180 {WINED3DFMT_G16R16F ,0 ,0 , 0, 0 ,0
181 ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
182 {WINED3DFMT_A16B16G16R16F ,GL_RGBA16F_ARB ,GL_RGBA16F_ARB , 0, GL_RGBA ,GL_HALF_FLOAT_ARB
183 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
184 /* Palettized formats */
185 {WINED3DFMT_A8P8, 0 ,0 , 0, 0 ,0
187 {WINED3DFMT_P8, GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX8_EXT , 0, GL_COLOR_INDEX ,GL_UNSIGNED_BYTE
189 /* Standard ARGB formats */
190 {WINED3DFMT_R8G8B8 ,GL_RGB8 ,GL_RGB8 , 0, GL_BGR ,GL_UNSIGNED_BYTE
191 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
192 {WINED3DFMT_A8R8G8B8 ,GL_RGBA8 ,GL_SRGB8_ALPHA8_EXT , 0, GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV
193 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
194 {WINED3DFMT_X8R8G8B8 ,GL_RGB8 ,GL_SRGB8_EXT , 0, GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV
195 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
196 {WINED3DFMT_R5G6B5 ,GL_RGB5 ,GL_RGB5 , GL_RGB8, GL_RGB ,GL_UNSIGNED_SHORT_5_6_5
197 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
198 {WINED3DFMT_X1R5G5B5 ,GL_RGB5 ,GL_RGB5_A1 , 0, GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV
199 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING },
200 {WINED3DFMT_A1R5G5B5 ,GL_RGB5_A1 ,GL_RGB5_A1 , 0, GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV
201 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING },
202 {WINED3DFMT_A4R4G4B4 ,GL_RGBA4 ,GL_SRGB8_ALPHA8_EXT , 0, GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV
203 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING },
204 {WINED3DFMT_R3G3B2 ,GL_R3_G3_B2 ,GL_R3_G3_B2 , 0, GL_RGB ,GL_UNSIGNED_BYTE_3_3_2
205 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING },
206 {WINED3DFMT_A8 ,GL_ALPHA8 ,GL_ALPHA8 , 0, GL_ALPHA ,GL_UNSIGNED_BYTE
207 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING },
208 {WINED3DFMT_A8R3G3B2 ,0 ,0 , 0, 0 ,0
210 {WINED3DFMT_X4R4G4B4 ,GL_RGB4 ,GL_RGB4 , 0, GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV
211 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
212 {WINED3DFMT_A2B10G10R10 ,GL_RGB10_A2 ,GL_RGB10_A2 , 0, GL_RGBA ,GL_UNSIGNED_INT_2_10_10_10_REV
213 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
214 {WINED3DFMT_A8B8G8R8 ,GL_RGBA8 ,GL_RGBA8 , 0, GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV
215 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
216 {WINED3DFMT_X8B8G8R8 ,GL_RGB8 ,GL_RGB8 , 0, GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV
217 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
218 {WINED3DFMT_G16R16 ,GL_RGB16_EXT ,GL_RGB16_EXT , 0, GL_RGB ,GL_UNSIGNED_SHORT
219 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING },
220 {WINED3DFMT_A2R10G10B10 ,GL_RGB10_A2 ,GL_RGB10_A2 , 0, GL_BGRA ,GL_UNSIGNED_INT_2_10_10_10_REV
221 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING },
222 {WINED3DFMT_A16B16G16R16 ,GL_RGBA16_EXT ,GL_RGBA16_EXT , 0, GL_RGBA ,GL_UNSIGNED_SHORT
223 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
225 {WINED3DFMT_L8 ,GL_LUMINANCE8 ,GL_SLUMINANCE8_EXT , 0, GL_LUMINANCE ,GL_UNSIGNED_BYTE
226 ,WINED3DFMT_FLAG_FILTERING },
227 {WINED3DFMT_A8L8 ,GL_LUMINANCE8_ALPHA8 ,GL_SLUMINANCE8_ALPHA8_EXT , 0, GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE
228 ,WINED3DFMT_FLAG_FILTERING },
229 {WINED3DFMT_A4L4 ,GL_LUMINANCE4_ALPHA4 ,GL_LUMINANCE4_ALPHA4 , 0, GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE
231 /* Bump mapping stuff */
232 {WINED3DFMT_V8U8 ,GL_DSDT8_NV ,GL_DSDT8_NV , 0, GL_DSDT_NV ,GL_BYTE
233 ,WINED3DFMT_FLAG_FILTERING },
234 {WINED3DFMT_L6V5U5 ,GL_DSDT8_MAG8_NV ,GL_DSDT8_MAG8_NV , 0, GL_DSDT_MAG_NV ,GL_BYTE
235 ,WINED3DFMT_FLAG_FILTERING },
236 {WINED3DFMT_X8L8V8U8 ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT8_MAG8_INTENSITY8_NV , 0, GL_DSDT_MAG_VIB_NV ,GL_UNSIGNED_INT_8_8_S8_S8_REV_NV
237 ,WINED3DFMT_FLAG_FILTERING },
238 {WINED3DFMT_Q8W8V8U8 ,GL_SIGNED_RGBA8_NV ,GL_SIGNED_RGBA8_NV , 0, GL_RGBA ,GL_BYTE
239 ,WINED3DFMT_FLAG_FILTERING },
240 {WINED3DFMT_V16U16 ,GL_SIGNED_HILO16_NV ,GL_SIGNED_HILO16_NV , 0, GL_HILO_NV ,GL_SHORT
241 ,WINED3DFMT_FLAG_FILTERING },
242 {WINED3DFMT_W11V11U10 ,0 ,0 , 0, 0 ,0
244 {WINED3DFMT_A2W10V10U10 ,0 ,0 , 0, 0 ,0
246 /* Depth stencil formats */
247 {WINED3DFMT_D16_LOCKABLE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT
248 ,WINED3DFMT_FLAG_DEPTH },
249 {WINED3DFMT_D32 ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT32_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT
250 ,WINED3DFMT_FLAG_DEPTH },
251 {WINED3DFMT_D15S1 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT
252 ,WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL },
253 {WINED3DFMT_D24S8 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT
254 ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL },
255 {WINED3DFMT_D24X8 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT
256 ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH },
257 {WINED3DFMT_D24X4S4 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT
258 ,WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL },
259 {WINED3DFMT_D16 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT
260 ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH },
261 {WINED3DFMT_L16 ,GL_LUMINANCE16_EXT ,GL_LUMINANCE16_EXT , 0, GL_LUMINANCE ,GL_UNSIGNED_SHORT
262 ,WINED3DFMT_FLAG_FILTERING },
263 {WINED3DFMT_D32F_LOCKABLE ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT32_ARB , 0, GL_DEPTH_COMPONENT ,GL_FLOAT
264 ,WINED3DFMT_FLAG_DEPTH },
265 {WINED3DFMT_D24FS8 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_FLOAT
266 ,WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
267 /* Is this a vertex buffer? */
268 {WINED3DFMT_VERTEXDATA ,0 ,0 , 0, 0 ,0
270 {WINED3DFMT_INDEX16 ,0 ,0 , 0, 0 ,0
272 {WINED3DFMT_INDEX32 ,0 ,0 , 0, 0 ,0
274 {WINED3DFMT_Q16W16V16U16 ,GL_COLOR_INDEX ,GL_COLOR_INDEX , 0, GL_COLOR_INDEX ,GL_UNSIGNED_SHORT
276 /* Vendor-specific formats */
277 {WINED3DFMT_ATI2N ,0 ,0 , 0, GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE
279 {WINED3DFMT_NVHU ,0 ,0 , 0, GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE
281 {WINED3DFMT_NVHS ,0 ,0 , 0, GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE
285 static inline int getFmtIdx(WINED3DFORMAT fmt) {
286 /* First check if the format is at the position of its value.
287 * This will catch the argb formats before the loop is entered
289 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
293 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
294 if(formats[i].format == fmt) {
302 #define GLINFO_LOCATION (*gl_info)
303 BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
308 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
309 sizeof(formats) / sizeof(formats[0]) * sizeof(gl_info->gl_formats[0]));
310 if(!gl_info->gl_formats) return FALSE;
312 /* If a format depends on some extensions, remove them from the table above and initialize them
315 for(src = 0; src < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); src++) {
316 dst = getFmtIdx(gl_formats_template[src].fmt);
317 gl_info->gl_formats[dst].glInternal = gl_formats_template[src].glInternal;
318 gl_info->gl_formats[dst].glGammaInternal = gl_formats_template[src].glGammaInternal;
319 gl_info->gl_formats[dst].glFormat = gl_formats_template[src].glFormat;
320 gl_info->gl_formats[dst].glType = gl_formats_template[src].glType;
321 gl_info->gl_formats[dst].color_fixup = COLOR_FIXUP_IDENTITY;
322 gl_info->gl_formats[dst].Flags = gl_formats_template[src].Flags;
323 gl_info->gl_formats[dst].heightscale = 1.0;
325 if(wined3d_settings.offscreen_rendering_mode == ORM_FBO &&
326 gl_formats_template[src].rtInternal != 0) {
330 /* Check if the default internal format is supported as a frame buffer target, otherwise
331 * fall back to the render target internal.
333 * Try to stick to the standard format if possible, this limits precision differences
336 glGenTextures(1, &tex);
337 glBindTexture(GL_TEXTURE_2D, tex);
338 glTexImage2D(GL_TEXTURE_2D, 0, gl_formats_template[src].glInternal, 16, 16, 0,
339 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
341 GL_EXTCALL(glGenFramebuffersEXT(1, &fb));
342 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb));
343 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
344 GL_TEXTURE_2D, tex, 0));
346 status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
347 GL_EXTCALL(glDeleteFramebuffersEXT(1, &fb));
348 glDeleteTextures(1, &tex);
350 checkGLcall("Framebuffer format check");
352 if(status != GL_FRAMEBUFFER_COMPLETE_EXT) {
353 TRACE("Internal format of %s not supported as frame buffer target, using render target internal instead\n",
354 debug_d3dformat(gl_formats_template[src].fmt));
355 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].rtInternal;
357 TRACE("Format %s is supported as fbo target\n", debug_d3dformat(gl_formats_template[src].fmt));
358 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].glInternal;
362 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].glInternal;
366 dst = getFmtIdx(WINED3DFMT_R16F);
367 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
368 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
370 dst = getFmtIdx(WINED3DFMT_R32F);
371 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
372 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
374 dst = getFmtIdx(WINED3DFMT_G16R16);
375 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
376 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
378 dst = getFmtIdx(WINED3DFMT_G16R16F);
379 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
380 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
382 dst = getFmtIdx(WINED3DFMT_G32R32F);
383 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
384 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
386 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
387 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
388 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
389 * the only driver that implements it(fglrx) has a buggy implementation.
391 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
392 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
393 * conversion for this format.
395 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
397 dst = getFmtIdx(WINED3DFMT_V8U8);
398 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
399 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
400 dst = getFmtIdx(WINED3DFMT_V16U16);
401 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
402 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
406 dst = getFmtIdx(WINED3DFMT_V8U8);
407 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
408 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
409 dst = getFmtIdx(WINED3DFMT_V16U16);
410 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
411 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
414 if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
415 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
418 dst = getFmtIdx(WINED3DFMT_L6V5U5);
419 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
420 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
421 dst = getFmtIdx(WINED3DFMT_X8L8V8U8);
422 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
423 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
424 dst = getFmtIdx(WINED3DFMT_Q8W8V8U8);
425 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
426 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
428 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
429 * are converted at surface loading time, but they do not need any modification in
430 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
431 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
435 if(GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
436 dst = getFmtIdx(WINED3DFMT_ATI2N);
437 gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
438 gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
439 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
440 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
441 } else if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC)) {
442 dst = getFmtIdx(WINED3DFMT_ATI2N);
443 gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
444 gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
445 gl_info->gl_formats[dst].color_fixup= create_color_fixup_desc(
446 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
449 if(!GL_SUPPORT(APPLE_YCBCR_422)) {
450 dst = getFmtIdx(WINED3DFMT_YUY2);
451 gl_info->gl_formats[dst].glInternal = GL_LUMINANCE_ALPHA;
452 gl_info->gl_formats[dst].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
453 gl_info->gl_formats[dst].glFormat = GL_LUMINANCE_ALPHA;
454 gl_info->gl_formats[dst].glType = GL_UNSIGNED_BYTE;
455 gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
457 dst = getFmtIdx(WINED3DFMT_UYVY);
458 gl_info->gl_formats[dst].glInternal = GL_LUMINANCE_ALPHA;
459 gl_info->gl_formats[dst].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
460 gl_info->gl_formats[dst].glFormat = GL_LUMINANCE_ALPHA;
461 gl_info->gl_formats[dst].glType = GL_UNSIGNED_BYTE;
462 gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
465 dst = getFmtIdx(WINED3DFMT_YV12);
466 gl_info->gl_formats[dst].heightscale = 1.5;
467 gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
472 /* NOTE: Make sure these are in the correct numerical order. (see /include/wined3d_types.h) */
473 static WINED3DGLTYPE const glTypeLookupTemplate[WINED3DDECLTYPE_UNUSED] = {
474 {WINED3DDECLTYPE_FLOAT1, 1, GL_FLOAT , GL_FALSE ,sizeof(float)},
475 {WINED3DDECLTYPE_FLOAT2, 2, GL_FLOAT , GL_FALSE ,sizeof(float)},
476 {WINED3DDECLTYPE_FLOAT3, 3, GL_FLOAT , GL_FALSE ,sizeof(float)},
477 {WINED3DDECLTYPE_FLOAT4, 4, GL_FLOAT , GL_FALSE ,sizeof(float)},
478 {WINED3DDECLTYPE_D3DCOLOR, 4, GL_UNSIGNED_BYTE , GL_TRUE ,sizeof(BYTE)},
479 {WINED3DDECLTYPE_UBYTE4, 4, GL_UNSIGNED_BYTE , GL_FALSE ,sizeof(BYTE)},
480 {WINED3DDECLTYPE_SHORT2, 2, GL_SHORT , GL_FALSE ,sizeof(short int)},
481 {WINED3DDECLTYPE_SHORT4, 4, GL_SHORT , GL_FALSE ,sizeof(short int)},
482 {WINED3DDECLTYPE_UBYTE4N, 4, GL_UNSIGNED_BYTE , GL_TRUE ,sizeof(BYTE)},
483 {WINED3DDECLTYPE_SHORT2N, 2, GL_SHORT , GL_TRUE ,sizeof(short int)},
484 {WINED3DDECLTYPE_SHORT4N, 4, GL_SHORT , GL_TRUE ,sizeof(short int)},
485 {WINED3DDECLTYPE_USHORT2N, 2, GL_UNSIGNED_SHORT , GL_TRUE ,sizeof(short int)},
486 {WINED3DDECLTYPE_USHORT4N, 4, GL_UNSIGNED_SHORT , GL_TRUE ,sizeof(short int)},
487 {WINED3DDECLTYPE_UDEC3, 3, GL_UNSIGNED_SHORT , GL_FALSE ,sizeof(short int)},
488 {WINED3DDECLTYPE_DEC3N, 3, GL_SHORT , GL_TRUE ,sizeof(short int)},
489 {WINED3DDECLTYPE_FLOAT16_2, 2, GL_HALF_FLOAT_NV , GL_FALSE ,sizeof(GLhalfNV)},
490 {WINED3DDECLTYPE_FLOAT16_4, 4, GL_HALF_FLOAT_NV , GL_FALSE ,sizeof(GLhalfNV)}};
492 void init_type_lookup(WineD3D_GL_Info *gl_info) {
493 memcpy(gl_info->glTypeLookup, glTypeLookupTemplate, sizeof(glTypeLookupTemplate));
494 if(!GL_SUPPORT(NV_HALF_FLOAT)) {
495 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
496 * It is the job of the vertex buffer code to make sure that the vbos have the right format
498 gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_2].glType = GL_FLOAT;
499 gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_4].glType = GL_FLOAT;
503 #undef GLINFO_LOCATION
505 #define GLINFO_LOCATION This->adapter->gl_info
507 const StaticPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const WineD3D_GL_Info *gl_info,
508 const struct GlPixelFormatDesc **glDesc)
510 int idx = getFmtIdx(fmt);
513 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
514 /* Get the caller a valid pointer */
515 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
518 if(!gl_info->gl_formats) {
519 /* If we do not have gl format information, provide a dummy NULL format. This is an easy way to make
520 * all gl caps check return "unsupported" than catching the lack of gl all over the code. ANSI C requires
521 * static variables to be initialized to 0.
523 static const struct GlPixelFormatDesc dummyFmt;
526 *glDesc = &gl_info->gl_formats[idx];
529 return &formats[idx];
532 /*****************************************************************************
533 * Trace formatting of useful values
535 const char* debug_d3dformat(WINED3DFORMAT fmt) {
537 #define FMT_TO_STR(fmt) case fmt: return #fmt
538 FMT_TO_STR(WINED3DFMT_UNKNOWN);
539 FMT_TO_STR(WINED3DFMT_R8G8B8);
540 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
541 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
542 FMT_TO_STR(WINED3DFMT_R5G6B5);
543 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
544 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
545 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
546 FMT_TO_STR(WINED3DFMT_R3G3B2);
547 FMT_TO_STR(WINED3DFMT_A8);
548 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
549 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
550 FMT_TO_STR(WINED3DFMT_A2B10G10R10);
551 FMT_TO_STR(WINED3DFMT_A8B8G8R8);
552 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
553 FMT_TO_STR(WINED3DFMT_G16R16);
554 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
555 FMT_TO_STR(WINED3DFMT_A16B16G16R16);
556 FMT_TO_STR(WINED3DFMT_A8P8);
557 FMT_TO_STR(WINED3DFMT_P8);
558 FMT_TO_STR(WINED3DFMT_L8);
559 FMT_TO_STR(WINED3DFMT_A8L8);
560 FMT_TO_STR(WINED3DFMT_A4L4);
561 FMT_TO_STR(WINED3DFMT_V8U8);
562 FMT_TO_STR(WINED3DFMT_L6V5U5);
563 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
564 FMT_TO_STR(WINED3DFMT_Q8W8V8U8);
565 FMT_TO_STR(WINED3DFMT_V16U16);
566 FMT_TO_STR(WINED3DFMT_W11V11U10);
567 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
568 FMT_TO_STR(WINED3DFMT_UYVY);
569 FMT_TO_STR(WINED3DFMT_YUY2);
570 FMT_TO_STR(WINED3DFMT_YV12);
571 FMT_TO_STR(WINED3DFMT_DXT1);
572 FMT_TO_STR(WINED3DFMT_DXT2);
573 FMT_TO_STR(WINED3DFMT_DXT3);
574 FMT_TO_STR(WINED3DFMT_DXT4);
575 FMT_TO_STR(WINED3DFMT_DXT5);
576 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
577 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
578 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
579 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
580 FMT_TO_STR(WINED3DFMT_D32);
581 FMT_TO_STR(WINED3DFMT_D15S1);
582 FMT_TO_STR(WINED3DFMT_D24S8);
583 FMT_TO_STR(WINED3DFMT_D24X8);
584 FMT_TO_STR(WINED3DFMT_D24X4S4);
585 FMT_TO_STR(WINED3DFMT_D16);
586 FMT_TO_STR(WINED3DFMT_L16);
587 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
588 FMT_TO_STR(WINED3DFMT_D24FS8);
589 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
590 FMT_TO_STR(WINED3DFMT_INDEX16);
591 FMT_TO_STR(WINED3DFMT_INDEX32);
592 FMT_TO_STR(WINED3DFMT_Q16W16V16U16);
593 FMT_TO_STR(WINED3DFMT_R16F);
594 FMT_TO_STR(WINED3DFMT_G16R16F);
595 FMT_TO_STR(WINED3DFMT_A16B16G16R16F);
596 FMT_TO_STR(WINED3DFMT_R32F);
597 FMT_TO_STR(WINED3DFMT_G32R32F);
598 FMT_TO_STR(WINED3DFMT_A32B32G32R32F);
599 FMT_TO_STR(WINED3DFMT_CxV8U8);
600 FMT_TO_STR(WINED3DFMT_ATI2N);
601 FMT_TO_STR(WINED3DFMT_NVHU);
602 FMT_TO_STR(WINED3DFMT_NVHS);
607 fourcc[0] = (char)(fmt);
608 fourcc[1] = (char)(fmt >> 8);
609 fourcc[2] = (char)(fmt >> 16);
610 fourcc[3] = (char)(fmt >> 24);
612 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
613 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
615 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
617 return "unrecognized";
621 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
623 #define DEVTYPE_TO_STR(dev) case dev: return #dev
624 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
625 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
626 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
627 #undef DEVTYPE_TO_STR
629 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
630 return "unrecognized";
634 const char* debug_d3dusage(DWORD usage) {
635 switch (usage & WINED3DUSAGE_MASK) {
636 #define WINED3DUSAGE_TO_STR(u) case u: return #u
637 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
638 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
639 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
640 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
641 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
642 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
643 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
644 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
645 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
646 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
647 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
648 #undef WINED3DUSAGE_TO_STR
649 case 0: return "none";
651 FIXME("Unrecognized %u Usage!\n", usage);
652 return "unrecognized";
656 const char* debug_d3dusagequery(DWORD usagequery) {
657 switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
658 #define WINED3DUSAGEQUERY_TO_STR(u) case u: return #u
659 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
660 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
661 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
662 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
663 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
664 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
665 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
666 #undef WINED3DUSAGEQUERY_TO_STR
667 case 0: return "none";
669 FIXME("Unrecognized %u Usage Query!\n", usagequery);
670 return "unrecognized";
674 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
676 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
677 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
678 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
679 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
680 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
681 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
682 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
683 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
684 #undef WINED3DDECLMETHOD_TO_STR
686 FIXME("Unrecognized %u declaration method!\n", method);
687 return "unrecognized";
691 const char* debug_d3ddecltype(WINED3DDECLTYPE type) {
693 #define WINED3DDECLTYPE_TO_STR(u) case u: return #u
694 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT1);
695 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT2);
696 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT3);
697 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT4);
698 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_D3DCOLOR);
699 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4);
700 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2);
701 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4);
702 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4N);
703 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2N);
704 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4N);
705 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT2N);
706 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT4N);
707 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UDEC3);
708 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_DEC3N);
709 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_2);
710 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_4);
711 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UNUSED);
712 #undef WINED3DDECLTYPE_TO_STR
714 FIXME("Unrecognized %u declaration type!\n", type);
715 return "unrecognized";
719 const char* debug_d3ddeclusage(BYTE usage) {
721 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
722 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
723 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
724 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
725 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
726 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
727 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
728 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
729 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
730 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
731 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
732 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
733 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
734 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
735 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
736 #undef WINED3DDECLUSAGE_TO_STR
738 FIXME("Unrecognized %u declaration usage!\n", usage);
739 return "unrecognized";
743 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
745 #define RES_TO_STR(res) case res: return #res;
746 RES_TO_STR(WINED3DRTYPE_SURFACE);
747 RES_TO_STR(WINED3DRTYPE_VOLUME);
748 RES_TO_STR(WINED3DRTYPE_TEXTURE);
749 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
750 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
751 RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER);
752 RES_TO_STR(WINED3DRTYPE_INDEXBUFFER);
755 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
756 return "unrecognized";
760 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
761 switch (PrimitiveType) {
762 #define PRIM_TO_STR(prim) case prim: return #prim;
763 PRIM_TO_STR(WINED3DPT_POINTLIST);
764 PRIM_TO_STR(WINED3DPT_LINELIST);
765 PRIM_TO_STR(WINED3DPT_LINESTRIP);
766 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
767 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
768 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
771 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
772 return "unrecognized";
776 const char* debug_d3drenderstate(DWORD state) {
778 #define D3DSTATE_TO_STR(u) case u: return #u
779 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
780 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
781 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
782 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
783 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
784 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
785 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
786 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
787 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
788 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
789 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
790 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
791 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
792 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
793 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
794 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
795 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
796 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
797 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
798 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
799 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
800 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
801 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
802 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
803 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
804 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
805 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
806 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
807 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
808 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
809 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
810 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
811 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
812 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
813 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
814 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
815 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
816 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
817 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
818 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
819 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
820 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
821 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
822 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
823 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
824 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
825 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
826 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
827 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
828 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
829 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
830 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
831 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
832 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
833 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
834 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
835 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
836 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
837 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
838 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
839 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
840 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
841 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
842 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
843 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
844 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
845 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
846 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
847 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
848 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
849 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
850 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
851 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
852 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
853 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
854 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
855 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
856 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
857 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
858 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
859 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
860 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
861 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
862 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
863 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
864 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
865 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
866 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
867 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
868 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
869 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
870 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
871 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
872 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
873 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
874 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
875 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
876 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
877 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
878 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
879 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
880 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
881 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
882 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
883 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
884 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
885 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
886 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
887 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
888 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
889 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
890 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
891 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
892 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
893 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
894 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
895 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
896 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
897 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
898 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
899 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
900 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
901 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
902 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
903 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
904 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
905 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
906 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
907 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
908 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
909 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
910 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
911 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
912 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
913 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
914 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
915 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
916 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
917 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
918 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
919 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
920 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
921 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
922 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
923 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
924 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
925 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
926 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
927 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
928 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
929 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
930 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
931 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
932 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
933 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
934 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
935 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
936 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
937 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
938 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
939 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
940 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
941 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
942 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
943 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
944 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
945 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
946 #undef D3DSTATE_TO_STR
948 FIXME("Unrecognized %u render state!\n", state);
949 return "unrecognized";
953 const char* debug_d3dsamplerstate(DWORD state) {
955 #define D3DSTATE_TO_STR(u) case u: return #u
956 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
957 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
958 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
959 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
960 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
961 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
962 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
963 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
964 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
965 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
966 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
967 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
968 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
969 #undef D3DSTATE_TO_STR
971 FIXME("Unrecognized %u sampler state!\n", state);
972 return "unrecognized";
976 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
977 switch (filter_type) {
978 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
979 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
980 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
981 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
982 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
983 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
984 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
985 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
986 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
987 #undef D3DTEXTUREFILTERTYPE_TO_STR
989 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
990 return "unrecognized";
994 const char* debug_d3dtexturestate(DWORD state) {
996 #define D3DSTATE_TO_STR(u) case u: return #u
997 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
998 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
999 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1000 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1001 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1002 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1003 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1004 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1005 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1006 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1007 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1008 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1009 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1010 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1011 D3DSTATE_TO_STR(WINED3DTSS_ADDRESSW );
1012 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1013 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1014 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1015 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1016 #undef D3DSTATE_TO_STR
1018 /* Note WINED3DTSS are not consecutive, so skip these */
1021 FIXME("Unrecognized %u texture state!\n", state);
1022 return "unrecognized";
1026 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1028 #define D3DTOP_TO_STR(u) case u: return #u
1029 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1030 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1031 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1032 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1033 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1034 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1035 D3DTOP_TO_STR(WINED3DTOP_ADD);
1036 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1037 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1038 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1039 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1040 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1041 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1042 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1043 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1044 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1045 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1046 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1047 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1048 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1049 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1050 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1051 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1052 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1053 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1054 D3DTOP_TO_STR(WINED3DTOP_LERP);
1055 #undef D3DTOP_TO_STR
1057 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1058 return "unrecognized";
1062 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1064 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1065 TSTYPE_TO_STR(WINED3DTS_VIEW);
1066 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1067 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1068 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1069 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1070 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1071 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1072 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1073 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1074 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1075 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1076 #undef TSTYPE_TO_STR
1078 if (tstype > 256 && tstype < 512) {
1079 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1080 return ("WINED3DTS_WORLDMATRIX > 0");
1082 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1083 return "unrecognized";
1087 const char* debug_d3dpool(WINED3DPOOL Pool) {
1089 #define POOL_TO_STR(p) case p: return #p;
1090 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1091 POOL_TO_STR(WINED3DPOOL_MANAGED);
1092 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1093 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1096 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1097 return "unrecognized";
1101 const char *debug_fbostatus(GLenum status) {
1103 #define FBOSTATUS_TO_STR(u) case u: return #u
1104 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1105 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1106 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1107 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1108 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1109 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1110 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1111 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
1112 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1113 #undef FBOSTATUS_TO_STR
1115 FIXME("Unrecognied FBO status 0x%08x\n", status);
1116 return "unrecognized";
1120 const char *debug_glerror(GLenum error) {
1122 #define GLERROR_TO_STR(u) case u: return #u
1123 GLERROR_TO_STR(GL_NO_ERROR);
1124 GLERROR_TO_STR(GL_INVALID_ENUM);
1125 GLERROR_TO_STR(GL_INVALID_VALUE);
1126 GLERROR_TO_STR(GL_INVALID_OPERATION);
1127 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1128 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1129 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1130 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1131 #undef GLERROR_TO_STR
1133 FIXME("Unrecognied GL error 0x%08x\n", error);
1134 return "unrecognized";
1138 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1140 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1141 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1142 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1143 default: return "unrecognized";
1147 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1149 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1150 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1151 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1152 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1153 default: return "unrecognized";
1157 const char *debug_fixup_channel_source(enum fixup_channel_source source)
1161 #define WINED3D_TO_STR(x) case x: return #x
1162 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1163 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1164 WINED3D_TO_STR(CHANNEL_SOURCE_X);
1165 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1166 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1167 WINED3D_TO_STR(CHANNEL_SOURCE_W);
1168 WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1169 WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1170 #undef WINED3D_TO_STR
1172 FIXME("Unrecognized fixup_channel_source %#x\n", source);
1173 return "unrecognized";
1177 const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1181 #define WINED3D_TO_STR(x) case x: return #x
1182 WINED3D_TO_STR(YUV_FIXUP_YUY2);
1183 WINED3D_TO_STR(YUV_FIXUP_UYVY);
1184 WINED3D_TO_STR(YUV_FIXUP_YV12);
1185 #undef WINED3D_TO_STR
1187 FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1188 return "unrecognized";
1192 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1194 if (is_yuv_fixup(fixup))
1196 TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1200 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1201 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1202 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1203 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1206 /*****************************************************************************
1207 * Useful functions mapping GL <-> D3D values
1209 GLenum StencilOp(DWORD op) {
1211 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1212 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1213 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1214 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1215 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1216 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1217 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1218 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1220 FIXME("Unrecognized stencil op %d\n", op);
1225 GLenum CompareFunc(DWORD func) {
1226 switch ((WINED3DCMPFUNC)func) {
1227 case WINED3DCMP_NEVER : return GL_NEVER;
1228 case WINED3DCMP_LESS : return GL_LESS;
1229 case WINED3DCMP_EQUAL : return GL_EQUAL;
1230 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1231 case WINED3DCMP_GREATER : return GL_GREATER;
1232 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1233 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1234 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1236 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1241 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1242 if (op == WINED3DTOP_DISABLE) return FALSE;
1243 if (This->stateBlock->textures[stage]) return FALSE;
1245 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1246 && op != WINED3DTOP_SELECTARG2) return TRUE;
1247 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1248 && op != WINED3DTOP_SELECTARG1) return TRUE;
1249 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1250 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1255 /* Setup this textures matrix according to the texture flags*/
1256 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype,
1257 BOOL ffp_proj_control)
1261 glMatrixMode(GL_TEXTURE);
1262 checkGLcall("glMatrixMode(GL_TEXTURE)");
1264 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1266 checkGLcall("glLoadIdentity()");
1270 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1271 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1275 memcpy(mat, smat, 16 * sizeof(float));
1277 if (flags & WINED3DTTFF_PROJECTED) {
1278 if(!ffp_proj_control) {
1279 switch (flags & ~WINED3DTTFF_PROJECTED) {
1280 case WINED3DTTFF_COUNT2:
1281 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1282 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1284 case WINED3DTTFF_COUNT3:
1285 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1286 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1290 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1291 if(!calculatedCoords) {
1293 case WINED3DDECLTYPE_FLOAT1:
1294 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1295 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1296 * the input value to the transformation will be 0, so the matrix value is irrelevant
1303 case WINED3DDECLTYPE_FLOAT2:
1304 /* See above, just 3rd and 4th coord
1311 case WINED3DDECLTYPE_FLOAT3: /* Opengl defaults match dx defaults */
1312 case WINED3DDECLTYPE_FLOAT4: /* No defaults apply, all app defined */
1314 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1315 * into a bad place. The division elimination below will apply to make sure the
1316 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1318 case WINED3DDECLTYPE_UNUSED: /* No texture coords, 0/0/0/1 defaults are passed */
1321 FIXME("Unexpected fixed function texture coord input\n");
1324 if(!ffp_proj_control) {
1325 switch (flags & ~WINED3DTTFF_PROJECTED) {
1326 /* case WINED3DTTFF_COUNT1: Won't ever get here */
1327 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
1328 /* OpenGL divides the first 3 vertex coord by the 4th by default,
1329 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
1330 * the 4th coord evaluates to 1.0 to eliminate that.
1332 * If the fixed function pipeline is used, the 4th value remains unused,
1333 * so there is no danger in doing this. With vertex shaders we have a
1334 * problem. Should an app hit that problem, the code here would have to
1335 * check for pixel shaders, and the shader has to undo the default gl divide.
1337 * A more serious problem occurs if the app passes 4 coordinates in, and the
1338 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
1339 * or a replacement shader
1341 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
1347 checkGLcall("glLoadMatrixf(mat)");
1349 #undef GLINFO_LOCATION
1351 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
1353 /* This small helper function is used to convert a bitmask into the number of masked bits */
1354 unsigned int count_bits(unsigned int mask)
1357 for (count = 0; mask; ++count)
1364 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
1365 * The later function requires individual color components. */
1366 BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
1368 const StaticPixelFormatDesc *desc;
1370 TRACE("fmt: %s\n", debug_d3dformat(fmt));
1373 case WINED3DFMT_X8R8G8B8:
1374 case WINED3DFMT_R8G8B8:
1375 case WINED3DFMT_A8R8G8B8:
1376 case WINED3DFMT_A2R10G10B10:
1377 case WINED3DFMT_X1R5G5B5:
1378 case WINED3DFMT_A1R5G5B5:
1379 case WINED3DFMT_R5G6B5:
1380 case WINED3DFMT_X4R4G4B4:
1381 case WINED3DFMT_A4R4G4B4:
1382 case WINED3DFMT_R3G3B2:
1383 case WINED3DFMT_A8P8:
1387 ERR("Unsupported format: %s\n", debug_d3dformat(fmt));
1391 desc = getFormatDescEntry(fmt, NULL, NULL);
1394 ERR("Unable to look up format: 0x%x\n", fmt);
1397 *redSize = count_bits(desc->redMask);
1398 *greenSize = count_bits(desc->greenMask);
1399 *blueSize = count_bits(desc->blueMask);
1400 *alphaSize = count_bits(desc->alphaMask);
1401 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
1403 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n", *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(fmt));
1407 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
1408 BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize)
1410 const StaticPixelFormatDesc *desc;
1412 TRACE("fmt: %s\n", debug_d3dformat(fmt));
1415 case WINED3DFMT_D16_LOCKABLE:
1416 case WINED3DFMT_D16:
1417 case WINED3DFMT_D15S1:
1418 case WINED3DFMT_D24X8:
1419 case WINED3DFMT_D24X4S4:
1420 case WINED3DFMT_D24S8:
1421 case WINED3DFMT_D24FS8:
1422 case WINED3DFMT_D32:
1423 case WINED3DFMT_D32F_LOCKABLE:
1426 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(fmt));
1430 desc = getFormatDescEntry(fmt, NULL, NULL);
1433 ERR("Unable to look up format: 0x%x\n", fmt);
1436 *depthSize = desc->depthSize;
1437 *stencilSize = desc->stencilSize;
1439 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n", *depthSize, *stencilSize, debug_d3dformat(fmt));
1443 #undef GLINFO_LOCATION
1445 /* DirectDraw stuff */
1446 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
1448 case 8: return WINED3DFMT_P8;
1449 case 15: return WINED3DFMT_X1R5G5B5;
1450 case 16: return WINED3DFMT_R5G6B5;
1451 case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
1452 case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
1453 default: return WINED3DFMT_UNKNOWN;
1457 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
1460 /* Now do the multiplication 'by hand'.
1461 I know that all this could be optimised, but this will be done later :-) */
1462 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);
1463 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);
1464 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);
1465 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);
1467 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);
1468 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);
1469 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);
1470 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);
1472 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);
1473 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);
1474 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);
1475 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);
1477 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);
1478 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);
1479 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);
1480 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);
1482 /* And copy the new matrix in the good storage.. */
1483 memcpy(dest, &temp, 16 * sizeof(float));
1486 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
1489 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
1491 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
1492 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
1493 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
1494 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
1495 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
1496 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
1497 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
1498 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
1499 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
1500 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
1501 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
1502 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
1503 default: ERR("Unexpected position mask\n");
1505 for (i = 0; i < numTextures; i++) {
1506 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
1512 /***********************************************************************
1515 * Calculates the dimensions of the opengl texture used for blits.
1516 * Handled oversized opengl textures and updates the source rectangle
1520 * This: Surface to operate on
1521 * Rect: Requested rectangle
1524 * TRUE if the texture part can be loaded,
1527 *********************************************************************/
1528 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
1530 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
1531 int x1 = Rect->left, x2 = Rect->right;
1532 int y1 = Rect->top, y2 = Rect->bottom;
1533 GLint maxSize = GL_LIMITS(texture_size);
1535 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
1536 Rect->left, Rect->top, Rect->right, Rect->bottom);
1538 /* The sizes might be reversed */
1539 if(Rect->left > Rect->right) {
1543 if(Rect->top > Rect->bottom) {
1548 /* No oversized texture? This is easy */
1549 if(!(This->Flags & SFLAG_OVERSIZE)) {
1550 /* Which rect from the texture do I need? */
1551 if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
1552 glTexCoord[0] = (float) Rect->left;
1553 glTexCoord[2] = (float) Rect->top;
1554 glTexCoord[1] = (float) Rect->right;
1555 glTexCoord[3] = (float) Rect->bottom;
1557 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
1558 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
1559 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
1560 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
1565 /* Check if we can succeed at all */
1566 if( (x2 - x1) > maxSize ||
1567 (y2 - y1) > maxSize ) {
1568 TRACE("Requested rectangle is too large for gl\n");
1572 /* A part of the texture has to be picked. First, check if
1573 * some texture part is loaded already, if yes try to re-use it.
1574 * If the texture is dirty, or the part can't be used,
1575 * re-position the part to load
1577 if(This->Flags & SFLAG_INTEXTURE) {
1578 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
1579 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
1580 /* Ok, the rectangle is ok, re-use it */
1581 TRACE("Using existing gl Texture\n");
1583 /* Rectangle is not ok, dirtify the texture to reload it */
1584 TRACE("Dirtifying texture to force reload\n");
1585 This->Flags &= ~SFLAG_INTEXTURE;
1589 /* Now if we are dirty(no else if!) */
1590 if(!(This->Flags & SFLAG_INTEXTURE)) {
1591 /* Set the new rectangle. Use the following strategy:
1592 * 1) Use as big textures as possible.
1593 * 2) Place the texture part in the way that the requested
1594 * part is in the middle of the texture(well, almost)
1595 * 3) If the texture is moved over the edges of the
1596 * surface, replace it nicely
1597 * 4) If the coord is not limiting the texture size,
1598 * use the whole size
1600 if((This->pow2Width) > maxSize) {
1601 This->glRect.left = x1 - maxSize / 2;
1602 if(This->glRect.left < 0) {
1603 This->glRect.left = 0;
1605 This->glRect.right = This->glRect.left + maxSize;
1606 if(This->glRect.right > This->currentDesc.Width) {
1607 This->glRect.right = This->currentDesc.Width;
1608 This->glRect.left = This->glRect.right - maxSize;
1611 This->glRect.left = 0;
1612 This->glRect.right = This->pow2Width;
1615 if(This->pow2Height > maxSize) {
1616 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
1617 if(This->glRect.top < 0) This->glRect.top = 0;
1618 This->glRect.bottom = This->glRect.left + maxSize;
1619 if(This->glRect.bottom > This->currentDesc.Height) {
1620 This->glRect.bottom = This->currentDesc.Height;
1621 This->glRect.top = This->glRect.bottom - maxSize;
1624 This->glRect.top = 0;
1625 This->glRect.bottom = This->pow2Height;
1627 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
1628 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
1631 /* Re-calculate the rect to draw */
1632 Rect->left -= This->glRect.left;
1633 Rect->right -= This->glRect.left;
1634 Rect->top -= This->glRect.top;
1635 Rect->bottom -= This->glRect.top;
1637 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
1638 * or the pow2Width / pow2Height of the surface.
1640 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
1641 * as regular GL_TEXTURE_2D.
1643 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
1644 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
1645 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
1646 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
1650 #undef GLINFO_LOCATION
1652 /* Hash table functions */
1654 struct hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
1656 struct hash_table_t *table;
1657 unsigned int initial_size = 8;
1659 table = HeapAlloc(GetProcessHeap(), 0, sizeof(struct hash_table_t) + (initial_size * sizeof(struct list)));
1662 ERR("Failed to allocate table, returning NULL.\n");
1666 table->hash_function = hash_function;
1667 table->compare_function = compare_function;
1669 table->grow_size = initial_size - (initial_size >> 2);
1670 table->shrink_size = 0;
1672 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
1673 if (!table->buckets)
1675 ERR("Failed to allocate table buckets, returning NULL.\n");
1676 HeapFree(GetProcessHeap(), 0, table);
1679 table->bucket_count = initial_size;
1681 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(struct hash_table_entry_t));
1682 if (!table->entries)
1684 ERR("Failed to allocate table entries, returning NULL.\n");
1685 HeapFree(GetProcessHeap(), 0, table->buckets);
1686 HeapFree(GetProcessHeap(), 0, table);
1689 table->entry_count = 0;
1691 list_init(&table->free_entries);
1697 void hash_table_destroy(struct hash_table_t *table, void (*free_value)(void *value, void *cb), void *cb)
1701 for (i = 0; i < table->entry_count; ++i)
1704 free_value(table->entries[i].value, cb);
1706 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
1709 HeapFree(GetProcessHeap(), 0, table->entries);
1710 HeapFree(GetProcessHeap(), 0, table->buckets);
1711 HeapFree(GetProcessHeap(), 0, table);
1714 static inline struct hash_table_entry_t *hash_table_get_by_idx(const struct hash_table_t *table, const void *key,
1717 struct hash_table_entry_t *entry;
1719 if (table->buckets[idx].next)
1720 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), struct hash_table_entry_t, entry)
1721 if (table->compare_function(entry->key, key)) return entry;
1726 static BOOL hash_table_resize(struct hash_table_t *table, unsigned int new_bucket_count)
1728 unsigned int new_entry_count = 0;
1729 struct hash_table_entry_t *new_entries;
1730 struct list *new_buckets;
1731 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
1734 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
1737 ERR("Failed to allocate new buckets, returning FALSE.\n");
1741 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(struct hash_table_entry_t));
1744 ERR("Failed to allocate new entries, returning FALSE.\n");
1745 HeapFree(GetProcessHeap(), 0, new_buckets);
1749 for (i = 0; i < table->bucket_count; ++i)
1751 if (table->buckets[i].next)
1753 struct hash_table_entry_t *entry, *entry2;
1755 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], struct hash_table_entry_t, entry)
1758 struct hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
1759 *new_entry = *entry;
1761 j = new_entry->hash & (new_bucket_count - 1);
1763 if (!new_buckets[j].next) list_init(&new_buckets[j]);
1764 list_add_head(&new_buckets[j], &new_entry->entry);
1769 HeapFree(GetProcessHeap(), 0, table->buckets);
1770 table->buckets = new_buckets;
1772 HeapFree(GetProcessHeap(), 0, table->entries);
1773 table->entries = new_entries;
1775 table->entry_count = new_entry_count;
1776 list_init(&table->free_entries);
1778 table->bucket_count = new_bucket_count;
1779 table->grow_size = grow_size;
1780 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
1785 void hash_table_put(struct hash_table_t *table, void *key, void *value)
1789 struct hash_table_entry_t *entry;
1791 hash = table->hash_function(key);
1792 idx = hash & (table->bucket_count - 1);
1793 entry = hash_table_get_by_idx(table, key, idx);
1797 HeapFree(GetProcessHeap(), 0, key);
1798 entry->value = value;
1802 HeapFree(GetProcessHeap(), 0, entry->key);
1805 /* Remove the entry */
1806 list_remove(&entry->entry);
1807 list_add_head(&table->free_entries, &entry->entry);
1811 /* Shrink if necessary */
1812 if (table->count < table->shrink_size) {
1813 if (!hash_table_resize(table, table->bucket_count >> 1))
1815 ERR("Failed to shrink the table...\n");
1825 /* Grow if necessary */
1826 if (table->count >= table->grow_size)
1828 if (!hash_table_resize(table, table->bucket_count << 1))
1830 ERR("Failed to grow the table, returning.\n");
1834 idx = hash & (table->bucket_count - 1);
1837 /* Find an entry to insert */
1838 if (!list_empty(&table->free_entries))
1840 struct list *elem = list_head(&table->free_entries);
1843 entry = LIST_ENTRY(elem, struct hash_table_entry_t, entry);
1845 entry = table->entries + (table->entry_count++);
1848 /* Insert the entry */
1850 entry->value = value;
1852 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
1853 list_add_head(&table->buckets[idx], &entry->entry);
1858 void hash_table_remove(struct hash_table_t *table, void *key)
1860 hash_table_put(table, key, NULL);
1863 void *hash_table_get(const struct hash_table_t *table, const void *key)
1866 struct hash_table_entry_t *entry;
1868 idx = table->hash_function(key) & (table->bucket_count - 1);
1869 entry = hash_table_get_by_idx(table, key, idx);
1871 return entry ? entry->value : NULL;
1874 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
1875 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
1879 static const unsigned char args[WINED3DTOP_LERP + 1] = {
1881 /* D3DTOP_DISABLE */ 0,
1882 /* D3DTOP_SELECTARG1 */ ARG1,
1883 /* D3DTOP_SELECTARG2 */ ARG2,
1884 /* D3DTOP_MODULATE */ ARG1 | ARG2,
1885 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
1886 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
1887 /* D3DTOP_ADD */ ARG1 | ARG2,
1888 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
1889 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
1890 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
1891 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
1892 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
1893 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
1894 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
1895 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
1896 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
1897 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
1898 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
1899 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
1900 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
1901 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
1902 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
1903 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
1904 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
1905 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
1906 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
1910 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
1912 for(i = 0; i < GL_LIMITS(texture_stages); i++) {
1913 IWineD3DBaseTextureImpl *texture;
1914 settings->op[i].padding = 0;
1915 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
1916 settings->op[i].cop = WINED3DTOP_DISABLE;
1917 settings->op[i].aop = WINED3DTOP_DISABLE;
1918 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
1919 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
1920 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
1921 settings->op[i].dst = resultreg;
1922 settings->op[i].tex_type = tex_1d;
1923 settings->op[i].projected = proj_none;
1928 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
1930 settings->op[i].color_fixup = texture->baseTexture.shader_color_fixup;
1931 if(ignore_textype) {
1932 settings->op[i].tex_type = tex_1d;
1934 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
1936 settings->op[i].tex_type = tex_1d;
1939 settings->op[i].tex_type = tex_2d;
1942 settings->op[i].tex_type = tex_3d;
1944 case GL_TEXTURE_CUBE_MAP_ARB:
1945 settings->op[i].tex_type = tex_cube;
1947 case GL_TEXTURE_RECTANGLE_ARB:
1948 settings->op[i].tex_type = tex_rect;
1953 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
1954 settings->op[i].tex_type = tex_1d;
1957 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
1958 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
1960 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
1961 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
1962 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
1964 if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
1965 carg1, carg2, carg0)) {
1968 carg1 = WINED3DTA_CURRENT;
1969 cop = WINED3DTOP_SELECTARG1;
1972 if(cop == WINED3DTOP_DOTPRODUCT3) {
1973 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
1974 * the color result to the alpha component of the destination
1981 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
1982 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
1983 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
1986 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
1988 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
1990 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
1992 IWineD3DSurfaceImpl *surf;
1993 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
1995 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT
1996 && getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000)
1998 if (aop == WINED3DTOP_DISABLE)
2000 aarg1 = WINED3DTA_TEXTURE;
2001 aop = WINED3DTOP_SELECTARG1;
2003 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2005 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2007 aarg2 = WINED3DTA_TEXTURE;
2008 aop = WINED3DTOP_MODULATE;
2010 else aarg1 = WINED3DTA_TEXTURE;
2012 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2014 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2016 aarg1 = WINED3DTA_TEXTURE;
2017 aop = WINED3DTOP_MODULATE;
2019 else aarg2 = WINED3DTA_TEXTURE;
2025 if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
2026 aarg1, aarg2, aarg0)) {
2029 aarg1 = WINED3DTA_CURRENT;
2030 aop = WINED3DTOP_SELECTARG1;
2033 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2034 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2035 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2036 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2037 settings->op[i].projected = proj_count3;
2038 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2039 settings->op[i].projected = proj_count4;
2041 settings->op[i].projected = proj_none;
2044 settings->op[i].projected = proj_none;
2047 settings->op[i].cop = cop;
2048 settings->op[i].aop = aop;
2049 settings->op[i].carg0 = carg0;
2050 settings->op[i].carg1 = carg1;
2051 settings->op[i].carg2 = carg2;
2052 settings->op[i].aarg0 = aarg0;
2053 settings->op[i].aarg1 = aarg1;
2054 settings->op[i].aarg2 = aarg2;
2056 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2057 settings->op[i].dst = tempreg;
2059 settings->op[i].dst = resultreg;
2063 /* Clear unsupported stages */
2064 for(; i < MAX_TEXTURES; i++) {
2065 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2068 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2069 settings->fog = FOG_OFF;
2070 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2071 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2072 case WINED3DFOG_NONE:
2073 case WINED3DFOG_LINEAR:
2074 settings->fog = FOG_LINEAR;
2076 case WINED3DFOG_EXP:
2077 settings->fog = FOG_EXP;
2079 case WINED3DFOG_EXP2:
2080 settings->fog = FOG_EXP2;
2084 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2085 case WINED3DFOG_LINEAR:
2086 settings->fog = FOG_LINEAR;
2088 case WINED3DFOG_EXP:
2089 settings->fog = FOG_EXP;
2091 case WINED3DFOG_EXP2:
2092 settings->fog = FOG_EXP2;
2096 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2097 settings->sRGB_write = 1;
2099 settings->sRGB_write = 0;
2102 #undef GLINFO_LOCATION
2104 const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
2105 const struct ffp_frag_settings *settings)
2107 return (const struct ffp_frag_desc *)hash_table_get(fragment_shaders, settings);
2110 void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *desc) {
2111 struct ffp_frag_settings *key = HeapAlloc(GetProcessHeap(), 0, sizeof(*key));
2112 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2113 * whereas desc points to an extended structure with implementation specific parts.
2114 * Make a copy of the key because hash_table_put takes ownership of it
2116 *key = desc->settings;
2117 hash_table_put(shaders, key, desc);
2120 /* Activates the texture dimension according to the bound D3D texture.
2121 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2122 * Requires the caller to activate the correct unit before
2124 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2125 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2126 if(stateblock->textures[stage]) {
2127 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2129 glDisable(GL_TEXTURE_3D);
2130 checkGLcall("glDisable(GL_TEXTURE_3D)");
2131 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2132 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2133 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2135 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2136 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2137 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2139 glEnable(GL_TEXTURE_2D);
2140 checkGLcall("glEnable(GL_TEXTURE_2D)");
2142 case GL_TEXTURE_RECTANGLE_ARB:
2143 glDisable(GL_TEXTURE_2D);
2144 checkGLcall("glDisable(GL_TEXTURE_2D)");
2145 glDisable(GL_TEXTURE_3D);
2146 checkGLcall("glDisable(GL_TEXTURE_3D)");
2147 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2148 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2149 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2151 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2152 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2155 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2156 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2157 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2159 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2160 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2161 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2163 glDisable(GL_TEXTURE_2D);
2164 checkGLcall("glDisable(GL_TEXTURE_2D)");
2165 glEnable(GL_TEXTURE_3D);
2166 checkGLcall("glEnable(GL_TEXTURE_3D)");
2168 case GL_TEXTURE_CUBE_MAP_ARB:
2169 glDisable(GL_TEXTURE_2D);
2170 checkGLcall("glDisable(GL_TEXTURE_2D)");
2171 glDisable(GL_TEXTURE_3D);
2172 checkGLcall("glDisable(GL_TEXTURE_3D)");
2173 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2174 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2175 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2177 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2178 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2182 glEnable(GL_TEXTURE_2D);
2183 checkGLcall("glEnable(GL_TEXTURE_2D)");
2184 glDisable(GL_TEXTURE_3D);
2185 checkGLcall("glDisable(GL_TEXTURE_3D)");
2186 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2187 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2188 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2190 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2191 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2192 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2194 /* Binding textures is done by samplers. A dummy texture will be bound */
2198 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2199 DWORD sampler = state - STATE_SAMPLER(0);
2200 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2202 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2203 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2204 * will take care of this business
2206 if(mapped_stage == -1 || mapped_stage >= GL_LIMITS(textures)) return;
2207 if(sampler >= stateblock->lowest_disabled_stage) return;
2208 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2210 texture_activate_dimensions(sampler, stateblock, context);
2212 #undef GLINFO_LOCATION
2214 unsigned int ffp_frag_program_key_hash(const void *key)
2216 const struct ffp_frag_settings *k = (const struct ffp_frag_settings *)key;
2217 unsigned int hash = 0, i;
2220 /* This takes the texture op settings of stage 0 and 1 into account.
2221 * how exactly depends on the memory laybout of the compiler, but it
2222 * should not matter too much. Stages > 1 are used rarely, so there's
2223 * no need to process them. Even if they're used it is likely that
2224 * the ffp setup has distinct stage 0 and 1 settings.
2226 for(i = 0; i < 2; i++) {
2227 blob = (const DWORD *)&k->op[i];
2228 hash ^= blob[0] ^ blob[1];
2231 hash += ~(hash << 15);
2232 hash ^= (hash >> 10);
2233 hash += (hash << 3);
2234 hash ^= (hash >> 6);
2235 hash += ~(hash << 11);
2236 hash ^= (hash >> 16);
2241 BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb)
2243 const struct ffp_frag_settings *ka = (const struct ffp_frag_settings *)keya;
2244 const struct ffp_frag_settings *kb = (const struct ffp_frag_settings *)keyb;
2246 return memcmp(ka, kb, sizeof(*ka)) == 0;
2249 UINT wined3d_log2i(UINT32 x)
2251 static const BYTE l[] =
2253 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2254 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2255 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2256 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2257 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2258 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2259 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2260 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2261 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2262 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2263 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2264 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2265 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2266 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2267 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2268 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2272 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];