- update wined3d/d3d8/d3d9 to Wine 1.1.15
[reactos.git] / reactos / dll / directx / wine / wined3d / utils.c
1 /*
2 * Utility functions for the WineD3D Library
3 *
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006-2008 Henri Verbeet
9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
10 *
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.
15 *
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.
20 *
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
24 */
25
26 #include "config.h"
27 #include "wined3d_private.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
30
31 /*****************************************************************************
32 * Pixel format array
33 *
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.
40 */
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 },
119 };
120
121 typedef struct {
122 WINED3DFORMAT fmt;
123 GLint glInternal, glGammaInternal, rtInternal, glFormat, glType;
124 unsigned int Flags;
125 } GlPixelFormatDescTemplate;
126
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.
132 */
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
144 */
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 }
283 };
284
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
288 */
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;
296 }
297 }
298 }
299 return -1;
300 }
301
302 #define GLINFO_LOCATION (*gl_info)
303 BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
304 {
305 unsigned int src;
306 int dst;
307
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;
311
312 /* If a format depends on some extensions, remove them from the table above and initialize them
313 * after this loop
314 */
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;
324
325 if(wined3d_settings.offscreen_rendering_mode == ORM_FBO &&
326 gl_formats_template[src].rtInternal != 0) {
327 GLuint tex, fb;
328 GLenum status;
329
330 /* Check if the default internal format is supported as a frame buffer target, otherwise
331 * fall back to the render target internal.
332 *
333 * Try to stick to the standard format if possible, this limits precision differences
334 */
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);
340
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));
345
346 status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
347 GL_EXTCALL(glDeleteFramebuffersEXT(1, &fb));
348 glDeleteTextures(1, &tex);
349
350 checkGLcall("Framebuffer format check");
351
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;
359 }
360
361 } else {
362 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].glInternal;
363 }
364 }
365
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))
371 {
372 gl_info->gl_formats[dst].glInternal = GL_R16F;
373 gl_info->gl_formats[dst].glGammaInternal = GL_R16F;
374 }
375
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))
381 {
382 gl_info->gl_formats[dst].glInternal = GL_R32F;
383 gl_info->gl_formats[dst].glGammaInternal = GL_R32F;
384 }
385
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);
389
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);
393
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);
397
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.
402 *
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.
406 */
407 if (!GL_SUPPORT(NV_TEXTURE_SHADER))
408 {
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);
415 }
416 else
417 {
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);
424 }
425
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
429 */
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
444 */
445 }
446
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);
459 }
460
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);
468
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);
475 }
476
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);
480
481 return TRUE;
482 }
483
484 /* NOTE: Make sure these are in the correct numerical order. (see /include/wined3d_types.h) */
485 static WINED3DGLTYPE const glTypeLookupTemplate[WINED3DDECLTYPE_UNUSED] =
486 {
487 {WINED3DDECLTYPE_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
488 {WINED3DDECLTYPE_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
489 {WINED3DDECLTYPE_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
490 {WINED3DDECLTYPE_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
491 {WINED3DDECLTYPE_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
492 {WINED3DDECLTYPE_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
493 {WINED3DDECLTYPE_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
494 {WINED3DDECLTYPE_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
495 {WINED3DDECLTYPE_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
496 {WINED3DDECLTYPE_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
497 {WINED3DDECLTYPE_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
498 {WINED3DDECLTYPE_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
499 {WINED3DDECLTYPE_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
500 {WINED3DDECLTYPE_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
501 {WINED3DDECLTYPE_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
502 {WINED3DDECLTYPE_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
503 {WINED3DDECLTYPE_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
504 };
505
506 void init_type_lookup(WineD3D_GL_Info *gl_info) {
507 memcpy(gl_info->glTypeLookup, glTypeLookupTemplate, sizeof(glTypeLookupTemplate));
508
509 if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
510 {
511 gl_info->glTypeLookup[WINED3DDECLTYPE_D3DCOLOR].format = GL_BGRA;
512 }
513
514 if (GL_SUPPORT(NV_HALF_FLOAT))
515 {
516 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
517 * It is the job of the vertex buffer code to make sure that the vbos have the right format
518 */
519 gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_2].glType = GL_HALF_FLOAT_NV;
520 gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_4].glType = GL_HALF_FLOAT_NV;
521 }
522 }
523
524 #undef GLINFO_LOCATION
525
526 #define GLINFO_LOCATION This->adapter->gl_info
527
528 const StaticPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const WineD3D_GL_Info *gl_info,
529 const struct GlPixelFormatDesc **glDesc)
530 {
531 int idx = getFmtIdx(fmt);
532
533 if(idx == -1) {
534 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
535 /* Get the caller a valid pointer */
536 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
537 }
538 if(glDesc) {
539 if(!gl_info->gl_formats) {
540 /* If we do not have gl format information, provide a dummy NULL format. This is an easy way to make
541 * all gl caps check return "unsupported" than catching the lack of gl all over the code. ANSI C requires
542 * static variables to be initialized to 0.
543 */
544 static const struct GlPixelFormatDesc dummyFmt;
545 *glDesc = &dummyFmt;
546 } else {
547 *glDesc = &gl_info->gl_formats[idx];
548 }
549 }
550 return &formats[idx];
551 }
552
553 /*****************************************************************************
554 * Trace formatting of useful values
555 */
556 const char* debug_d3dformat(WINED3DFORMAT fmt) {
557 switch (fmt) {
558 #define FMT_TO_STR(fmt) case fmt: return #fmt
559 FMT_TO_STR(WINED3DFMT_UNKNOWN);
560 FMT_TO_STR(WINED3DFMT_R8G8B8);
561 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
562 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
563 FMT_TO_STR(WINED3DFMT_R5G6B5);
564 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
565 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
566 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
567 FMT_TO_STR(WINED3DFMT_R3G3B2);
568 FMT_TO_STR(WINED3DFMT_A8);
569 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
570 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
571 FMT_TO_STR(WINED3DFMT_A2B10G10R10);
572 FMT_TO_STR(WINED3DFMT_A8B8G8R8);
573 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
574 FMT_TO_STR(WINED3DFMT_G16R16);
575 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
576 FMT_TO_STR(WINED3DFMT_A16B16G16R16);
577 FMT_TO_STR(WINED3DFMT_A8P8);
578 FMT_TO_STR(WINED3DFMT_P8);
579 FMT_TO_STR(WINED3DFMT_L8);
580 FMT_TO_STR(WINED3DFMT_A8L8);
581 FMT_TO_STR(WINED3DFMT_A4L4);
582 FMT_TO_STR(WINED3DFMT_V8U8);
583 FMT_TO_STR(WINED3DFMT_L6V5U5);
584 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
585 FMT_TO_STR(WINED3DFMT_Q8W8V8U8);
586 FMT_TO_STR(WINED3DFMT_V16U16);
587 FMT_TO_STR(WINED3DFMT_W11V11U10);
588 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
589 FMT_TO_STR(WINED3DFMT_UYVY);
590 FMT_TO_STR(WINED3DFMT_YUY2);
591 FMT_TO_STR(WINED3DFMT_YV12);
592 FMT_TO_STR(WINED3DFMT_DXT1);
593 FMT_TO_STR(WINED3DFMT_DXT2);
594 FMT_TO_STR(WINED3DFMT_DXT3);
595 FMT_TO_STR(WINED3DFMT_DXT4);
596 FMT_TO_STR(WINED3DFMT_DXT5);
597 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
598 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
599 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
600 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
601 FMT_TO_STR(WINED3DFMT_D32);
602 FMT_TO_STR(WINED3DFMT_D15S1);
603 FMT_TO_STR(WINED3DFMT_D24S8);
604 FMT_TO_STR(WINED3DFMT_D24X8);
605 FMT_TO_STR(WINED3DFMT_D24X4S4);
606 FMT_TO_STR(WINED3DFMT_D16);
607 FMT_TO_STR(WINED3DFMT_L16);
608 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
609 FMT_TO_STR(WINED3DFMT_D24FS8);
610 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
611 FMT_TO_STR(WINED3DFMT_INDEX16);
612 FMT_TO_STR(WINED3DFMT_INDEX32);
613 FMT_TO_STR(WINED3DFMT_Q16W16V16U16);
614 FMT_TO_STR(WINED3DFMT_R16F);
615 FMT_TO_STR(WINED3DFMT_G16R16F);
616 FMT_TO_STR(WINED3DFMT_A16B16G16R16F);
617 FMT_TO_STR(WINED3DFMT_R32F);
618 FMT_TO_STR(WINED3DFMT_G32R32F);
619 FMT_TO_STR(WINED3DFMT_A32B32G32R32F);
620 FMT_TO_STR(WINED3DFMT_CxV8U8);
621 FMT_TO_STR(WINED3DFMT_ATI2N);
622 FMT_TO_STR(WINED3DFMT_NVHU);
623 FMT_TO_STR(WINED3DFMT_NVHS);
624 #undef FMT_TO_STR
625 default:
626 {
627 char fourcc[5];
628 fourcc[0] = (char)(fmt);
629 fourcc[1] = (char)(fmt >> 8);
630 fourcc[2] = (char)(fmt >> 16);
631 fourcc[3] = (char)(fmt >> 24);
632 fourcc[4] = 0;
633 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
634 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
635 else
636 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
637 }
638 return "unrecognized";
639 }
640 }
641
642 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
643 switch (devtype) {
644 #define DEVTYPE_TO_STR(dev) case dev: return #dev
645 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
646 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
647 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
648 #undef DEVTYPE_TO_STR
649 default:
650 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
651 return "unrecognized";
652 }
653 }
654
655 const char* debug_d3dusage(DWORD usage) {
656 switch (usage & WINED3DUSAGE_MASK) {
657 #define WINED3DUSAGE_TO_STR(u) case u: return #u
658 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
659 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
660 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
661 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
662 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
663 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
664 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
665 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
666 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
667 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
668 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
669 #undef WINED3DUSAGE_TO_STR
670 case 0: return "none";
671 default:
672 FIXME("Unrecognized %u Usage!\n", usage);
673 return "unrecognized";
674 }
675 }
676
677 const char* debug_d3dusagequery(DWORD usagequery) {
678 switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
679 #define WINED3DUSAGEQUERY_TO_STR(u) case u: return #u
680 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
681 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
682 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
683 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
684 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
685 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
686 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
687 #undef WINED3DUSAGEQUERY_TO_STR
688 case 0: return "none";
689 default:
690 FIXME("Unrecognized %u Usage Query!\n", usagequery);
691 return "unrecognized";
692 }
693 }
694
695 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
696 switch (method) {
697 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
698 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
699 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
700 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
701 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
702 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
703 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
704 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
705 #undef WINED3DDECLMETHOD_TO_STR
706 default:
707 FIXME("Unrecognized %u declaration method!\n", method);
708 return "unrecognized";
709 }
710 }
711
712 const char* debug_d3ddecltype(WINED3DDECLTYPE type) {
713 switch (type) {
714 #define WINED3DDECLTYPE_TO_STR(u) case u: return #u
715 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT1);
716 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT2);
717 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT3);
718 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT4);
719 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_D3DCOLOR);
720 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4);
721 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2);
722 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4);
723 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4N);
724 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2N);
725 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4N);
726 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT2N);
727 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT4N);
728 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UDEC3);
729 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_DEC3N);
730 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_2);
731 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_4);
732 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UNUSED);
733 #undef WINED3DDECLTYPE_TO_STR
734 default:
735 FIXME("Unrecognized %u declaration type!\n", type);
736 return "unrecognized";
737 }
738 }
739
740 const char* debug_d3ddeclusage(BYTE usage) {
741 switch (usage) {
742 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
743 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
744 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
745 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
746 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
747 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
748 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
749 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
750 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
751 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
752 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
753 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
754 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
755 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
756 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
757 #undef WINED3DDECLUSAGE_TO_STR
758 default:
759 FIXME("Unrecognized %u declaration usage!\n", usage);
760 return "unrecognized";
761 }
762 }
763
764 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
765 switch (res) {
766 #define RES_TO_STR(res) case res: return #res
767 RES_TO_STR(WINED3DRTYPE_SURFACE);
768 RES_TO_STR(WINED3DRTYPE_VOLUME);
769 RES_TO_STR(WINED3DRTYPE_TEXTURE);
770 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
771 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
772 RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER);
773 RES_TO_STR(WINED3DRTYPE_INDEXBUFFER);
774 #undef RES_TO_STR
775 default:
776 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
777 return "unrecognized";
778 }
779 }
780
781 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
782 switch (PrimitiveType) {
783 #define PRIM_TO_STR(prim) case prim: return #prim
784 PRIM_TO_STR(WINED3DPT_POINTLIST);
785 PRIM_TO_STR(WINED3DPT_LINELIST);
786 PRIM_TO_STR(WINED3DPT_LINESTRIP);
787 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
788 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
789 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
790 #undef PRIM_TO_STR
791 default:
792 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
793 return "unrecognized";
794 }
795 }
796
797 const char* debug_d3drenderstate(DWORD state) {
798 switch (state) {
799 #define D3DSTATE_TO_STR(u) case u: return #u
800 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
801 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
802 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
803 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
804 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
805 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
806 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
807 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
808 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
809 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
810 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
811 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
812 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
813 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
814 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
815 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
816 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
817 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
818 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
819 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
820 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
821 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
822 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
823 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
824 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
825 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
826 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
827 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
828 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
829 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
830 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
831 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
832 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
833 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
834 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
835 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
836 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
837 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
838 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
839 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
840 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
841 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
842 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
843 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
844 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
845 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
846 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
847 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
848 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
849 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
850 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
851 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
852 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
853 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
854 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
855 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
856 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
857 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
858 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
859 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
860 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
861 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
862 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
863 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
864 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
865 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
866 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
867 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
868 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
869 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
870 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
871 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
872 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
873 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
874 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
875 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
876 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
877 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
878 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
879 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
880 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
881 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
882 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
883 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
884 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
885 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
886 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
887 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
888 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
889 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
890 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
891 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
892 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
893 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
894 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
895 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
896 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
897 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
898 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
899 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
900 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
901 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
902 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
903 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
904 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
905 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
906 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
907 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
908 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
909 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
910 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
911 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
912 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
913 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
914 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
915 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
916 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
917 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
918 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
919 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
920 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
921 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
922 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
923 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
924 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
925 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
926 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
927 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
928 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
929 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
930 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
931 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
932 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
933 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
934 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
935 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
936 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
937 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
938 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
939 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
940 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
941 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
942 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
943 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
944 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
945 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
946 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
947 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
948 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
949 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
950 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
951 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
952 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
953 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
954 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
955 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
956 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
957 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
958 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
959 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
960 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
961 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
962 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
963 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
964 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
965 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
966 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
967 #undef D3DSTATE_TO_STR
968 default:
969 FIXME("Unrecognized %u render state!\n", state);
970 return "unrecognized";
971 }
972 }
973
974 const char* debug_d3dsamplerstate(DWORD state) {
975 switch (state) {
976 #define D3DSTATE_TO_STR(u) case u: return #u
977 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
978 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
979 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
980 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
981 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
982 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
983 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
984 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
985 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
986 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
987 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
988 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
989 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
990 #undef D3DSTATE_TO_STR
991 default:
992 FIXME("Unrecognized %u sampler state!\n", state);
993 return "unrecognized";
994 }
995 }
996
997 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
998 switch (filter_type) {
999 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
1000 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
1001 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
1002 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
1003 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
1004 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
1005 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
1006 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
1007 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
1008 #undef D3DTEXTUREFILTERTYPE_TO_STR
1009 default:
1010 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
1011 return "unrecognized";
1012 }
1013 }
1014
1015 const char* debug_d3dtexturestate(DWORD state) {
1016 switch (state) {
1017 #define D3DSTATE_TO_STR(u) case u: return #u
1018 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
1019 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
1020 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
1021 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
1022 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
1023 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
1024 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
1025 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
1026 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
1027 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
1028 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
1029 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
1030 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
1031 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
1032 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
1033 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
1034 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
1035 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
1036 #undef D3DSTATE_TO_STR
1037 default:
1038 FIXME("Unrecognized %u texture state!\n", state);
1039 return "unrecognized";
1040 }
1041 }
1042
1043 const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
1044 switch (d3dtop) {
1045 #define D3DTOP_TO_STR(u) case u: return #u
1046 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
1047 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
1048 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
1049 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
1050 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
1051 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
1052 D3DTOP_TO_STR(WINED3DTOP_ADD);
1053 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
1054 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
1055 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
1056 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
1057 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
1058 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
1059 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
1060 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
1061 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
1062 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
1063 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
1064 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
1065 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
1066 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
1067 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
1068 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
1069 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
1070 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
1071 D3DTOP_TO_STR(WINED3DTOP_LERP);
1072 #undef D3DTOP_TO_STR
1073 default:
1074 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
1075 return "unrecognized";
1076 }
1077 }
1078
1079 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
1080 switch (tstype) {
1081 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
1082 TSTYPE_TO_STR(WINED3DTS_VIEW);
1083 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
1084 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
1085 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
1086 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
1087 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
1088 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
1089 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
1090 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
1091 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
1092 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
1093 #undef TSTYPE_TO_STR
1094 default:
1095 if (tstype > 256 && tstype < 512) {
1096 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
1097 return ("WINED3DTS_WORLDMATRIX > 0");
1098 }
1099 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1100 return "unrecognized";
1101 }
1102 }
1103
1104 const char* debug_d3dpool(WINED3DPOOL Pool) {
1105 switch (Pool) {
1106 #define POOL_TO_STR(p) case p: return #p
1107 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1108 POOL_TO_STR(WINED3DPOOL_MANAGED);
1109 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1110 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1111 #undef POOL_TO_STR
1112 default:
1113 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1114 return "unrecognized";
1115 }
1116 }
1117
1118 const char *debug_fbostatus(GLenum status) {
1119 switch(status) {
1120 #define FBOSTATUS_TO_STR(u) case u: return #u
1121 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1122 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1123 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1124 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1125 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1126 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1127 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1128 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
1129 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1130 #undef FBOSTATUS_TO_STR
1131 default:
1132 FIXME("Unrecognied FBO status 0x%08x\n", status);
1133 return "unrecognized";
1134 }
1135 }
1136
1137 const char *debug_glerror(GLenum error) {
1138 switch(error) {
1139 #define GLERROR_TO_STR(u) case u: return #u
1140 GLERROR_TO_STR(GL_NO_ERROR);
1141 GLERROR_TO_STR(GL_INVALID_ENUM);
1142 GLERROR_TO_STR(GL_INVALID_VALUE);
1143 GLERROR_TO_STR(GL_INVALID_OPERATION);
1144 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1145 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1146 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1147 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1148 #undef GLERROR_TO_STR
1149 default:
1150 FIXME("Unrecognied GL error 0x%08x\n", error);
1151 return "unrecognized";
1152 }
1153 }
1154
1155 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1156 switch(basis) {
1157 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1158 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1159 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1160 default: return "unrecognized";
1161 }
1162 }
1163
1164 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1165 switch(degree) {
1166 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1167 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1168 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1169 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1170 default: return "unrecognized";
1171 }
1172 }
1173
1174 const char *debug_fixup_channel_source(enum fixup_channel_source source)
1175 {
1176 switch(source)
1177 {
1178 #define WINED3D_TO_STR(x) case x: return #x
1179 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
1180 WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
1181 WINED3D_TO_STR(CHANNEL_SOURCE_X);
1182 WINED3D_TO_STR(CHANNEL_SOURCE_Y);
1183 WINED3D_TO_STR(CHANNEL_SOURCE_Z);
1184 WINED3D_TO_STR(CHANNEL_SOURCE_W);
1185 WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
1186 WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
1187 #undef WINED3D_TO_STR
1188 default:
1189 FIXME("Unrecognized fixup_channel_source %#x\n", source);
1190 return "unrecognized";
1191 }
1192 }
1193
1194 const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
1195 {
1196 switch(yuv_fixup)
1197 {
1198 #define WINED3D_TO_STR(x) case x: return #x
1199 WINED3D_TO_STR(YUV_FIXUP_YUY2);
1200 WINED3D_TO_STR(YUV_FIXUP_UYVY);
1201 WINED3D_TO_STR(YUV_FIXUP_YV12);
1202 #undef WINED3D_TO_STR
1203 default:
1204 FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
1205 return "unrecognized";
1206 }
1207 }
1208
1209 void dump_color_fixup_desc(struct color_fixup_desc fixup)
1210 {
1211 if (is_yuv_fixup(fixup))
1212 {
1213 TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
1214 return;
1215 }
1216
1217 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
1218 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
1219 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
1220 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
1221 }
1222
1223 /*****************************************************************************
1224 * Useful functions mapping GL <-> D3D values
1225 */
1226 GLenum StencilOp(DWORD op) {
1227 switch(op) {
1228 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1229 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1230 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1231 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1232 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1233 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1234 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1235 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1236 default:
1237 FIXME("Unrecognized stencil op %d\n", op);
1238 return GL_KEEP;
1239 }
1240 }
1241
1242 GLenum CompareFunc(DWORD func) {
1243 switch ((WINED3DCMPFUNC)func) {
1244 case WINED3DCMP_NEVER : return GL_NEVER;
1245 case WINED3DCMP_LESS : return GL_LESS;
1246 case WINED3DCMP_EQUAL : return GL_EQUAL;
1247 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1248 case WINED3DCMP_GREATER : return GL_GREATER;
1249 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1250 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1251 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1252 default:
1253 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1254 return 0;
1255 }
1256 }
1257
1258 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1259 if (op == WINED3DTOP_DISABLE) return FALSE;
1260 if (This->stateBlock->textures[stage]) return FALSE;
1261
1262 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1263 && op != WINED3DTOP_SELECTARG2) return TRUE;
1264 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1265 && op != WINED3DTOP_SELECTARG1) return TRUE;
1266 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1267 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1268
1269 return FALSE;
1270 }
1271
1272 /* Setup this textures matrix according to the texture flags*/
1273 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype,
1274 BOOL ffp_proj_control)
1275 {
1276 float mat[16];
1277
1278 glMatrixMode(GL_TEXTURE);
1279 checkGLcall("glMatrixMode(GL_TEXTURE)");
1280
1281 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
1282 glLoadIdentity();
1283 checkGLcall("glLoadIdentity()");
1284 return;
1285 }
1286
1287 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
1288 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
1289 return;
1290 }
1291
1292 memcpy(mat, smat, 16 * sizeof(float));
1293
1294 if (flags & WINED3DTTFF_PROJECTED) {
1295 if(!ffp_proj_control) {
1296 switch (flags & ~WINED3DTTFF_PROJECTED) {
1297 case WINED3DTTFF_COUNT2:
1298 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
1299 mat[1] = mat[5] = mat[9] = mat[13] = 0;
1300 break;
1301 case WINED3DTTFF_COUNT3:
1302 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
1303 mat[2] = mat[6] = mat[10] = mat[14] = 0;
1304 break;
1305 }
1306 }
1307 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
1308 if(!calculatedCoords) {
1309 switch(coordtype) {
1310 case WINED3DDECLTYPE_FLOAT1:
1311 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
1312 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
1313 * the input value to the transformation will be 0, so the matrix value is irrelevant
1314 */
1315 mat[12] = mat[4];
1316 mat[13] = mat[5];
1317 mat[14] = mat[6];
1318 mat[15] = mat[7];
1319 break;
1320 case WINED3DDECLTYPE_FLOAT2:
1321 /* See above, just 3rd and 4th coord
1322 */
1323 mat[12] = mat[8];
1324 mat[13] = mat[9];
1325 mat[14] = mat[10];
1326 mat[15] = mat[11];
1327 break;
1328 case WINED3DDECLTYPE_FLOAT3: /* Opengl defaults match dx defaults */
1329 case WINED3DDECLTYPE_FLOAT4: /* No defaults apply, all app defined */
1330
1331 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
1332 * into a bad place. The division elimination below will apply to make sure the
1333 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
1334 */
1335 case WINED3DDECLTYPE_UNUSED: /* No texture coords, 0/0/0/1 defaults are passed */
1336 break;
1337 default:
1338 FIXME("Unexpected fixed function texture coord input\n");
1339 }
1340 }
1341 if(!ffp_proj_control) {
1342 switch (flags & ~WINED3DTTFF_PROJECTED) {
1343 /* case WINED3DTTFF_COUNT1: Won't ever get here */
1344 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
1345 /* OpenGL divides the first 3 vertex coord by the 4th by default,
1346 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
1347 * the 4th coord evaluates to 1.0 to eliminate that.
1348 *
1349 * If the fixed function pipeline is used, the 4th value remains unused,
1350 * so there is no danger in doing this. With vertex shaders we have a
1351 * problem. Should an app hit that problem, the code here would have to
1352 * check for pixel shaders, and the shader has to undo the default gl divide.
1353 *
1354 * A more serious problem occurs if the app passes 4 coordinates in, and the
1355 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
1356 * or a replacement shader
1357 */
1358 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
1359 }
1360 }
1361 }
1362
1363 glLoadMatrixf(mat);
1364 checkGLcall("glLoadMatrixf(mat)");
1365 }
1366 #undef GLINFO_LOCATION
1367
1368 /* This small helper function is used to convert a bitmask into the number of masked bits */
1369 unsigned int count_bits(unsigned int mask)
1370 {
1371 unsigned int count;
1372 for (count = 0; mask; ++count)
1373 {
1374 mask &= mask - 1;
1375 }
1376 return count;
1377 }
1378
1379 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
1380 * The later function requires individual color components. */
1381 BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
1382 {
1383 const StaticPixelFormatDesc *desc;
1384
1385 TRACE("fmt: %s\n", debug_d3dformat(fmt));
1386 switch(fmt)
1387 {
1388 case WINED3DFMT_X8R8G8B8:
1389 case WINED3DFMT_R8G8B8:
1390 case WINED3DFMT_A8R8G8B8:
1391 case WINED3DFMT_A2R10G10B10:
1392 case WINED3DFMT_X1R5G5B5:
1393 case WINED3DFMT_A1R5G5B5:
1394 case WINED3DFMT_R5G6B5:
1395 case WINED3DFMT_X4R4G4B4:
1396 case WINED3DFMT_A4R4G4B4:
1397 case WINED3DFMT_R3G3B2:
1398 case WINED3DFMT_A8P8:
1399 case WINED3DFMT_P8:
1400 break;
1401 default:
1402 ERR("Unsupported format: %s\n", debug_d3dformat(fmt));
1403 return FALSE;
1404 }
1405
1406 desc = getFormatDescEntry(fmt, NULL, NULL);
1407 if(!desc)
1408 {
1409 ERR("Unable to look up format: 0x%x\n", fmt);
1410 return FALSE;
1411 }
1412 *redSize = count_bits(desc->redMask);
1413 *greenSize = count_bits(desc->greenMask);
1414 *blueSize = count_bits(desc->blueMask);
1415 *alphaSize = count_bits(desc->alphaMask);
1416 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
1417
1418 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n", *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(fmt));
1419 return TRUE;
1420 }
1421
1422 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
1423 BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize)
1424 {
1425 const StaticPixelFormatDesc *desc;
1426
1427 TRACE("fmt: %s\n", debug_d3dformat(fmt));
1428 switch(fmt)
1429 {
1430 case WINED3DFMT_D16_LOCKABLE:
1431 case WINED3DFMT_D16:
1432 case WINED3DFMT_D15S1:
1433 case WINED3DFMT_D24X8:
1434 case WINED3DFMT_D24X4S4:
1435 case WINED3DFMT_D24S8:
1436 case WINED3DFMT_D24FS8:
1437 case WINED3DFMT_D32:
1438 case WINED3DFMT_D32F_LOCKABLE:
1439 break;
1440 default:
1441 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(fmt));
1442 return FALSE;
1443 }
1444
1445 desc = getFormatDescEntry(fmt, NULL, NULL);
1446 if(!desc)
1447 {
1448 ERR("Unable to look up format: 0x%x\n", fmt);
1449 return FALSE;
1450 }
1451 *depthSize = desc->depthSize;
1452 *stencilSize = desc->stencilSize;
1453
1454 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n", *depthSize, *stencilSize, debug_d3dformat(fmt));
1455 return TRUE;
1456 }
1457
1458 /* DirectDraw stuff */
1459 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
1460 switch(depth) {
1461 case 8: return WINED3DFMT_P8;
1462 case 15: return WINED3DFMT_X1R5G5B5;
1463 case 16: return WINED3DFMT_R5G6B5;
1464 case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
1465 case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
1466 default: return WINED3DFMT_UNKNOWN;
1467 }
1468 }
1469
1470 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
1471 WINED3DMATRIX temp;
1472
1473 /* Now do the multiplication 'by hand'.
1474 I know that all this could be optimised, but this will be done later :-) */
1475 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);
1476 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);
1477 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);
1478 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
1480 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);
1481 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);
1482 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);
1483 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
1485 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);
1486 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);
1487 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);
1488 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
1490 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);
1491 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);
1492 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);
1493 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
1495 /* And copy the new matrix in the good storage.. */
1496 memcpy(dest, &temp, 16 * sizeof(float));
1497 }
1498
1499 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
1500 DWORD size = 0;
1501 int i;
1502 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
1503
1504 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
1505 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
1506 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
1507 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
1508 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
1509 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
1510 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
1511 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
1512 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
1513 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
1514 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
1515 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
1516 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
1517 default: ERR("Unexpected position mask\n");
1518 }
1519 for (i = 0; i < numTextures; i++) {
1520 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
1521 }
1522
1523 return size;
1524 }
1525
1526 /***********************************************************************
1527 * CalculateTexRect
1528 *
1529 * Calculates the dimensions of the opengl texture used for blits.
1530 * Handled oversized opengl textures and updates the source rectangle
1531 * accordingly
1532 *
1533 * Params:
1534 * This: Surface to operate on
1535 * Rect: Requested rectangle
1536 *
1537 * Returns:
1538 * TRUE if the texture part can be loaded,
1539 * FALSE otherwise
1540 *
1541 *********************************************************************/
1542 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
1543
1544 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
1545 int x1 = Rect->left, x2 = Rect->right;
1546 int y1 = Rect->top, y2 = Rect->bottom;
1547 GLint maxSize = GL_LIMITS(texture_size);
1548
1549 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
1550 Rect->left, Rect->top, Rect->right, Rect->bottom);
1551
1552 /* The sizes might be reversed */
1553 if(Rect->left > Rect->right) {
1554 x1 = Rect->right;
1555 x2 = Rect->left;
1556 }
1557 if(Rect->top > Rect->bottom) {
1558 y1 = Rect->bottom;
1559 y2 = Rect->top;
1560 }
1561
1562 /* No oversized texture? This is easy */
1563 if(!(This->Flags & SFLAG_OVERSIZE)) {
1564 /* Which rect from the texture do I need? */
1565 if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
1566 glTexCoord[0] = (float) Rect->left;
1567 glTexCoord[2] = (float) Rect->top;
1568 glTexCoord[1] = (float) Rect->right;
1569 glTexCoord[3] = (float) Rect->bottom;
1570 } else {
1571 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
1572 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
1573 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
1574 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
1575 }
1576
1577 return TRUE;
1578 } else {
1579 /* Check if we can succeed at all */
1580 if( (x2 - x1) > maxSize ||
1581 (y2 - y1) > maxSize ) {
1582 TRACE("Requested rectangle is too large for gl\n");
1583 return FALSE;
1584 }
1585
1586 /* A part of the texture has to be picked. First, check if
1587 * some texture part is loaded already, if yes try to re-use it.
1588 * If the texture is dirty, or the part can't be used,
1589 * re-position the part to load
1590 */
1591 if(This->Flags & SFLAG_INTEXTURE) {
1592 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
1593 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
1594 /* Ok, the rectangle is ok, re-use it */
1595 TRACE("Using existing gl Texture\n");
1596 } else {
1597 /* Rectangle is not ok, dirtify the texture to reload it */
1598 TRACE("Dirtifying texture to force reload\n");
1599 This->Flags &= ~SFLAG_INTEXTURE;
1600 }
1601 }
1602
1603 /* Now if we are dirty(no else if!) */
1604 if(!(This->Flags & SFLAG_INTEXTURE)) {
1605 /* Set the new rectangle. Use the following strategy:
1606 * 1) Use as big textures as possible.
1607 * 2) Place the texture part in the way that the requested
1608 * part is in the middle of the texture(well, almost)
1609 * 3) If the texture is moved over the edges of the
1610 * surface, replace it nicely
1611 * 4) If the coord is not limiting the texture size,
1612 * use the whole size
1613 */
1614 if((This->pow2Width) > maxSize) {
1615 This->glRect.left = x1 - maxSize / 2;
1616 if(This->glRect.left < 0) {
1617 This->glRect.left = 0;
1618 }
1619 This->glRect.right = This->glRect.left + maxSize;
1620 if(This->glRect.right > This->currentDesc.Width) {
1621 This->glRect.right = This->currentDesc.Width;
1622 This->glRect.left = This->glRect.right - maxSize;
1623 }
1624 } else {
1625 This->glRect.left = 0;
1626 This->glRect.right = This->pow2Width;
1627 }
1628
1629 if(This->pow2Height > maxSize) {
1630 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
1631 if(This->glRect.top < 0) This->glRect.top = 0;
1632 This->glRect.bottom = This->glRect.left + maxSize;
1633 if(This->glRect.bottom > This->currentDesc.Height) {
1634 This->glRect.bottom = This->currentDesc.Height;
1635 This->glRect.top = This->glRect.bottom - maxSize;
1636 }
1637 } else {
1638 This->glRect.top = 0;
1639 This->glRect.bottom = This->pow2Height;
1640 }
1641 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
1642 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
1643 }
1644
1645 /* Re-calculate the rect to draw */
1646 Rect->left -= This->glRect.left;
1647 Rect->right -= This->glRect.left;
1648 Rect->top -= This->glRect.top;
1649 Rect->bottom -= This->glRect.top;
1650
1651 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
1652 * or the pow2Width / pow2Height of the surface.
1653 *
1654 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
1655 * as regular GL_TEXTURE_2D.
1656 */
1657 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
1658 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
1659 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
1660 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
1661 }
1662 return TRUE;
1663 }
1664 #undef GLINFO_LOCATION
1665
1666 /* Hash table functions */
1667
1668 struct hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
1669 {
1670 struct hash_table_t *table;
1671 unsigned int initial_size = 8;
1672
1673 table = HeapAlloc(GetProcessHeap(), 0, sizeof(struct hash_table_t) + (initial_size * sizeof(struct list)));
1674 if (!table)
1675 {
1676 ERR("Failed to allocate table, returning NULL.\n");
1677 return NULL;
1678 }
1679
1680 table->hash_function = hash_function;
1681 table->compare_function = compare_function;
1682
1683 table->grow_size = initial_size - (initial_size >> 2);
1684 table->shrink_size = 0;
1685
1686 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
1687 if (!table->buckets)
1688 {
1689 ERR("Failed to allocate table buckets, returning NULL.\n");
1690 HeapFree(GetProcessHeap(), 0, table);
1691 return NULL;
1692 }
1693 table->bucket_count = initial_size;
1694
1695 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(struct hash_table_entry_t));
1696 if (!table->entries)
1697 {
1698 ERR("Failed to allocate table entries, returning NULL.\n");
1699 HeapFree(GetProcessHeap(), 0, table->buckets);
1700 HeapFree(GetProcessHeap(), 0, table);
1701 return NULL;
1702 }
1703 table->entry_count = 0;
1704
1705 list_init(&table->free_entries);
1706 table->count = 0;
1707
1708 return table;
1709 }
1710
1711 void hash_table_destroy(struct hash_table_t *table, void (*free_value)(void *value, void *cb), void *cb)
1712 {
1713 unsigned int i = 0;
1714
1715 for (i = 0; i < table->entry_count; ++i)
1716 {
1717 if(free_value) {
1718 free_value(table->entries[i].value, cb);
1719 }
1720 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
1721 }
1722
1723 HeapFree(GetProcessHeap(), 0, table->entries);
1724 HeapFree(GetProcessHeap(), 0, table->buckets);
1725 HeapFree(GetProcessHeap(), 0, table);
1726 }
1727
1728 void hash_table_for_each_entry(struct hash_table_t *table, void (*callback)(void *value, void *context), void *context)
1729 {
1730 unsigned int i = 0;
1731
1732 for (i = 0; i < table->entry_count; ++i)
1733 {
1734 callback(table->entries[i].value, context);
1735 }
1736 }
1737
1738 static inline struct hash_table_entry_t *hash_table_get_by_idx(const struct hash_table_t *table, const void *key,
1739 unsigned int idx)
1740 {
1741 struct hash_table_entry_t *entry;
1742
1743 if (table->buckets[idx].next)
1744 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), struct hash_table_entry_t, entry)
1745 if (table->compare_function(entry->key, key)) return entry;
1746
1747 return NULL;
1748 }
1749
1750 static BOOL hash_table_resize(struct hash_table_t *table, unsigned int new_bucket_count)
1751 {
1752 unsigned int new_entry_count = 0;
1753 struct hash_table_entry_t *new_entries;
1754 struct list *new_buckets;
1755 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
1756 unsigned int i;
1757
1758 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
1759 if (!new_buckets)
1760 {
1761 ERR("Failed to allocate new buckets, returning FALSE.\n");
1762 return FALSE;
1763 }
1764
1765 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(struct hash_table_entry_t));
1766 if (!new_entries)
1767 {
1768 ERR("Failed to allocate new entries, returning FALSE.\n");
1769 HeapFree(GetProcessHeap(), 0, new_buckets);
1770 return FALSE;
1771 }
1772
1773 for (i = 0; i < table->bucket_count; ++i)
1774 {
1775 if (table->buckets[i].next)
1776 {
1777 struct hash_table_entry_t *entry, *entry2;
1778
1779 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], struct hash_table_entry_t, entry)
1780 {
1781 int j;
1782 struct hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
1783 *new_entry = *entry;
1784
1785 j = new_entry->hash & (new_bucket_count - 1);
1786
1787 if (!new_buckets[j].next) list_init(&new_buckets[j]);
1788 list_add_head(&new_buckets[j], &new_entry->entry);
1789 }
1790 }
1791 }
1792
1793 HeapFree(GetProcessHeap(), 0, table->buckets);
1794 table->buckets = new_buckets;
1795
1796 HeapFree(GetProcessHeap(), 0, table->entries);
1797 table->entries = new_entries;
1798
1799 table->entry_count = new_entry_count;
1800 list_init(&table->free_entries);
1801
1802 table->bucket_count = new_bucket_count;
1803 table->grow_size = grow_size;
1804 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
1805
1806 return TRUE;
1807 }
1808
1809 void hash_table_put(struct hash_table_t *table, void *key, void *value)
1810 {
1811 unsigned int idx;
1812 unsigned int hash;
1813 struct hash_table_entry_t *entry;
1814
1815 hash = table->hash_function(key);
1816 idx = hash & (table->bucket_count - 1);
1817 entry = hash_table_get_by_idx(table, key, idx);
1818
1819 if (entry)
1820 {
1821 HeapFree(GetProcessHeap(), 0, key);
1822 entry->value = value;
1823
1824 if (!value)
1825 {
1826 HeapFree(GetProcessHeap(), 0, entry->key);
1827 entry->key = NULL;
1828
1829 /* Remove the entry */
1830 list_remove(&entry->entry);
1831 list_add_head(&table->free_entries, &entry->entry);
1832
1833 --table->count;
1834
1835 /* Shrink if necessary */
1836 if (table->count < table->shrink_size) {
1837 if (!hash_table_resize(table, table->bucket_count >> 1))
1838 {
1839 ERR("Failed to shrink the table...\n");
1840 }
1841 }
1842 }
1843
1844 return;
1845 }
1846
1847 if (!value) return;
1848
1849 /* Grow if necessary */
1850 if (table->count >= table->grow_size)
1851 {
1852 if (!hash_table_resize(table, table->bucket_count << 1))
1853 {
1854 ERR("Failed to grow the table, returning.\n");
1855 return;
1856 }
1857
1858 idx = hash & (table->bucket_count - 1);
1859 }
1860
1861 /* Find an entry to insert */
1862 if (!list_empty(&table->free_entries))
1863 {
1864 struct list *elem = list_head(&table->free_entries);
1865
1866 list_remove(elem);
1867 entry = LIST_ENTRY(elem, struct hash_table_entry_t, entry);
1868 } else {
1869 entry = table->entries + (table->entry_count++);
1870 }
1871
1872 /* Insert the entry */
1873 entry->key = key;
1874 entry->value = value;
1875 entry->hash = hash;
1876 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
1877 list_add_head(&table->buckets[idx], &entry->entry);
1878
1879 ++table->count;
1880 }
1881
1882 void hash_table_remove(struct hash_table_t *table, void *key)
1883 {
1884 hash_table_put(table, key, NULL);
1885 }
1886
1887 void *hash_table_get(const struct hash_table_t *table, const void *key)
1888 {
1889 unsigned int idx;
1890 struct hash_table_entry_t *entry;
1891
1892 idx = table->hash_function(key) & (table->bucket_count - 1);
1893 entry = hash_table_get_by_idx(table, key, idx);
1894
1895 return entry ? entry->value : NULL;
1896 }
1897
1898 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
1899 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
1900 #define ARG1 0x01
1901 #define ARG2 0x02
1902 #define ARG0 0x04
1903 static const unsigned char args[WINED3DTOP_LERP + 1] = {
1904 /* undefined */ 0,
1905 /* D3DTOP_DISABLE */ 0,
1906 /* D3DTOP_SELECTARG1 */ ARG1,
1907 /* D3DTOP_SELECTARG2 */ ARG2,
1908 /* D3DTOP_MODULATE */ ARG1 | ARG2,
1909 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
1910 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
1911 /* D3DTOP_ADD */ ARG1 | ARG2,
1912 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
1913 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
1914 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
1915 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
1916 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
1917 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
1918 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
1919 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
1920 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
1921 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
1922 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
1923 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
1924 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
1925 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
1926 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
1927 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
1928 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
1929 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
1930 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
1931 };
1932 unsigned int i;
1933 DWORD ttff;
1934 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
1935
1936 for(i = 0; i < GL_LIMITS(texture_stages); i++) {
1937 IWineD3DBaseTextureImpl *texture;
1938 settings->op[i].padding = 0;
1939 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
1940 settings->op[i].cop = WINED3DTOP_DISABLE;
1941 settings->op[i].aop = WINED3DTOP_DISABLE;
1942 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
1943 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
1944 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
1945 settings->op[i].dst = resultreg;
1946 settings->op[i].tex_type = tex_1d;
1947 settings->op[i].projected = proj_none;
1948 i++;
1949 break;
1950 }
1951
1952 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
1953 if(texture) {
1954 settings->op[i].color_fixup = texture->baseTexture.shader_color_fixup;
1955 if(ignore_textype) {
1956 settings->op[i].tex_type = tex_1d;
1957 } else {
1958 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
1959 case GL_TEXTURE_1D:
1960 settings->op[i].tex_type = tex_1d;
1961 break;
1962 case GL_TEXTURE_2D:
1963 settings->op[i].tex_type = tex_2d;
1964 break;
1965 case GL_TEXTURE_3D:
1966 settings->op[i].tex_type = tex_3d;
1967 break;
1968 case GL_TEXTURE_CUBE_MAP_ARB:
1969 settings->op[i].tex_type = tex_cube;
1970 break;
1971 case GL_TEXTURE_RECTANGLE_ARB:
1972 settings->op[i].tex_type = tex_rect;
1973 break;
1974 }
1975 }
1976 } else {
1977 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
1978 settings->op[i].tex_type = tex_1d;
1979 }
1980
1981 cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
1982 aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
1983
1984 carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
1985 carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
1986 carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
1987
1988 if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
1989 carg1, carg2, carg0)) {
1990 carg0 = ARG_UNUSED;
1991 carg2 = ARG_UNUSED;
1992 carg1 = WINED3DTA_CURRENT;
1993 cop = WINED3DTOP_SELECTARG1;
1994 }
1995
1996 if(cop == WINED3DTOP_DOTPRODUCT3) {
1997 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
1998 * the color result to the alpha component of the destination
1999 */
2000 aop = cop;
2001 aarg1 = carg1;
2002 aarg2 = carg2;
2003 aarg0 = carg0;
2004 } else {
2005 aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2006 aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2007 aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2008 }
2009
2010 if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2011 {
2012 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2013
2014 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2015 {
2016 IWineD3DSurfaceImpl *surf;
2017 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2018
2019 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT
2020 && getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000)
2021 {
2022 if (aop == WINED3DTOP_DISABLE)
2023 {
2024 aarg1 = WINED3DTA_TEXTURE;
2025 aop = WINED3DTOP_SELECTARG1;
2026 }
2027 else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2028 {
2029 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2030 {
2031 aarg2 = WINED3DTA_TEXTURE;
2032 aop = WINED3DTOP_MODULATE;
2033 }
2034 else aarg1 = WINED3DTA_TEXTURE;
2035 }
2036 else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2037 {
2038 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2039 {
2040 aarg1 = WINED3DTA_TEXTURE;
2041 aop = WINED3DTOP_MODULATE;
2042 }
2043 else aarg2 = WINED3DTA_TEXTURE;
2044 }
2045 }
2046 }
2047 }
2048
2049 if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
2050 aarg1, aarg2, aarg0)) {
2051 aarg0 = ARG_UNUSED;
2052 aarg2 = ARG_UNUSED;
2053 aarg1 = WINED3DTA_CURRENT;
2054 aop = WINED3DTOP_SELECTARG1;
2055 }
2056
2057 if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2058 aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2059 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2060 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2061 settings->op[i].projected = proj_count3;
2062 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2063 settings->op[i].projected = proj_count4;
2064 } else {
2065 settings->op[i].projected = proj_none;
2066 }
2067 } else {
2068 settings->op[i].projected = proj_none;
2069 }
2070
2071 settings->op[i].cop = cop;
2072 settings->op[i].aop = aop;
2073 settings->op[i].carg0 = carg0;
2074 settings->op[i].carg1 = carg1;
2075 settings->op[i].carg2 = carg2;
2076 settings->op[i].aarg0 = aarg0;
2077 settings->op[i].aarg1 = aarg1;
2078 settings->op[i].aarg2 = aarg2;
2079
2080 if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2081 settings->op[i].dst = tempreg;
2082 } else {
2083 settings->op[i].dst = resultreg;
2084 }
2085 }
2086
2087 /* Clear unsupported stages */
2088 for(; i < MAX_TEXTURES; i++) {
2089 memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2090 }
2091
2092 if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2093 settings->fog = FOG_OFF;
2094 } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2095 if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2096 settings->fog = FOG_LINEAR;
2097 } else {
2098 switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2099 case WINED3DFOG_NONE:
2100 case WINED3DFOG_LINEAR:
2101 settings->fog = FOG_LINEAR;
2102 break;
2103 case WINED3DFOG_EXP:
2104 settings->fog = FOG_EXP;
2105 break;
2106 case WINED3DFOG_EXP2:
2107 settings->fog = FOG_EXP2;
2108 break;
2109 }
2110 }
2111 } else {
2112 switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2113 case WINED3DFOG_LINEAR:
2114 settings->fog = FOG_LINEAR;
2115 break;
2116 case WINED3DFOG_EXP:
2117 settings->fog = FOG_EXP;
2118 break;
2119 case WINED3DFOG_EXP2:
2120 settings->fog = FOG_EXP2;
2121 break;
2122 }
2123 }
2124 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2125 settings->sRGB_write = 1;
2126 } else {
2127 settings->sRGB_write = 0;
2128 }
2129 }
2130 #undef GLINFO_LOCATION
2131
2132 const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
2133 const struct ffp_frag_settings *settings)
2134 {
2135 return hash_table_get(fragment_shaders, settings);
2136 }
2137
2138 void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *desc) {
2139 struct ffp_frag_settings *key = HeapAlloc(GetProcessHeap(), 0, sizeof(*key));
2140 /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2141 * whereas desc points to an extended structure with implementation specific parts.
2142 * Make a copy of the key because hash_table_put takes ownership of it
2143 */
2144 *key = desc->settings;
2145 hash_table_put(shaders, key, desc);
2146 }
2147
2148 /* Activates the texture dimension according to the bound D3D texture.
2149 * Does not care for the colorop or correct gl texture unit(when using nvrc)
2150 * Requires the caller to activate the correct unit before
2151 */
2152 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2153 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2154 if(stateblock->textures[stage]) {
2155 switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2156 case GL_TEXTURE_2D:
2157 glDisable(GL_TEXTURE_3D);
2158 checkGLcall("glDisable(GL_TEXTURE_3D)");
2159 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2160 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2161 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2162 }
2163 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2164 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2165 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2166 }
2167 glEnable(GL_TEXTURE_2D);
2168 checkGLcall("glEnable(GL_TEXTURE_2D)");
2169 break;
2170 case GL_TEXTURE_RECTANGLE_ARB:
2171 glDisable(GL_TEXTURE_2D);
2172 checkGLcall("glDisable(GL_TEXTURE_2D)");
2173 glDisable(GL_TEXTURE_3D);
2174 checkGLcall("glDisable(GL_TEXTURE_3D)");
2175 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2176 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2177 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2178 }
2179 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2180 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2181 break;
2182 case GL_TEXTURE_3D:
2183 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2184 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2185 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2186 }
2187 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2188 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2189 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2190 }
2191 glDisable(GL_TEXTURE_2D);
2192 checkGLcall("glDisable(GL_TEXTURE_2D)");
2193 glEnable(GL_TEXTURE_3D);
2194 checkGLcall("glEnable(GL_TEXTURE_3D)");
2195 break;
2196 case GL_TEXTURE_CUBE_MAP_ARB:
2197 glDisable(GL_TEXTURE_2D);
2198 checkGLcall("glDisable(GL_TEXTURE_2D)");
2199 glDisable(GL_TEXTURE_3D);
2200 checkGLcall("glDisable(GL_TEXTURE_3D)");
2201 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2202 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2203 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2204 }
2205 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2206 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2207 break;
2208 }
2209 } else {
2210 glEnable(GL_TEXTURE_2D);
2211 checkGLcall("glEnable(GL_TEXTURE_2D)");
2212 glDisable(GL_TEXTURE_3D);
2213 checkGLcall("glDisable(GL_TEXTURE_3D)");
2214 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2215 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2216 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2217 }
2218 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2219 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2220 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2221 }
2222 /* Binding textures is done by samplers. A dummy texture will be bound */
2223 }
2224 }
2225
2226 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2227 DWORD sampler = state - STATE_SAMPLER(0);
2228 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2229
2230 /* No need to enable / disable anything here for unused samplers. The tex_colorop
2231 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2232 * will take care of this business
2233 */
2234 if(mapped_stage == -1 || mapped_stage >= GL_LIMITS(textures)) return;
2235 if(sampler >= stateblock->lowest_disabled_stage) return;
2236 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2237
2238 texture_activate_dimensions(sampler, stateblock, context);
2239 }
2240 #undef GLINFO_LOCATION
2241
2242 unsigned int ffp_frag_program_key_hash(const void *key)
2243 {
2244 const struct ffp_frag_settings *k = key;
2245 unsigned int hash = 0, i;
2246 const DWORD *blob;
2247
2248 /* This takes the texture op settings of stage 0 and 1 into account.
2249 * how exactly depends on the memory laybout of the compiler, but it
2250 * should not matter too much. Stages > 1 are used rarely, so there's
2251 * no need to process them. Even if they're used it is likely that
2252 * the ffp setup has distinct stage 0 and 1 settings.
2253 */
2254 for(i = 0; i < 2; i++) {
2255 blob = (const DWORD *)&k->op[i];
2256 hash ^= blob[0] ^ blob[1];
2257 }
2258
2259 hash += ~(hash << 15);
2260 hash ^= (hash >> 10);
2261 hash += (hash << 3);
2262 hash ^= (hash >> 6);
2263 hash += ~(hash << 11);
2264 hash ^= (hash >> 16);
2265
2266 return hash;
2267 }
2268
2269 BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb)
2270 {
2271 const struct ffp_frag_settings *ka = keya;
2272 const struct ffp_frag_settings *kb = keyb;
2273
2274 return memcmp(ka, kb, sizeof(*ka)) == 0;
2275 }
2276
2277 UINT wined3d_log2i(UINT32 x)
2278 {
2279 static const BYTE l[] =
2280 {
2281 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2282 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2283 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2284 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2285 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2286 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2287 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2288 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
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,
2291 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2292 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2293 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2294 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2295 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2296 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2297 };
2298 UINT32 i;
2299
2300 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
2301 }