cryptui: Add a header bitmap to CryptUIWizImport's interior pages.
[wine/wine64.git] / dlls / wined3d / utils.c
blob95ee0ec139289a38d379ce27915955ea8ec55787
1 /*
2 * Utility functions for the WineD3D Library
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2008 Henri Verbeet
9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
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
26 #include "config.h"
27 #include "wined3d_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
31 /*****************************************************************************
32 * Pixel format array
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 },
56 /* IEEE formats */
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 },
60 /* Hmm? */
61 {WINED3DFMT_CxV8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
62 /* Float */
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 },
87 /* Luminance */
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 },
121 typedef struct {
122 WINED3DFORMAT fmt;
123 GLint glInternal, glGammaInternal, rtInternal, glFormat, glType;
124 unsigned int Flags;
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
131 * table.
133 static const GlPixelFormatDescTemplate gl_formats_template[] = {
134 /*{ internal ,srgbInternal , rtInternal, format ,type \
135 ,Flags }*/
136 {WINED3DFMT_UNKNOWN ,0 ,0 , 0, 0 ,0
137 ,0 },
138 /* FourCC formats */
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
143 * endian machine
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
162 ,0 },
163 {WINED3DFMT_G8R8_G8B8 ,0 ,0 , 0, 0 ,0
164 ,0 },
165 {WINED3DFMT_R8G8_B8G8 ,0 ,0 , 0, 0 ,0
166 ,0 },
167 /* IEEE formats */
168 {WINED3DFMT_R32F ,GL_RGB32F_ARB ,GL_RGB32F_ARB , 0, GL_RED ,GL_FLOAT
169 ,WINED3DFMT_FLAG_RENDERTARGET },
170 {WINED3DFMT_G32R32F ,GL_RG32F ,GL_RG32F , 0, GL_RG ,GL_FLOAT
171 ,WINED3DFMT_FLAG_RENDERTARGET },
172 {WINED3DFMT_A32B32G32R32F ,GL_RGBA32F_ARB ,GL_RGBA32F_ARB , 0, GL_RGBA ,GL_FLOAT
173 ,WINED3DFMT_FLAG_RENDERTARGET },
174 /* Hmm? */
175 {WINED3DFMT_CxV8U8 ,0 ,0 , 0, 0 ,0
176 ,0 },
177 /* Float */
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 ,GL_RG16F ,GL_RG16F , 0, GL_RG ,GL_HALF_FLOAT_ARB
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
186 ,0 },
187 {WINED3DFMT_P8, GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX8_EXT , 0, GL_COLOR_INDEX ,GL_UNSIGNED_BYTE
188 ,0 },
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
209 ,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 },
224 /* Luminance */
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
230 ,0 },
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
243 ,0 },
244 {WINED3DFMT_A2W10V10U10 ,0 ,0 , 0, 0 ,0
245 ,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
269 ,0 },
270 {WINED3DFMT_INDEX16 ,0 ,0 , 0, 0 ,0
271 ,0 },
272 {WINED3DFMT_INDEX32 ,0 ,0 , 0, 0 ,0
273 ,0 },
274 {WINED3DFMT_Q16W16V16U16 ,GL_COLOR_INDEX ,GL_COLOR_INDEX , 0, GL_COLOR_INDEX ,GL_UNSIGNED_SHORT
275 ,0 },
276 /* Vendor-specific formats */
277 {WINED3DFMT_ATI2N ,0 ,0 , 0, GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE
278 ,0 },
279 {WINED3DFMT_NVHU ,0 ,0 , 0, GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE
280 ,0 },
281 {WINED3DFMT_NVHS ,0 ,0 , 0, GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE
282 ,0 }
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) {
290 return fmt;
291 } else {
292 unsigned int i;
293 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
294 if(formats[i].format == fmt) {
295 return i;
299 return -1;
302 #define GLINFO_LOCATION (*gl_info)
303 BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
305 unsigned int src;
306 int dst;
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
313 * after this loop
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) {
327 GLuint tex, fb;
328 GLenum status;
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
335 while(glGetError());
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;
356 } else {
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;
361 } else {
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);
369 /* When ARB_texture_rg is supported we only require 16-bit for R16F instead of 64-bit RGBA16F */
370 if(GL_SUPPORT(ARB_TEXTURE_RG))
372 gl_info->gl_formats[dst].glInternal = GL_R16F;
373 gl_info->gl_formats[dst].glGammaInternal = GL_R16F;
376 dst = getFmtIdx(WINED3DFMT_R32F);
377 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
378 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
379 /* When ARB_texture_rg is supported we only require 32-bit for R32F instead of 128-bit RGBA32F */
380 if(GL_SUPPORT(ARB_TEXTURE_RG))
382 gl_info->gl_formats[dst].glInternal = GL_R32F;
383 gl_info->gl_formats[dst].glGammaInternal = GL_R32F;
386 dst = getFmtIdx(WINED3DFMT_G16R16);
387 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
388 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
390 dst = getFmtIdx(WINED3DFMT_G16R16F);
391 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
392 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
394 dst = getFmtIdx(WINED3DFMT_G32R32F);
395 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
396 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
398 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
399 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
400 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
401 * the only driver that implements it(fglrx) has a buggy implementation.
403 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
404 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
405 * conversion for this format.
407 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
409 dst = getFmtIdx(WINED3DFMT_V8U8);
410 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
411 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
412 dst = getFmtIdx(WINED3DFMT_V16U16);
413 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
414 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
416 else
418 dst = getFmtIdx(WINED3DFMT_V8U8);
419 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
420 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
421 dst = getFmtIdx(WINED3DFMT_V16U16);
422 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
423 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
426 if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
427 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
428 * with each other
430 dst = getFmtIdx(WINED3DFMT_L6V5U5);
431 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
432 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
433 dst = getFmtIdx(WINED3DFMT_X8L8V8U8);
434 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
435 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
436 dst = getFmtIdx(WINED3DFMT_Q8W8V8U8);
437 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
438 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
439 } else {
440 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
441 * are converted at surface loading time, but they do not need any modification in
442 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
443 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
447 if(GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
448 dst = getFmtIdx(WINED3DFMT_ATI2N);
449 gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
450 gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
451 gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
452 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
453 } else if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC)) {
454 dst = getFmtIdx(WINED3DFMT_ATI2N);
455 gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
456 gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
457 gl_info->gl_formats[dst].color_fixup= create_color_fixup_desc(
458 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
461 if(!GL_SUPPORT(APPLE_YCBCR_422)) {
462 dst = getFmtIdx(WINED3DFMT_YUY2);
463 gl_info->gl_formats[dst].glInternal = GL_LUMINANCE_ALPHA;
464 gl_info->gl_formats[dst].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
465 gl_info->gl_formats[dst].glFormat = GL_LUMINANCE_ALPHA;
466 gl_info->gl_formats[dst].glType = GL_UNSIGNED_BYTE;
467 gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
469 dst = getFmtIdx(WINED3DFMT_UYVY);
470 gl_info->gl_formats[dst].glInternal = GL_LUMINANCE_ALPHA;
471 gl_info->gl_formats[dst].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
472 gl_info->gl_formats[dst].glFormat = GL_LUMINANCE_ALPHA;
473 gl_info->gl_formats[dst].glType = GL_UNSIGNED_BYTE;
474 gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
477 dst = getFmtIdx(WINED3DFMT_YV12);
478 gl_info->gl_formats[dst].heightscale = 1.5;
479 gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
481 return TRUE;
484 /* NOTE: Make sure these are in the correct numerical order. (see /include/wined3d_types.h) */
485 static WINED3DGLTYPE const glTypeLookupTemplate[WINED3DDECLTYPE_UNUSED] = {
486 {WINED3DDECLTYPE_FLOAT1, 1, GL_FLOAT , GL_FALSE ,sizeof(float)},
487 {WINED3DDECLTYPE_FLOAT2, 2, GL_FLOAT , GL_FALSE ,sizeof(float)},
488 {WINED3DDECLTYPE_FLOAT3, 3, GL_FLOAT , GL_FALSE ,sizeof(float)},
489 {WINED3DDECLTYPE_FLOAT4, 4, GL_FLOAT , GL_FALSE ,sizeof(float)},
490 {WINED3DDECLTYPE_D3DCOLOR, 4, GL_UNSIGNED_BYTE , GL_TRUE ,sizeof(BYTE)},
491 {WINED3DDECLTYPE_UBYTE4, 4, GL_UNSIGNED_BYTE , GL_FALSE ,sizeof(BYTE)},
492 {WINED3DDECLTYPE_SHORT2, 2, GL_SHORT , GL_FALSE ,sizeof(short int)},
493 {WINED3DDECLTYPE_SHORT4, 4, GL_SHORT , GL_FALSE ,sizeof(short int)},
494 {WINED3DDECLTYPE_UBYTE4N, 4, GL_UNSIGNED_BYTE , GL_TRUE ,sizeof(BYTE)},
495 {WINED3DDECLTYPE_SHORT2N, 2, GL_SHORT , GL_TRUE ,sizeof(short int)},
496 {WINED3DDECLTYPE_SHORT4N, 4, GL_SHORT , GL_TRUE ,sizeof(short int)},
497 {WINED3DDECLTYPE_USHORT2N, 2, GL_UNSIGNED_SHORT , GL_TRUE ,sizeof(short int)},
498 {WINED3DDECLTYPE_USHORT4N, 4, GL_UNSIGNED_SHORT , GL_TRUE ,sizeof(short int)},
499 {WINED3DDECLTYPE_UDEC3, 3, GL_UNSIGNED_SHORT , GL_FALSE ,sizeof(short int)},
500 {WINED3DDECLTYPE_DEC3N, 3, GL_SHORT , GL_TRUE ,sizeof(short int)},
501 {WINED3DDECLTYPE_FLOAT16_2, 2, GL_HALF_FLOAT_NV , GL_FALSE ,sizeof(GLhalfNV)},
502 {WINED3DDECLTYPE_FLOAT16_4, 4, GL_HALF_FLOAT_NV , GL_FALSE ,sizeof(GLhalfNV)}};
504 void init_type_lookup(WineD3D_GL_Info *gl_info) {
505 memcpy(gl_info->glTypeLookup, glTypeLookupTemplate, sizeof(glTypeLookupTemplate));
506 if(!GL_SUPPORT(NV_HALF_FLOAT)) {
507 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
508 * It is the job of the vertex buffer code to make sure that the vbos have the right format
510 gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_2].glType = GL_FLOAT;
511 gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_4].glType = GL_FLOAT;
515 #undef GLINFO_LOCATION
517 #define GLINFO_LOCATION This->adapter->gl_info
519 const StaticPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const WineD3D_GL_Info *gl_info,
520 const struct GlPixelFormatDesc **glDesc)
522 int idx = getFmtIdx(fmt);
524 if(idx == -1) {
525 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
526 /* Get the caller a valid pointer */
527 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
529 if(glDesc) {
530 if(!gl_info->gl_formats) {
531 /* If we do not have gl format information, provide a dummy NULL format. This is an easy way to make
532 * all gl caps check return "unsupported" than catching the lack of gl all over the code. ANSI C requires
533 * static variables to be initialized to 0.
535 static const struct GlPixelFormatDesc dummyFmt;
536 *glDesc = &dummyFmt;
537 } else {
538 *glDesc = &gl_info->gl_formats[idx];
541 return &formats[idx];
544 /*****************************************************************************
545 * Trace formatting of useful values
547 const char* debug_d3dformat(WINED3DFORMAT fmt) {
548 switch (fmt) {
549 #define FMT_TO_STR(fmt) case fmt: return #fmt
550 FMT_TO_STR(WINED3DFMT_UNKNOWN);
551 FMT_TO_STR(WINED3DFMT_R8G8B8);
552 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
553 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
554 FMT_TO_STR(WINED3DFMT_R5G6B5);
555 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
556 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
557 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
558 FMT_TO_STR(WINED3DFMT_R3G3B2);
559 FMT_TO_STR(WINED3DFMT_A8);
560 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
561 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
562 FMT_TO_STR(WINED3DFMT_A2B10G10R10);
563 FMT_TO_STR(WINED3DFMT_A8B8G8R8);
564 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
565 FMT_TO_STR(WINED3DFMT_G16R16);
566 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
567 FMT_TO_STR(WINED3DFMT_A16B16G16R16);
568 FMT_TO_STR(WINED3DFMT_A8P8);
569 FMT_TO_STR(WINED3DFMT_P8);
570 FMT_TO_STR(WINED3DFMT_L8);
571 FMT_TO_STR(WINED3DFMT_A8L8);
572 FMT_TO_STR(WINED3DFMT_A4L4);
573 FMT_TO_STR(WINED3DFMT_V8U8);
574 FMT_TO_STR(WINED3DFMT_L6V5U5);
575 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
576 FMT_TO_STR(WINED3DFMT_Q8W8V8U8);
577 FMT_TO_STR(WINED3DFMT_V16U16);
578 FMT_TO_STR(WINED3DFMT_W11V11U10);
579 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
580 FMT_TO_STR(WINED3DFMT_UYVY);
581 FMT_TO_STR(WINED3DFMT_YUY2);
582 FMT_TO_STR(WINED3DFMT_YV12);
583 FMT_TO_STR(WINED3DFMT_DXT1);
584 FMT_TO_STR(WINED3DFMT_DXT2);
585 FMT_TO_STR(WINED3DFMT_DXT3);
586 FMT_TO_STR(WINED3DFMT_DXT4);
587 FMT_TO_STR(WINED3DFMT_DXT5);
588 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
589 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
590 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
591 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
592 FMT_TO_STR(WINED3DFMT_D32);
593 FMT_TO_STR(WINED3DFMT_D15S1);
594 FMT_TO_STR(WINED3DFMT_D24S8);
595 FMT_TO_STR(WINED3DFMT_D24X8);
596 FMT_TO_STR(WINED3DFMT_D24X4S4);
597 FMT_TO_STR(WINED3DFMT_D16);
598 FMT_TO_STR(WINED3DFMT_L16);
599 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
600 FMT_TO_STR(WINED3DFMT_D24FS8);
601 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
602 FMT_TO_STR(WINED3DFMT_INDEX16);
603 FMT_TO_STR(WINED3DFMT_INDEX32);
604 FMT_TO_STR(WINED3DFMT_Q16W16V16U16);
605 FMT_TO_STR(WINED3DFMT_R16F);
606 FMT_TO_STR(WINED3DFMT_G16R16F);
607 FMT_TO_STR(WINED3DFMT_A16B16G16R16F);
608 FMT_TO_STR(WINED3DFMT_R32F);
609 FMT_TO_STR(WINED3DFMT_G32R32F);
610 FMT_TO_STR(WINED3DFMT_A32B32G32R32F);
611 FMT_TO_STR(WINED3DFMT_CxV8U8);
612 FMT_TO_STR(WINED3DFMT_ATI2N);
613 FMT_TO_STR(WINED3DFMT_NVHU);
614 FMT_TO_STR(WINED3DFMT_NVHS);
615 #undef FMT_TO_STR
616 default:
618 char fourcc[5];
619 fourcc[0] = (char)(fmt);
620 fourcc[1] = (char)(fmt >> 8);
621 fourcc[2] = (char)(fmt >> 16);
622 fourcc[3] = (char)(fmt >> 24);
623 fourcc[4] = 0;
624 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
625 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
626 else
627 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
629 return "unrecognized";
633 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
634 switch (devtype) {
635 #define DEVTYPE_TO_STR(dev) case dev: return #dev
636 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
637 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
638 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
639 #undef DEVTYPE_TO_STR
640 default:
641 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
642 return "unrecognized";
646 const char* debug_d3dusage(DWORD usage) {
647 switch (usage & WINED3DUSAGE_MASK) {
648 #define WINED3DUSAGE_TO_STR(u) case u: return #u
649 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
650 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
651 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
652 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
653 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
654 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
655 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
656 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
657 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
658 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
659 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
660 #undef WINED3DUSAGE_TO_STR
661 case 0: return "none";
662 default:
663 FIXME("Unrecognized %u Usage!\n", usage);
664 return "unrecognized";
668 const char* debug_d3dusagequery(DWORD usagequery) {
669 switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
670 #define WINED3DUSAGEQUERY_TO_STR(u) case u: return #u
671 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
672 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
673 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
674 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
675 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
676 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
677 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
678 #undef WINED3DUSAGEQUERY_TO_STR
679 case 0: return "none";
680 default:
681 FIXME("Unrecognized %u Usage Query!\n", usagequery);
682 return "unrecognized";
686 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
687 switch (method) {
688 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
689 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
690 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
691 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
692 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
693 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
694 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
695 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
696 #undef WINED3DDECLMETHOD_TO_STR
697 default:
698 FIXME("Unrecognized %u declaration method!\n", method);
699 return "unrecognized";
703 const char* debug_d3ddecltype(WINED3DDECLTYPE type) {
704 switch (type) {
705 #define WINED3DDECLTYPE_TO_STR(u) case u: return #u
706 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT1);
707 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT2);
708 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT3);
709 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT4);
710 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_D3DCOLOR);
711 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4);
712 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2);
713 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4);
714 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4N);
715 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2N);
716 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4N);
717 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT2N);
718 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT4N);
719 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UDEC3);
720 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_DEC3N);
721 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_2);
722 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_4);
723 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UNUSED);
724 #undef WINED3DDECLTYPE_TO_STR
725 default:
726 FIXME("Unrecognized %u declaration type!\n", type);
727 return "unrecognized";
731 const char* debug_d3ddeclusage(BYTE usage) {
732 switch (usage) {
733 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
734 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
735 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
736 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
737 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
738 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
739 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
740 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
741 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
742 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
743 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
744 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
745 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
746 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
747 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
748 #undef WINED3DDECLUSAGE_TO_STR
749 default:
750 FIXME("Unrecognized %u declaration usage!\n", usage);
751 return "unrecognized";
755 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
756 switch (res) {
757 #define RES_TO_STR(res) case res: return #res;
758 RES_TO_STR(WINED3DRTYPE_SURFACE);
759 RES_TO_STR(WINED3DRTYPE_VOLUME);
760 RES_TO_STR(WINED3DRTYPE_TEXTURE);
761 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
762 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
763 RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER);
764 RES_TO_STR(WINED3DRTYPE_INDEXBUFFER);
765 #undef RES_TO_STR
766 default:
767 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
768 return "unrecognized";
772 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
773 switch (PrimitiveType) {
774 #define PRIM_TO_STR(prim) case prim: return #prim;
775 PRIM_TO_STR(WINED3DPT_POINTLIST);
776 PRIM_TO_STR(WINED3DPT_LINELIST);
777 PRIM_TO_STR(WINED3DPT_LINESTRIP);
778 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
779 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
780 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
781 #undef PRIM_TO_STR
782 default:
783 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
784 return "unrecognized";
788 const char* debug_d3drenderstate(DWORD state) {
789 switch (state) {
790 #define D3DSTATE_TO_STR(u) case u: return #u
791 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
792 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
793 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
794 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
795 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
796 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
797 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
798 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
799 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
800 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
801 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
802 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
803 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
804 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
805 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
806 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
807 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
808 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
809 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
810 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
811 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
812 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
813 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
814 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
815 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
816 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
817 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
818 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
819 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
820 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
821 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
822 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
823 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
824 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
825 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
826 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
827 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
828 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
829 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
830 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
831 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
832 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
833 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
834 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
835 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
836 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
837 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
838 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
839 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
840 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
841 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
842 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
843 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
844 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
845 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
846 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
847 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
848 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
849 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
850 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
851 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
852 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
853 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
854 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
855 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
856 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
857 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
858 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
859 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
860 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
861 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
862 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
863 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
864 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
865 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
866 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
867 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
868 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
869 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
870 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
871 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
872 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
873 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
874 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
875 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
876 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
877 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
878 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
879 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
880 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
881 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
882 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
883 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
884 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
885 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
886 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
887 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
888 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
889 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
890 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
891 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
892 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
893 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
894 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
895 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
896 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
897 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
898 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
899 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
900 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
901 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
902 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
903 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
904 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
905 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
906 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
907 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
908 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
909 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
910 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
911 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
912 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
913 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
914 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
915 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
916 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
917 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
918 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
919 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
920 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
921 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
922 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
923 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
924 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
925 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
926 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
927 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
928 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
929 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
930 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
931 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
932 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
933 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
934 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
935 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
936 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
937 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
938 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
939 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
940 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
941 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
942 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
943 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
944 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
945 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
946 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
947 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
948 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
949 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
950 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
951 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
952 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
953 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
954 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
955 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
956 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
957 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
958 #undef D3DSTATE_TO_STR
959 default:
960 FIXME("Unrecognized %u render state!\n", state);
961 return "unrecognized";
965 const char* debug_d3dsamplerstate(DWORD state) {
966 switch (state) {
967 #define D3DSTATE_TO_STR(u) case u: return #u
968 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
969 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
970 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
971 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
972 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
973 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
974 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
975 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
976 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
977 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
978 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
979 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
980 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
981 #undef D3DSTATE_TO_STR
982 default:
983 FIXME("Unrecognized %u sampler state!\n", state);
984 return "unrecognized";
988 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
989 switch (filter_type) {
990 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
991 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
992 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
993 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
994 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
995 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
996 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
997 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
998 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
999 #undef D3DTEXTUREFILTERTYPE_TO_STR
1000 default:
1001 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1002 return "unrecognized";
1006 const char* debug_d3dtexturestate(DWORD state) {
1007 switch (state) {
1008 #define D3DSTATE_TO_STR(u) case u: return #u
1009 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1010 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1011 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1012 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1013 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1014 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1015 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1016 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1017 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1018 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1019 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1020 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1021 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1022 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1023 D3DSTATE_TO_STR(WINED3DTSS_ADDRESSW );
1024 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1025 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1026 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1027 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1028 #undef D3DSTATE_TO_STR
1029 case 12:
1030 /* Note WINED3DTSS are not consecutive, so skip these */
1031 return "unused";
1032 default:
1033 FIXME("Unrecognized %u texture state!\n", state);
1034 return "unrecognized";
1038 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1039 switch (d3dtop) {
1040 #define D3DTOP_TO_STR(u) case u: return #u
1041 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1042 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1043 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1044 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1045 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1046 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1047 D3DTOP_TO_STR(WINED3DTOP_ADD);
1048 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1049 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1050 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1051 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1052 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1053 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1054 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1055 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1056 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1057 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1058 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1059 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1060 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1061 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1062 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1063 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1064 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1065 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1066 D3DTOP_TO_STR(WINED3DTOP_LERP);
1067 #undef D3DTOP_TO_STR
1068 default:
1069 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1070 return "unrecognized";
1074 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1075 switch (tstype) {
1076 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1077 TSTYPE_TO_STR(WINED3DTS_VIEW);
1078 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1079 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1080 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1081 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1082 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1083 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1084 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1085 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1086 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1087 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1088 #undef TSTYPE_TO_STR
1089 default:
1090 if (tstype > 256 && tstype < 512) {
1091 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1092 return ("WINED3DTS_WORLDMATRIX > 0");
1094 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1095 return "unrecognized";
1099 const char* debug_d3dpool(WINED3DPOOL Pool) {
1100 switch (Pool) {
1101 #define POOL_TO_STR(p) case p: return #p;
1102 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1103 POOL_TO_STR(WINED3DPOOL_MANAGED);
1104 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1105 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1106 #undef POOL_TO_STR
1107 default:
1108 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1109 return "unrecognized";
1113 const char *debug_fbostatus(GLenum status) {
1114 switch(status) {
1115 #define FBOSTATUS_TO_STR(u) case u: return #u
1116 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1117 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1118 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1119 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1120 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1121 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1122 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1123 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
1124 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1125 #undef FBOSTATUS_TO_STR
1126 default:
1127 FIXME("Unrecognied FBO status 0x%08x\n", status);
1128 return "unrecognized";
1132 const char *debug_glerror(GLenum error) {
1133 switch(error) {
1134 #define GLERROR_TO_STR(u) case u: return #u
1135 GLERROR_TO_STR(GL_NO_ERROR);
1136 GLERROR_TO_STR(GL_INVALID_ENUM);
1137 GLERROR_TO_STR(GL_INVALID_VALUE);
1138 GLERROR_TO_STR(GL_INVALID_OPERATION);
1139 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1140 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1141 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1142 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1143 #undef GLERROR_TO_STR
1144 default:
1145 FIXME("Unrecognied GL error 0x%08x\n", error);
1146 return "unrecognized";
1150 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1151 switch(basis) {
1152 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1153 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1154 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1155 default: return "unrecognized";
1159 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1160 switch(degree) {
1161 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1162 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1163 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1164 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1165 default: return "unrecognized";
1169 const char *debug_fixup_channel_source(enum fixup_channel_source source)
1171 switch(source)
1173 #define WINED3D_TO_STR(x) case x: return #x
1174 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1175 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1176 WINED3D_TO_STR(CHANNEL_SOURCE_X);
1177 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1178 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1179 WINED3D_TO_STR(CHANNEL_SOURCE_W);
1180 WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1181 WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1182 #undef WINED3D_TO_STR
1183 default:
1184 FIXME("Unrecognized fixup_channel_source %#x\n", source);
1185 return "unrecognized";
1189 const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1191 switch(yuv_fixup)
1193 #define WINED3D_TO_STR(x) case x: return #x
1194 WINED3D_TO_STR(YUV_FIXUP_YUY2);
1195 WINED3D_TO_STR(YUV_FIXUP_UYVY);
1196 WINED3D_TO_STR(YUV_FIXUP_YV12);
1197 #undef WINED3D_TO_STR
1198 default:
1199 FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1200 return "unrecognized";
1204 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1206 if (is_yuv_fixup(fixup))
1208 TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1209 return;
1212 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1213 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1214 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1215 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1218 /*****************************************************************************
1219 * Useful functions mapping GL <-> D3D values
1221 GLenum StencilOp(DWORD op) {
1222 switch(op) {
1223 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1224 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1225 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1226 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1227 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1228 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1229 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1230 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1231 default:
1232 FIXME("Unrecognized stencil op %d\n", op);
1233 return GL_KEEP;
1237 GLenum CompareFunc(DWORD func) {
1238 switch ((WINED3DCMPFUNC)func) {
1239 case WINED3DCMP_NEVER : return GL_NEVER;
1240 case WINED3DCMP_LESS : return GL_LESS;
1241 case WINED3DCMP_EQUAL : return GL_EQUAL;
1242 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1243 case WINED3DCMP_GREATER : return GL_GREATER;
1244 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1245 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1246 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1247 default:
1248 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1249 return 0;
1253 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1254 if (op == WINED3DTOP_DISABLE) return FALSE;
1255 if (This->stateBlock->textures[stage]) return FALSE;
1257 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1258 && op != WINED3DTOP_SELECTARG2) return TRUE;
1259 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1260 && op != WINED3DTOP_SELECTARG1) return TRUE;
1261 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1262 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1264 return FALSE;
1267 /* Setup this textures matrix according to the texture flags*/
1268 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype,
1269 BOOL ffp_proj_control)
1271 float mat[16];
1273 glMatrixMode(GL_TEXTURE);
1274 checkGLcall("glMatrixMode(GL_TEXTURE)");
1276 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1277 glLoadIdentity();
1278 checkGLcall("glLoadIdentity()");
1279 return;
1282 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1283 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1284 return;
1287 memcpy(mat, smat, 16 * sizeof(float));
1289 if (flags & WINED3DTTFF_PROJECTED) {
1290 if(!ffp_proj_control) {
1291 switch (flags & ~WINED3DTTFF_PROJECTED) {
1292 case WINED3DTTFF_COUNT2:
1293 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1294 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1295 break;
1296 case WINED3DTTFF_COUNT3:
1297 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1298 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1299 break;
1302 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1303 if(!calculatedCoords) {
1304 switch(coordtype) {
1305 case WINED3DDECLTYPE_FLOAT1:
1306 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1307 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1308 * the input value to the transformation will be 0, so the matrix value is irrelevant
1310 mat[12] = mat[4];
1311 mat[13] = mat[5];
1312 mat[14] = mat[6];
1313 mat[15] = mat[7];
1314 break;
1315 case WINED3DDECLTYPE_FLOAT2:
1316 /* See above, just 3rd and 4th coord
1318 mat[12] = mat[8];
1319 mat[13] = mat[9];
1320 mat[14] = mat[10];
1321 mat[15] = mat[11];
1322 break;
1323 case WINED3DDECLTYPE_FLOAT3: /* Opengl defaults match dx defaults */
1324 case WINED3DDECLTYPE_FLOAT4: /* No defaults apply, all app defined */
1326 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1327 * into a bad place. The division elimination below will apply to make sure the
1328 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1330 case WINED3DDECLTYPE_UNUSED: /* No texture coords, 0/0/0/1 defaults are passed */
1331 break;
1332 default:
1333 FIXME("Unexpected fixed function texture coord input\n");
1336 if(!ffp_proj_control) {
1337 switch (flags & ~WINED3DTTFF_PROJECTED) {
1338 /* case WINED3DTTFF_COUNT1: Won't ever get here */
1339 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
1340 /* OpenGL divides the first 3 vertex coord by the 4th by default,
1341 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
1342 * the 4th coord evaluates to 1.0 to eliminate that.
1344 * If the fixed function pipeline is used, the 4th value remains unused,
1345 * so there is no danger in doing this. With vertex shaders we have a
1346 * problem. Should an app hit that problem, the code here would have to
1347 * check for pixel shaders, and the shader has to undo the default gl divide.
1349 * A more serious problem occurs if the app passes 4 coordinates in, and the
1350 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
1351 * or a replacement shader
1353 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
1358 glLoadMatrixf(mat);
1359 checkGLcall("glLoadMatrixf(mat)");
1361 #undef GLINFO_LOCATION
1363 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
1365 /* This small helper function is used to convert a bitmask into the number of masked bits */
1366 unsigned int count_bits(unsigned int mask)
1368 unsigned int count;
1369 for (count = 0; mask; ++count)
1371 mask &= mask - 1;
1373 return count;
1376 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
1377 * The later function requires individual color components. */
1378 BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
1380 const StaticPixelFormatDesc *desc;
1382 TRACE("fmt: %s\n", debug_d3dformat(fmt));
1383 switch(fmt)
1385 case WINED3DFMT_X8R8G8B8:
1386 case WINED3DFMT_R8G8B8:
1387 case WINED3DFMT_A8R8G8B8:
1388 case WINED3DFMT_A2R10G10B10:
1389 case WINED3DFMT_X1R5G5B5:
1390 case WINED3DFMT_A1R5G5B5:
1391 case WINED3DFMT_R5G6B5:
1392 case WINED3DFMT_X4R4G4B4:
1393 case WINED3DFMT_A4R4G4B4:
1394 case WINED3DFMT_R3G3B2:
1395 case WINED3DFMT_A8P8:
1396 case WINED3DFMT_P8:
1397 break;
1398 default:
1399 ERR("Unsupported format: %s\n", debug_d3dformat(fmt));
1400 return FALSE;
1403 desc = getFormatDescEntry(fmt, NULL, NULL);
1404 if(!desc)
1406 ERR("Unable to look up format: 0x%x\n", fmt);
1407 return FALSE;
1409 *redSize = count_bits(desc->redMask);
1410 *greenSize = count_bits(desc->greenMask);
1411 *blueSize = count_bits(desc->blueMask);
1412 *alphaSize = count_bits(desc->alphaMask);
1413 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
1415 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n", *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(fmt));
1416 return TRUE;
1419 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
1420 BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize)
1422 const StaticPixelFormatDesc *desc;
1424 TRACE("fmt: %s\n", debug_d3dformat(fmt));
1425 switch(fmt)
1427 case WINED3DFMT_D16_LOCKABLE:
1428 case WINED3DFMT_D16:
1429 case WINED3DFMT_D15S1:
1430 case WINED3DFMT_D24X8:
1431 case WINED3DFMT_D24X4S4:
1432 case WINED3DFMT_D24S8:
1433 case WINED3DFMT_D24FS8:
1434 case WINED3DFMT_D32:
1435 case WINED3DFMT_D32F_LOCKABLE:
1436 break;
1437 default:
1438 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(fmt));
1439 return FALSE;
1442 desc = getFormatDescEntry(fmt, NULL, NULL);
1443 if(!desc)
1445 ERR("Unable to look up format: 0x%x\n", fmt);
1446 return FALSE;
1448 *depthSize = desc->depthSize;
1449 *stencilSize = desc->stencilSize;
1451 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n", *depthSize, *stencilSize, debug_d3dformat(fmt));
1452 return TRUE;
1455 #undef GLINFO_LOCATION
1457 /* DirectDraw stuff */
1458 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
1459 switch(depth) {
1460 case 8: return WINED3DFMT_P8;
1461 case 15: return WINED3DFMT_X1R5G5B5;
1462 case 16: return WINED3DFMT_R5G6B5;
1463 case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
1464 case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
1465 default: return WINED3DFMT_UNKNOWN;
1469 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
1470 WINED3DMATRIX temp;
1472 /* Now do the multiplication 'by hand'.
1473 I know that all this could be optimised, but this will be done later :-) */
1474 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);
1475 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);
1476 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);
1477 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);
1479 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);
1480 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);
1481 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);
1482 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);
1484 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);
1485 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);
1486 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);
1487 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);
1489 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);
1490 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);
1491 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);
1492 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);
1494 /* And copy the new matrix in the good storage.. */
1495 memcpy(dest, &temp, 16 * sizeof(float));
1498 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
1499 DWORD size = 0;
1500 int i;
1501 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
1503 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
1504 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
1505 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
1506 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
1507 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
1508 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
1509 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
1510 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
1511 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
1512 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
1513 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
1514 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
1515 default: ERR("Unexpected position mask\n");
1517 for (i = 0; i < numTextures; i++) {
1518 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
1521 return size;
1524 /***********************************************************************
1525 * CalculateTexRect
1527 * Calculates the dimensions of the opengl texture used for blits.
1528 * Handled oversized opengl textures and updates the source rectangle
1529 * accordingly
1531 * Params:
1532 * This: Surface to operate on
1533 * Rect: Requested rectangle
1535 * Returns:
1536 * TRUE if the texture part can be loaded,
1537 * FALSE otherwise
1539 *********************************************************************/
1540 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
1542 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
1543 int x1 = Rect->left, x2 = Rect->right;
1544 int y1 = Rect->top, y2 = Rect->bottom;
1545 GLint maxSize = GL_LIMITS(texture_size);
1547 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
1548 Rect->left, Rect->top, Rect->right, Rect->bottom);
1550 /* The sizes might be reversed */
1551 if(Rect->left > Rect->right) {
1552 x1 = Rect->right;
1553 x2 = Rect->left;
1555 if(Rect->top > Rect->bottom) {
1556 y1 = Rect->bottom;
1557 y2 = Rect->top;
1560 /* No oversized texture? This is easy */
1561 if(!(This->Flags & SFLAG_OVERSIZE)) {
1562 /* Which rect from the texture do I need? */
1563 if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
1564 glTexCoord[0] = (float) Rect->left;
1565 glTexCoord[2] = (float) Rect->top;
1566 glTexCoord[1] = (float) Rect->right;
1567 glTexCoord[3] = (float) Rect->bottom;
1568 } else {
1569 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
1570 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
1571 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
1572 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
1575 return TRUE;
1576 } else {
1577 /* Check if we can succeed at all */
1578 if( (x2 - x1) > maxSize ||
1579 (y2 - y1) > maxSize ) {
1580 TRACE("Requested rectangle is too large for gl\n");
1581 return FALSE;
1584 /* A part of the texture has to be picked. First, check if
1585 * some texture part is loaded already, if yes try to re-use it.
1586 * If the texture is dirty, or the part can't be used,
1587 * re-position the part to load
1589 if(This->Flags & SFLAG_INTEXTURE) {
1590 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
1591 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
1592 /* Ok, the rectangle is ok, re-use it */
1593 TRACE("Using existing gl Texture\n");
1594 } else {
1595 /* Rectangle is not ok, dirtify the texture to reload it */
1596 TRACE("Dirtifying texture to force reload\n");
1597 This->Flags &= ~SFLAG_INTEXTURE;
1601 /* Now if we are dirty(no else if!) */
1602 if(!(This->Flags & SFLAG_INTEXTURE)) {
1603 /* Set the new rectangle. Use the following strategy:
1604 * 1) Use as big textures as possible.
1605 * 2) Place the texture part in the way that the requested
1606 * part is in the middle of the texture(well, almost)
1607 * 3) If the texture is moved over the edges of the
1608 * surface, replace it nicely
1609 * 4) If the coord is not limiting the texture size,
1610 * use the whole size
1612 if((This->pow2Width) > maxSize) {
1613 This->glRect.left = x1 - maxSize / 2;
1614 if(This->glRect.left < 0) {
1615 This->glRect.left = 0;
1617 This->glRect.right = This->glRect.left + maxSize;
1618 if(This->glRect.right > This->currentDesc.Width) {
1619 This->glRect.right = This->currentDesc.Width;
1620 This->glRect.left = This->glRect.right - maxSize;
1622 } else {
1623 This->glRect.left = 0;
1624 This->glRect.right = This->pow2Width;
1627 if(This->pow2Height > maxSize) {
1628 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
1629 if(This->glRect.top < 0) This->glRect.top = 0;
1630 This->glRect.bottom = This->glRect.left + maxSize;
1631 if(This->glRect.bottom > This->currentDesc.Height) {
1632 This->glRect.bottom = This->currentDesc.Height;
1633 This->glRect.top = This->glRect.bottom - maxSize;
1635 } else {
1636 This->glRect.top = 0;
1637 This->glRect.bottom = This->pow2Height;
1639 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
1640 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
1643 /* Re-calculate the rect to draw */
1644 Rect->left -= This->glRect.left;
1645 Rect->right -= This->glRect.left;
1646 Rect->top -= This->glRect.top;
1647 Rect->bottom -= This->glRect.top;
1649 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
1650 * or the pow2Width / pow2Height of the surface.
1652 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
1653 * as regular GL_TEXTURE_2D.
1655 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
1656 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
1657 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
1658 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
1660 return TRUE;
1662 #undef GLINFO_LOCATION
1664 /* Hash table functions */
1666 struct hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
1668 struct hash_table_t *table;
1669 unsigned int initial_size = 8;
1671 table = HeapAlloc(GetProcessHeap(), 0, sizeof(struct hash_table_t) + (initial_size * sizeof(struct list)));
1672 if (!table)
1674 ERR("Failed to allocate table, returning NULL.\n");
1675 return NULL;
1678 table->hash_function = hash_function;
1679 table->compare_function = compare_function;
1681 table->grow_size = initial_size - (initial_size >> 2);
1682 table->shrink_size = 0;
1684 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
1685 if (!table->buckets)
1687 ERR("Failed to allocate table buckets, returning NULL.\n");
1688 HeapFree(GetProcessHeap(), 0, table);
1689 return NULL;
1691 table->bucket_count = initial_size;
1693 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(struct hash_table_entry_t));
1694 if (!table->entries)
1696 ERR("Failed to allocate table entries, returning NULL.\n");
1697 HeapFree(GetProcessHeap(), 0, table->buckets);
1698 HeapFree(GetProcessHeap(), 0, table);
1699 return NULL;
1701 table->entry_count = 0;
1703 list_init(&table->free_entries);
1704 table->count = 0;
1706 return table;
1709 void hash_table_destroy(struct hash_table_t *table, void (*free_value)(void *value, void *cb), void *cb)
1711 unsigned int i = 0;
1713 for (i = 0; i < table->entry_count; ++i)
1715 if(free_value) {
1716 free_value(table->entries[i].value, cb);
1718 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
1721 HeapFree(GetProcessHeap(), 0, table->entries);
1722 HeapFree(GetProcessHeap(), 0, table->buckets);
1723 HeapFree(GetProcessHeap(), 0, table);
1726 void hash_table_for_each_entry(struct hash_table_t *table, void (*callback)(void *value, void *context), void *context)
1728 unsigned int i = 0;
1730 for (i = 0; i < table->entry_count; ++i)
1732 callback(table->entries[i].value, context);
1736 static inline struct hash_table_entry_t *hash_table_get_by_idx(const struct hash_table_t *table, const void *key,
1737 unsigned int idx)
1739 struct hash_table_entry_t *entry;
1741 if (table->buckets[idx].next)
1742 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), struct hash_table_entry_t, entry)
1743 if (table->compare_function(entry->key, key)) return entry;
1745 return NULL;
1748 static BOOL hash_table_resize(struct hash_table_t *table, unsigned int new_bucket_count)
1750 unsigned int new_entry_count = 0;
1751 struct hash_table_entry_t *new_entries;
1752 struct list *new_buckets;
1753 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
1754 unsigned int i;
1756 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
1757 if (!new_buckets)
1759 ERR("Failed to allocate new buckets, returning FALSE.\n");
1760 return FALSE;
1763 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(struct hash_table_entry_t));
1764 if (!new_entries)
1766 ERR("Failed to allocate new entries, returning FALSE.\n");
1767 HeapFree(GetProcessHeap(), 0, new_buckets);
1768 return FALSE;
1771 for (i = 0; i < table->bucket_count; ++i)
1773 if (table->buckets[i].next)
1775 struct hash_table_entry_t *entry, *entry2;
1777 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], struct hash_table_entry_t, entry)
1779 int j;
1780 struct hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
1781 *new_entry = *entry;
1783 j = new_entry->hash & (new_bucket_count - 1);
1785 if (!new_buckets[j].next) list_init(&new_buckets[j]);
1786 list_add_head(&new_buckets[j], &new_entry->entry);
1791 HeapFree(GetProcessHeap(), 0, table->buckets);
1792 table->buckets = new_buckets;
1794 HeapFree(GetProcessHeap(), 0, table->entries);
1795 table->entries = new_entries;
1797 table->entry_count = new_entry_count;
1798 list_init(&table->free_entries);
1800 table->bucket_count = new_bucket_count;
1801 table->grow_size = grow_size;
1802 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
1804 return TRUE;
1807 void hash_table_put(struct hash_table_t *table, void *key, void *value)
1809 unsigned int idx;
1810 unsigned int hash;
1811 struct hash_table_entry_t *entry;
1813 hash = table->hash_function(key);
1814 idx = hash & (table->bucket_count - 1);
1815 entry = hash_table_get_by_idx(table, key, idx);
1817 if (entry)
1819 HeapFree(GetProcessHeap(), 0, key);
1820 entry->value = value;
1822 if (!value)
1824 HeapFree(GetProcessHeap(), 0, entry->key);
1825 entry->key = NULL;
1827 /* Remove the entry */
1828 list_remove(&entry->entry);
1829 list_add_head(&table->free_entries, &entry->entry);
1831 --table->count;
1833 /* Shrink if necessary */
1834 if (table->count < table->shrink_size) {
1835 if (!hash_table_resize(table, table->bucket_count >> 1))
1837 ERR("Failed to shrink the table...\n");
1842 return;
1845 if (!value) return;
1847 /* Grow if necessary */
1848 if (table->count >= table->grow_size)
1850 if (!hash_table_resize(table, table->bucket_count << 1))
1852 ERR("Failed to grow the table, returning.\n");
1853 return;
1856 idx = hash & (table->bucket_count - 1);
1859 /* Find an entry to insert */
1860 if (!list_empty(&table->free_entries))
1862 struct list *elem = list_head(&table->free_entries);
1864 list_remove(elem);
1865 entry = LIST_ENTRY(elem, struct hash_table_entry_t, entry);
1866 } else {
1867 entry = table->entries + (table->entry_count++);
1870 /* Insert the entry */
1871 entry->key = key;
1872 entry->value = value;
1873 entry->hash = hash;
1874 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
1875 list_add_head(&table->buckets[idx], &entry->entry);
1877 ++table->count;
1880 void hash_table_remove(struct hash_table_t *table, void *key)
1882 hash_table_put(table, key, NULL);
1885 void *hash_table_get(const struct hash_table_t *table, const void *key)
1887 unsigned int idx;
1888 struct hash_table_entry_t *entry;
1890 idx = table->hash_function(key) & (table->bucket_count - 1);
1891 entry = hash_table_get_by_idx(table, key, idx);
1893 return entry ? entry->value : NULL;
1896 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
1897 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
1898 #define ARG1 0x01
1899 #define ARG2 0x02
1900 #define ARG0 0x04
1901 static const unsigned char args[WINED3DTOP_LERP + 1] = {
1902 /* undefined */ 0,
1903 /* D3DTOP_DISABLE */ 0,
1904 /* D3DTOP_SELECTARG1 */ ARG1,
1905 /* D3DTOP_SELECTARG2 */ ARG2,
1906 /* D3DTOP_MODULATE */ ARG1 | ARG2,
1907 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
1908 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
1909 /* D3DTOP_ADD */ ARG1 | ARG2,
1910 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
1911 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
1912 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
1913 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
1914 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
1915 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
1916 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
1917 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
1918 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
1919 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
1920 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
1921 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
1922 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
1923 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
1924 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
1925 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
1926 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
1927 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
1928 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
1930 unsigned int i;
1931 DWORD ttff;
1932 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
1934 for(i = 0; i < GL_LIMITS(texture_stages); i++) {
1935 IWineD3DBaseTextureImpl *texture;
1936 settings->op[i].padding = 0;
1937 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
1938 settings->op[i].cop = WINED3DTOP_DISABLE;
1939 settings->op[i].aop = WINED3DTOP_DISABLE;
1940 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
1941 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
1942 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
1943 settings->op[i].dst = resultreg;
1944 settings->op[i].tex_type = tex_1d;
1945 settings->op[i].projected = proj_none;
1946 i++;
1947 break;
1950 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
1951 if(texture) {
1952 settings->op[i].color_fixup = texture->baseTexture.shader_color_fixup;
1953 if(ignore_textype) {
1954 settings->op[i].tex_type = tex_1d;
1955 } else {
1956 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
1957 case GL_TEXTURE_1D:
1958 settings->op[i].tex_type = tex_1d;
1959 break;
1960 case GL_TEXTURE_2D:
1961 settings->op[i].tex_type = tex_2d;
1962 break;
1963 case GL_TEXTURE_3D:
1964 settings->op[i].tex_type = tex_3d;
1965 break;
1966 case GL_TEXTURE_CUBE_MAP_ARB:
1967 settings->op[i].tex_type = tex_cube;
1968 break;
1969 case GL_TEXTURE_RECTANGLE_ARB:
1970 settings->op[i].tex_type = tex_rect;
1971 break;
1974 } else {
1975 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
1976 settings->op[i].tex_type = tex_1d;
1979 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
1980 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
1982 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
1983 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
1984 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
1986 if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
1987 carg1, carg2, carg0)) {
1988 carg0 = ARG_UNUSED;
1989 carg2 = ARG_UNUSED;
1990 carg1 = WINED3DTA_CURRENT;
1991 cop = WINED3DTOP_SELECTARG1;
1994 if(cop == WINED3DTOP_DOTPRODUCT3) {
1995 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
1996 * the color result to the alpha component of the destination
1998 aop = cop;
1999 aarg1 = carg1;
2000 aarg2 = carg2;
2001 aarg0 = carg0;
2002 } else {
2003 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2004 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2005 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2008 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2010 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2012 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2014 IWineD3DSurfaceImpl *surf;
2015 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2017 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT
2018 && getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000)
2020 if (aop == WINED3DTOP_DISABLE)
2022 aarg1 = WINED3DTA_TEXTURE;
2023 aop = WINED3DTOP_SELECTARG1;
2025 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2027 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2029 aarg2 = WINED3DTA_TEXTURE;
2030 aop = WINED3DTOP_MODULATE;
2032 else aarg1 = WINED3DTA_TEXTURE;
2034 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2036 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2038 aarg1 = WINED3DTA_TEXTURE;
2039 aop = WINED3DTOP_MODULATE;
2041 else aarg2 = WINED3DTA_TEXTURE;
2047 if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
2048 aarg1, aarg2, aarg0)) {
2049 aarg0 = ARG_UNUSED;
2050 aarg2 = ARG_UNUSED;
2051 aarg1 = WINED3DTA_CURRENT;
2052 aop = WINED3DTOP_SELECTARG1;
2055 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2056 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2057 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2058 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2059 settings->op[i].projected = proj_count3;
2060 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2061 settings->op[i].projected = proj_count4;
2062 } else {
2063 settings->op[i].projected = proj_none;
2065 } else {
2066 settings->op[i].projected = proj_none;
2069 settings->op[i].cop = cop;
2070 settings->op[i].aop = aop;
2071 settings->op[i].carg0 = carg0;
2072 settings->op[i].carg1 = carg1;
2073 settings->op[i].carg2 = carg2;
2074 settings->op[i].aarg0 = aarg0;
2075 settings->op[i].aarg1 = aarg1;
2076 settings->op[i].aarg2 = aarg2;
2078 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2079 settings->op[i].dst = tempreg;
2080 } else {
2081 settings->op[i].dst = resultreg;
2085 /* Clear unsupported stages */
2086 for(; i < MAX_TEXTURES; i++) {
2087 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2090 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2091 settings->fog = FOG_OFF;
2092 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2093 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2094 case WINED3DFOG_NONE:
2095 case WINED3DFOG_LINEAR:
2096 settings->fog = FOG_LINEAR;
2097 break;
2098 case WINED3DFOG_EXP:
2099 settings->fog = FOG_EXP;
2100 break;
2101 case WINED3DFOG_EXP2:
2102 settings->fog = FOG_EXP2;
2103 break;
2105 } else {
2106 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2107 case WINED3DFOG_LINEAR:
2108 settings->fog = FOG_LINEAR;
2109 break;
2110 case WINED3DFOG_EXP:
2111 settings->fog = FOG_EXP;
2112 break;
2113 case WINED3DFOG_EXP2:
2114 settings->fog = FOG_EXP2;
2115 break;
2118 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2119 settings->sRGB_write = 1;
2120 } else {
2121 settings->sRGB_write = 0;
2124 #undef GLINFO_LOCATION
2126 const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
2127 const struct ffp_frag_settings *settings)
2129 return (const struct ffp_frag_desc *)hash_table_get(fragment_shaders, settings);
2132 void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *desc) {
2133 struct ffp_frag_settings *key = HeapAlloc(GetProcessHeap(), 0, sizeof(*key));
2134 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2135 * whereas desc points to an extended structure with implementation specific parts.
2136 * Make a copy of the key because hash_table_put takes ownership of it
2138 *key = desc->settings;
2139 hash_table_put(shaders, key, desc);
2142 /* Activates the texture dimension according to the bound D3D texture.
2143 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2144 * Requires the caller to activate the correct unit before
2146 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2147 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2148 if(stateblock->textures[stage]) {
2149 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2150 case GL_TEXTURE_2D:
2151 glDisable(GL_TEXTURE_3D);
2152 checkGLcall("glDisable(GL_TEXTURE_3D)");
2153 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2154 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2155 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2157 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2158 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2159 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2161 glEnable(GL_TEXTURE_2D);
2162 checkGLcall("glEnable(GL_TEXTURE_2D)");
2163 break;
2164 case GL_TEXTURE_RECTANGLE_ARB:
2165 glDisable(GL_TEXTURE_2D);
2166 checkGLcall("glDisable(GL_TEXTURE_2D)");
2167 glDisable(GL_TEXTURE_3D);
2168 checkGLcall("glDisable(GL_TEXTURE_3D)");
2169 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2170 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2171 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2173 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2174 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2175 break;
2176 case GL_TEXTURE_3D:
2177 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2178 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2179 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2181 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2182 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2183 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2185 glDisable(GL_TEXTURE_2D);
2186 checkGLcall("glDisable(GL_TEXTURE_2D)");
2187 glEnable(GL_TEXTURE_3D);
2188 checkGLcall("glEnable(GL_TEXTURE_3D)");
2189 break;
2190 case GL_TEXTURE_CUBE_MAP_ARB:
2191 glDisable(GL_TEXTURE_2D);
2192 checkGLcall("glDisable(GL_TEXTURE_2D)");
2193 glDisable(GL_TEXTURE_3D);
2194 checkGLcall("glDisable(GL_TEXTURE_3D)");
2195 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2196 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2197 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2199 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2200 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2201 break;
2203 } else {
2204 glEnable(GL_TEXTURE_2D);
2205 checkGLcall("glEnable(GL_TEXTURE_2D)");
2206 glDisable(GL_TEXTURE_3D);
2207 checkGLcall("glDisable(GL_TEXTURE_3D)");
2208 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2209 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2210 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2212 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2213 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2214 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2216 /* Binding textures is done by samplers. A dummy texture will be bound */
2220 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2221 DWORD sampler = state - STATE_SAMPLER(0);
2222 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2224 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2225 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2226 * will take care of this business
2228 if(mapped_stage == -1 || mapped_stage >= GL_LIMITS(textures)) return;
2229 if(sampler >= stateblock->lowest_disabled_stage) return;
2230 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2232 texture_activate_dimensions(sampler, stateblock, context);
2234 #undef GLINFO_LOCATION
2236 unsigned int ffp_frag_program_key_hash(const void *key)
2238 const struct ffp_frag_settings *k = (const struct ffp_frag_settings *)key;
2239 unsigned int hash = 0, i;
2240 const DWORD *blob;
2242 /* This takes the texture op settings of stage 0 and 1 into account.
2243 * how exactly depends on the memory laybout of the compiler, but it
2244 * should not matter too much. Stages > 1 are used rarely, so there's
2245 * no need to process them. Even if they're used it is likely that
2246 * the ffp setup has distinct stage 0 and 1 settings.
2248 for(i = 0; i < 2; i++) {
2249 blob = (const DWORD *)&k->op[i];
2250 hash ^= blob[0] ^ blob[1];
2253 hash += ~(hash << 15);
2254 hash ^= (hash >> 10);
2255 hash += (hash << 3);
2256 hash ^= (hash >> 6);
2257 hash += ~(hash << 11);
2258 hash ^= (hash >> 16);
2260 return hash;
2263 BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb)
2265 const struct ffp_frag_settings *ka = (const struct ffp_frag_settings *)keya;
2266 const struct ffp_frag_settings *kb = (const struct ffp_frag_settings *)keyb;
2268 return memcmp(ka, kb, sizeof(*ka)) == 0;
2271 UINT wined3d_log2i(UINT32 x)
2273 static const BYTE l[] =
2275 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2276 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2277 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2278 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2279 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2280 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2281 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2282 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2283 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2284 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2285 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2286 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2287 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2288 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2289 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2290 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2292 UINT32 i;
2294 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];