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