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