ole32: Move private data structure out of header file.
[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 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
1369
1370 /* This small helper function is used to convert a bitmask into the number of masked bits */
1371 unsigned int count_bits(unsigned int mask)
1372 {
1373     unsigned int count;
1374     for (count = 0; mask; ++count)
1375     {
1376         mask &= mask - 1;
1377     }
1378     return count;
1379 }
1380
1381 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
1382  * The later function requires individual color components. */
1383 BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
1384 {
1385     const StaticPixelFormatDesc *desc;
1386
1387     TRACE("fmt: %s\n", debug_d3dformat(fmt));
1388     switch(fmt)
1389     {
1390         case WINED3DFMT_X8R8G8B8:
1391         case WINED3DFMT_R8G8B8:
1392         case WINED3DFMT_A8R8G8B8:
1393         case WINED3DFMT_A2R10G10B10:
1394         case WINED3DFMT_X1R5G5B5:
1395         case WINED3DFMT_A1R5G5B5:
1396         case WINED3DFMT_R5G6B5:
1397         case WINED3DFMT_X4R4G4B4:
1398         case WINED3DFMT_A4R4G4B4:
1399         case WINED3DFMT_R3G3B2:
1400         case WINED3DFMT_A8P8:
1401         case WINED3DFMT_P8:
1402             break;
1403         default:
1404             ERR("Unsupported format: %s\n", debug_d3dformat(fmt));
1405             return FALSE;
1406     }
1407
1408     desc = getFormatDescEntry(fmt, NULL, NULL);
1409     if(!desc)
1410     {
1411         ERR("Unable to look up format: 0x%x\n", fmt);
1412         return FALSE;
1413     }
1414     *redSize = count_bits(desc->redMask);
1415     *greenSize = count_bits(desc->greenMask);
1416     *blueSize = count_bits(desc->blueMask);
1417     *alphaSize = count_bits(desc->alphaMask);
1418     *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
1419
1420     TRACE("Returning red:  %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n", *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(fmt));
1421     return TRUE;
1422 }
1423
1424 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
1425 BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize)
1426 {
1427     const StaticPixelFormatDesc *desc;
1428
1429     TRACE("fmt: %s\n", debug_d3dformat(fmt));
1430     switch(fmt)
1431     {
1432         case WINED3DFMT_D16_LOCKABLE:
1433         case WINED3DFMT_D16:
1434         case WINED3DFMT_D15S1:
1435         case WINED3DFMT_D24X8:
1436         case WINED3DFMT_D24X4S4:
1437         case WINED3DFMT_D24S8:
1438         case WINED3DFMT_D24FS8:
1439         case WINED3DFMT_D32:
1440         case WINED3DFMT_D32F_LOCKABLE:
1441             break;
1442         default:
1443             FIXME("Unsupported stencil format: %s\n", debug_d3dformat(fmt));
1444             return FALSE;
1445     }
1446
1447     desc = getFormatDescEntry(fmt, NULL, NULL);
1448     if(!desc)
1449     {
1450         ERR("Unable to look up format: 0x%x\n", fmt);
1451         return FALSE;
1452     }
1453     *depthSize = desc->depthSize;
1454     *stencilSize = desc->stencilSize;
1455
1456     TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n", *depthSize, *stencilSize, debug_d3dformat(fmt));
1457     return TRUE;
1458 }
1459
1460 #undef GLINFO_LOCATION
1461
1462 /* DirectDraw stuff */
1463 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
1464     switch(depth) {
1465         case 8:  return WINED3DFMT_P8;
1466         case 15: return WINED3DFMT_X1R5G5B5;
1467         case 16: return WINED3DFMT_R5G6B5;
1468         case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
1469         case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
1470         default: return WINED3DFMT_UNKNOWN;
1471     }
1472 }
1473
1474 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
1475     WINED3DMATRIX temp;
1476
1477     /* Now do the multiplication 'by hand'.
1478        I know that all this could be optimised, but this will be done later :-) */
1479     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);
1480     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);
1481     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);
1482     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);
1483
1484     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);
1485     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);
1486     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);
1487     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);
1488
1489     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);
1490     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);
1491     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);
1492     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);
1493
1494     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);
1495     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);
1496     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);
1497     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);
1498
1499     /* And copy the new matrix in the good storage.. */
1500     memcpy(dest, &temp, 16 * sizeof(float));
1501 }
1502
1503 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
1504     DWORD size = 0;
1505     int i;
1506     int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
1507
1508     if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
1509     if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
1510     if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
1511     if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
1512     switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
1513         case WINED3DFVF_XYZ:    size += 3 * sizeof(float); break;
1514         case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
1515         case WINED3DFVF_XYZB1:  size += 4 * sizeof(float); break;
1516         case WINED3DFVF_XYZB2:  size += 5 * sizeof(float); break;
1517         case WINED3DFVF_XYZB3:  size += 6 * sizeof(float); break;
1518         case WINED3DFVF_XYZB4:  size += 7 * sizeof(float); break;
1519         case WINED3DFVF_XYZB5:  size += 8 * sizeof(float); break;
1520         case WINED3DFVF_XYZW:   size += 4 * sizeof(float); break;
1521         default: ERR("Unexpected position mask\n");
1522     }
1523     for (i = 0; i < numTextures; i++) {
1524         size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
1525     }
1526
1527     return size;
1528 }
1529
1530 /***********************************************************************
1531  * CalculateTexRect
1532  *
1533  * Calculates the dimensions of the opengl texture used for blits.
1534  * Handled oversized opengl textures and updates the source rectangle
1535  * accordingly
1536  *
1537  * Params:
1538  *  This: Surface to operate on
1539  *  Rect: Requested rectangle
1540  *
1541  * Returns:
1542  *  TRUE if the texture part can be loaded,
1543  *  FALSE otherwise
1544  *
1545  *********************************************************************/
1546 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
1547
1548 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
1549     int x1 = Rect->left, x2 = Rect->right;
1550     int y1 = Rect->top, y2 = Rect->bottom;
1551     GLint maxSize = GL_LIMITS(texture_size);
1552
1553     TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
1554           Rect->left, Rect->top, Rect->right, Rect->bottom);
1555
1556     /* The sizes might be reversed */
1557     if(Rect->left > Rect->right) {
1558         x1 = Rect->right;
1559         x2 = Rect->left;
1560     }
1561     if(Rect->top > Rect->bottom) {
1562         y1 = Rect->bottom;
1563         y2 = Rect->top;
1564     }
1565
1566     /* No oversized texture? This is easy */
1567     if(!(This->Flags & SFLAG_OVERSIZE)) {
1568         /* Which rect from the texture do I need? */
1569         if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
1570             glTexCoord[0] = (float) Rect->left;
1571             glTexCoord[2] = (float) Rect->top;
1572             glTexCoord[1] = (float) Rect->right;
1573             glTexCoord[3] = (float) Rect->bottom;
1574         } else {
1575             glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
1576             glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
1577             glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
1578             glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
1579         }
1580
1581         return TRUE;
1582     } else {
1583         /* Check if we can succeed at all */
1584         if( (x2 - x1) > maxSize ||
1585             (y2 - y1) > maxSize ) {
1586             TRACE("Requested rectangle is too large for gl\n");
1587             return FALSE;
1588         }
1589
1590         /* A part of the texture has to be picked. First, check if
1591          * some texture part is loaded already, if yes try to re-use it.
1592          * If the texture is dirty, or the part can't be used,
1593          * re-position the part to load
1594          */
1595         if(This->Flags & SFLAG_INTEXTURE) {
1596             if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
1597                This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
1598                 /* Ok, the rectangle is ok, re-use it */
1599                 TRACE("Using existing gl Texture\n");
1600             } else {
1601                 /* Rectangle is not ok, dirtify the texture to reload it */
1602                 TRACE("Dirtifying texture to force reload\n");
1603                 This->Flags &= ~SFLAG_INTEXTURE;
1604             }
1605         }
1606
1607         /* Now if we are dirty(no else if!) */
1608         if(!(This->Flags & SFLAG_INTEXTURE)) {
1609             /* Set the new rectangle. Use the following strategy:
1610              * 1) Use as big textures as possible.
1611              * 2) Place the texture part in the way that the requested
1612              *    part is in the middle of the texture(well, almost)
1613              * 3) If the texture is moved over the edges of the
1614              *    surface, replace it nicely
1615              * 4) If the coord is not limiting the texture size,
1616              *    use the whole size
1617              */
1618             if((This->pow2Width) > maxSize) {
1619                 This->glRect.left = x1 - maxSize / 2;
1620                 if(This->glRect.left < 0) {
1621                     This->glRect.left = 0;
1622                 }
1623                 This->glRect.right = This->glRect.left + maxSize;
1624                 if(This->glRect.right > This->currentDesc.Width) {
1625                     This->glRect.right = This->currentDesc.Width;
1626                     This->glRect.left = This->glRect.right - maxSize;
1627                 }
1628             } else {
1629                 This->glRect.left = 0;
1630                 This->glRect.right = This->pow2Width;
1631             }
1632
1633             if(This->pow2Height > maxSize) {
1634                 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
1635                 if(This->glRect.top < 0) This->glRect.top = 0;
1636                 This->glRect.bottom = This->glRect.left + maxSize;
1637                 if(This->glRect.bottom > This->currentDesc.Height) {
1638                     This->glRect.bottom = This->currentDesc.Height;
1639                     This->glRect.top = This->glRect.bottom - maxSize;
1640                 }
1641             } else {
1642                 This->glRect.top = 0;
1643                 This->glRect.bottom = This->pow2Height;
1644             }
1645             TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
1646                    This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
1647         }
1648
1649         /* Re-calculate the rect to draw */
1650         Rect->left -= This->glRect.left;
1651         Rect->right -= This->glRect.left;
1652         Rect->top -= This->glRect.top;
1653         Rect->bottom -= This->glRect.top;
1654
1655         /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
1656          * or the pow2Width / pow2Height of the surface.
1657          *
1658          * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
1659          * as regular GL_TEXTURE_2D.
1660          */
1661         glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
1662         glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
1663         glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
1664         glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
1665     }
1666     return TRUE;
1667 }
1668 #undef GLINFO_LOCATION
1669
1670 /* Hash table functions */
1671
1672 struct hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
1673 {
1674     struct hash_table_t *table;
1675     unsigned int initial_size = 8;
1676
1677     table = HeapAlloc(GetProcessHeap(), 0, sizeof(struct hash_table_t) + (initial_size * sizeof(struct list)));
1678     if (!table)
1679     {
1680         ERR("Failed to allocate table, returning NULL.\n");
1681         return NULL;
1682     }
1683
1684     table->hash_function = hash_function;
1685     table->compare_function = compare_function;
1686
1687     table->grow_size = initial_size - (initial_size >> 2);
1688     table->shrink_size = 0;
1689
1690     table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
1691     if (!table->buckets)
1692     {
1693         ERR("Failed to allocate table buckets, returning NULL.\n");
1694         HeapFree(GetProcessHeap(), 0, table);
1695         return NULL;
1696     }
1697     table->bucket_count = initial_size;
1698
1699     table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(struct hash_table_entry_t));
1700     if (!table->entries)
1701     {
1702         ERR("Failed to allocate table entries, returning NULL.\n");
1703         HeapFree(GetProcessHeap(), 0, table->buckets);
1704         HeapFree(GetProcessHeap(), 0, table);
1705         return NULL;
1706     }
1707     table->entry_count = 0;
1708
1709     list_init(&table->free_entries);
1710     table->count = 0;
1711
1712     return table;
1713 }
1714
1715 void hash_table_destroy(struct hash_table_t *table, void (*free_value)(void *value, void *cb), void *cb)
1716 {
1717     unsigned int i = 0;
1718
1719     for (i = 0; i < table->entry_count; ++i)
1720     {
1721         if(free_value) {
1722             free_value(table->entries[i].value, cb);
1723         }
1724         HeapFree(GetProcessHeap(), 0, table->entries[i].key);
1725     }
1726
1727     HeapFree(GetProcessHeap(), 0, table->entries);
1728     HeapFree(GetProcessHeap(), 0, table->buckets);
1729     HeapFree(GetProcessHeap(), 0, table);
1730 }
1731
1732 void hash_table_for_each_entry(struct hash_table_t *table, void (*callback)(void *value, void *context), void *context)
1733 {
1734     unsigned int i = 0;
1735
1736     for (i = 0; i < table->entry_count; ++i)
1737     {
1738         callback(table->entries[i].value, context);
1739     }
1740 }
1741
1742 static inline struct hash_table_entry_t *hash_table_get_by_idx(const struct hash_table_t *table, const void *key,
1743         unsigned int idx)
1744 {
1745     struct hash_table_entry_t *entry;
1746
1747     if (table->buckets[idx].next)
1748         LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), struct hash_table_entry_t, entry)
1749             if (table->compare_function(entry->key, key)) return entry;
1750
1751     return NULL;
1752 }
1753
1754 static BOOL hash_table_resize(struct hash_table_t *table, unsigned int new_bucket_count)
1755 {
1756     unsigned int new_entry_count = 0;
1757     struct hash_table_entry_t *new_entries;
1758     struct list *new_buckets;
1759     unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
1760     unsigned int i;
1761
1762     new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
1763     if (!new_buckets)
1764     {
1765         ERR("Failed to allocate new buckets, returning FALSE.\n");
1766         return FALSE;
1767     }
1768
1769     new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(struct hash_table_entry_t));
1770     if (!new_entries)
1771     {
1772         ERR("Failed to allocate new entries, returning FALSE.\n");
1773         HeapFree(GetProcessHeap(), 0, new_buckets);
1774         return FALSE;
1775     }
1776
1777     for (i = 0; i < table->bucket_count; ++i)
1778     {
1779         if (table->buckets[i].next)
1780         {
1781             struct hash_table_entry_t *entry, *entry2;
1782
1783             LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], struct hash_table_entry_t, entry)
1784             {
1785                 int j;
1786                 struct hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
1787                 *new_entry = *entry;
1788
1789                 j = new_entry->hash & (new_bucket_count - 1);
1790
1791                 if (!new_buckets[j].next) list_init(&new_buckets[j]);
1792                 list_add_head(&new_buckets[j], &new_entry->entry);
1793             }
1794         }
1795     }
1796
1797     HeapFree(GetProcessHeap(), 0, table->buckets);
1798     table->buckets = new_buckets;
1799
1800     HeapFree(GetProcessHeap(), 0, table->entries);
1801     table->entries = new_entries;
1802
1803     table->entry_count = new_entry_count;
1804     list_init(&table->free_entries);
1805
1806     table->bucket_count = new_bucket_count;
1807     table->grow_size = grow_size;
1808     table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
1809
1810     return TRUE;
1811 }
1812
1813 void hash_table_put(struct hash_table_t *table, void *key, void *value)
1814 {
1815     unsigned int idx;
1816     unsigned int hash;
1817     struct hash_table_entry_t *entry;
1818
1819     hash = table->hash_function(key);
1820     idx = hash & (table->bucket_count - 1);
1821     entry = hash_table_get_by_idx(table, key, idx);
1822
1823     if (entry)
1824     {
1825         HeapFree(GetProcessHeap(), 0, key);
1826         entry->value = value;
1827
1828         if (!value)
1829         {
1830             HeapFree(GetProcessHeap(), 0, entry->key);
1831             entry->key = NULL;
1832
1833             /* Remove the entry */
1834             list_remove(&entry->entry);
1835             list_add_head(&table->free_entries, &entry->entry);
1836
1837             --table->count;
1838
1839             /* Shrink if necessary */
1840             if (table->count < table->shrink_size) {
1841                 if (!hash_table_resize(table, table->bucket_count >> 1))
1842                 {
1843                     ERR("Failed to shrink the table...\n");
1844                 }
1845             }
1846         }
1847
1848         return;
1849     }
1850
1851     if (!value) return;
1852
1853     /* Grow if necessary */
1854     if (table->count >= table->grow_size)
1855     {
1856         if (!hash_table_resize(table, table->bucket_count << 1))
1857         {
1858             ERR("Failed to grow the table, returning.\n");
1859             return;
1860         }
1861
1862         idx = hash & (table->bucket_count - 1);
1863     }
1864
1865     /* Find an entry to insert */
1866     if (!list_empty(&table->free_entries))
1867     {
1868         struct list *elem = list_head(&table->free_entries);
1869
1870         list_remove(elem);
1871         entry = LIST_ENTRY(elem, struct hash_table_entry_t, entry);
1872     } else {
1873         entry = table->entries + (table->entry_count++);
1874     }
1875
1876     /* Insert the entry */
1877     entry->key = key;
1878     entry->value = value;
1879     entry->hash = hash;
1880     if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
1881     list_add_head(&table->buckets[idx], &entry->entry);
1882
1883     ++table->count;
1884 }
1885
1886 void hash_table_remove(struct hash_table_t *table, void *key)
1887 {
1888     hash_table_put(table, key, NULL);
1889 }
1890
1891 void *hash_table_get(const struct hash_table_t *table, const void *key)
1892 {
1893     unsigned int idx;
1894     struct hash_table_entry_t *entry;
1895
1896     idx = table->hash_function(key) & (table->bucket_count - 1);
1897     entry = hash_table_get_by_idx(table, key, idx);
1898
1899     return entry ? entry->value : NULL;
1900 }
1901
1902 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
1903 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
1904 #define ARG1 0x01
1905 #define ARG2 0x02
1906 #define ARG0 0x04
1907     static const unsigned char args[WINED3DTOP_LERP + 1] = {
1908         /* undefined                        */  0,
1909         /* D3DTOP_DISABLE                   */  0,
1910         /* D3DTOP_SELECTARG1                */  ARG1,
1911         /* D3DTOP_SELECTARG2                */  ARG2,
1912         /* D3DTOP_MODULATE                  */  ARG1 | ARG2,
1913         /* D3DTOP_MODULATE2X                */  ARG1 | ARG2,
1914         /* D3DTOP_MODULATE4X                */  ARG1 | ARG2,
1915         /* D3DTOP_ADD                       */  ARG1 | ARG2,
1916         /* D3DTOP_ADDSIGNED                 */  ARG1 | ARG2,
1917         /* D3DTOP_ADDSIGNED2X               */  ARG1 | ARG2,
1918         /* D3DTOP_SUBTRACT                  */  ARG1 | ARG2,
1919         /* D3DTOP_ADDSMOOTH                 */  ARG1 | ARG2,
1920         /* D3DTOP_BLENDDIFFUSEALPHA         */  ARG1 | ARG2,
1921         /* D3DTOP_BLENDTEXTUREALPHA         */  ARG1 | ARG2,
1922         /* D3DTOP_BLENDFACTORALPHA          */  ARG1 | ARG2,
1923         /* D3DTOP_BLENDTEXTUREALPHAPM       */  ARG1 | ARG2,
1924         /* D3DTOP_BLENDCURRENTALPHA         */  ARG1 | ARG2,
1925         /* D3DTOP_PREMODULATE               */  ARG1 | ARG2,
1926         /* D3DTOP_MODULATEALPHA_ADDCOLOR    */  ARG1 | ARG2,
1927         /* D3DTOP_MODULATECOLOR_ADDALPHA    */  ARG1 | ARG2,
1928         /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */  ARG1 | ARG2,
1929         /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */  ARG1 | ARG2,
1930         /* D3DTOP_BUMPENVMAP                */  ARG1 | ARG2,
1931         /* D3DTOP_BUMPENVMAPLUMINANCE       */  ARG1 | ARG2,
1932         /* D3DTOP_DOTPRODUCT3               */  ARG1 | ARG2,
1933         /* D3DTOP_MULTIPLYADD               */  ARG1 | ARG2 | ARG0,
1934         /* D3DTOP_LERP                      */  ARG1 | ARG2 | ARG0
1935     };
1936     unsigned int i;
1937     DWORD ttff;
1938     DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
1939
1940     for(i = 0; i < GL_LIMITS(texture_stages); i++) {
1941         IWineD3DBaseTextureImpl *texture;
1942         settings->op[i].padding = 0;
1943         if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
1944             settings->op[i].cop = WINED3DTOP_DISABLE;
1945             settings->op[i].aop = WINED3DTOP_DISABLE;
1946             settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
1947             settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
1948             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
1949             settings->op[i].dst = resultreg;
1950             settings->op[i].tex_type = tex_1d;
1951             settings->op[i].projected = proj_none;
1952             i++;
1953             break;
1954         }
1955
1956         texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
1957         if(texture) {
1958             settings->op[i].color_fixup = texture->baseTexture.shader_color_fixup;
1959             if(ignore_textype) {
1960                 settings->op[i].tex_type = tex_1d;
1961             } else {
1962                 switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
1963                     case GL_TEXTURE_1D:
1964                         settings->op[i].tex_type = tex_1d;
1965                         break;
1966                     case GL_TEXTURE_2D:
1967                         settings->op[i].tex_type = tex_2d;
1968                         break;
1969                     case GL_TEXTURE_3D:
1970                         settings->op[i].tex_type = tex_3d;
1971                         break;
1972                     case GL_TEXTURE_CUBE_MAP_ARB:
1973                         settings->op[i].tex_type = tex_cube;
1974                         break;
1975                     case GL_TEXTURE_RECTANGLE_ARB:
1976                         settings->op[i].tex_type = tex_rect;
1977                         break;
1978                 }
1979             }
1980         } else {
1981             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
1982             settings->op[i].tex_type = tex_1d;
1983         }
1984
1985         cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
1986         aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
1987
1988         carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
1989         carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
1990         carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
1991
1992         if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
1993                          carg1, carg2, carg0)) {
1994             carg0 = ARG_UNUSED;
1995             carg2 = ARG_UNUSED;
1996             carg1 = WINED3DTA_CURRENT;
1997             cop = WINED3DTOP_SELECTARG1;
1998         }
1999
2000         if(cop == WINED3DTOP_DOTPRODUCT3) {
2001             /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
2002              * the color result to the alpha component of the destination
2003              */
2004             aop = cop;
2005             aarg1 = carg1;
2006             aarg2 = carg2;
2007             aarg0 = carg0;
2008         } else {
2009             aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
2010             aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
2011             aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
2012         }
2013
2014         if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
2015         {
2016             UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
2017
2018             if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
2019             {
2020                 IWineD3DSurfaceImpl *surf;
2021                 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
2022
2023                 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT
2024                         && getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000)
2025                 {
2026                     if (aop == WINED3DTOP_DISABLE)
2027                     {
2028                        aarg1 = WINED3DTA_TEXTURE;
2029                        aop = WINED3DTOP_SELECTARG1;
2030                     }
2031                     else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
2032                     {
2033                         if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2034                         {
2035                             aarg2 = WINED3DTA_TEXTURE;
2036                             aop = WINED3DTOP_MODULATE;
2037                         }
2038                         else aarg1 = WINED3DTA_TEXTURE;
2039                     }
2040                     else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
2041                     {
2042                         if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
2043                         {
2044                             aarg1 = WINED3DTA_TEXTURE;
2045                             aop = WINED3DTOP_MODULATE;
2046                         }
2047                         else aarg2 = WINED3DTA_TEXTURE;
2048                     }
2049                 }
2050             }
2051         }
2052
2053         if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
2054            aarg1, aarg2, aarg0)) {
2055                aarg0 = ARG_UNUSED;
2056                aarg2 = ARG_UNUSED;
2057                aarg1 = WINED3DTA_CURRENT;
2058                aop = WINED3DTOP_SELECTARG1;
2059         }
2060
2061         if(carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE ||
2062            aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) {
2063             ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
2064             if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
2065                 settings->op[i].projected = proj_count3;
2066             } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
2067                 settings->op[i].projected = proj_count4;
2068             } else {
2069                 settings->op[i].projected = proj_none;
2070             }
2071         } else {
2072             settings->op[i].projected = proj_none;
2073         }
2074
2075         settings->op[i].cop = cop;
2076         settings->op[i].aop = aop;
2077         settings->op[i].carg0 = carg0;
2078         settings->op[i].carg1 = carg1;
2079         settings->op[i].carg2 = carg2;
2080         settings->op[i].aarg0 = aarg0;
2081         settings->op[i].aarg1 = aarg1;
2082         settings->op[i].aarg2 = aarg2;
2083
2084         if(stateblock->textureState[i][WINED3DTSS_RESULTARG] == WINED3DTA_TEMP) {
2085             settings->op[i].dst = tempreg;
2086         } else {
2087             settings->op[i].dst = resultreg;
2088         }
2089     }
2090
2091     /* Clear unsupported stages */
2092     for(; i < MAX_TEXTURES; i++) {
2093         memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
2094     }
2095
2096     if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
2097         settings->fog = FOG_OFF;
2098     } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
2099         if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
2100             settings->fog = FOG_LINEAR;
2101         } else {
2102             switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
2103                 case WINED3DFOG_NONE:
2104                 case WINED3DFOG_LINEAR:
2105                     settings->fog = FOG_LINEAR;
2106                     break;
2107                 case WINED3DFOG_EXP:
2108                     settings->fog = FOG_EXP;
2109                     break;
2110                 case WINED3DFOG_EXP2:
2111                     settings->fog = FOG_EXP2;
2112                     break;
2113             }
2114         }
2115     } else {
2116         switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
2117             case WINED3DFOG_LINEAR:
2118                 settings->fog = FOG_LINEAR;
2119                 break;
2120             case WINED3DFOG_EXP:
2121                 settings->fog = FOG_EXP;
2122                 break;
2123             case WINED3DFOG_EXP2:
2124                 settings->fog = FOG_EXP2;
2125                 break;
2126         }
2127     }
2128     if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
2129         settings->sRGB_write = 1;
2130     } else {
2131         settings->sRGB_write = 0;
2132     }
2133 }
2134 #undef GLINFO_LOCATION
2135
2136 const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
2137         const struct ffp_frag_settings *settings)
2138 {
2139     return (const struct ffp_frag_desc *)hash_table_get(fragment_shaders, settings);
2140 }
2141
2142 void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *desc) {
2143     struct ffp_frag_settings *key = HeapAlloc(GetProcessHeap(), 0, sizeof(*key));
2144     /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
2145      * whereas desc points to an extended structure with implementation specific parts.
2146      * Make a copy of the key because hash_table_put takes ownership of it
2147      */
2148     *key = desc->settings;
2149     hash_table_put(shaders, key, desc);
2150 }
2151
2152 /* Activates the texture dimension according to the bound D3D texture.
2153  * Does not care for the colorop or correct gl texture unit(when using nvrc)
2154  * Requires the caller to activate the correct unit before
2155  */
2156 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
2157 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2158     if(stateblock->textures[stage]) {
2159         switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
2160             case GL_TEXTURE_2D:
2161                 glDisable(GL_TEXTURE_3D);
2162                 checkGLcall("glDisable(GL_TEXTURE_3D)");
2163                 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2164                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2165                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2166                 }
2167                 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2168                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
2169                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2170                 }
2171                 glEnable(GL_TEXTURE_2D);
2172                 checkGLcall("glEnable(GL_TEXTURE_2D)");
2173                 break;
2174             case GL_TEXTURE_RECTANGLE_ARB:
2175                 glDisable(GL_TEXTURE_2D);
2176                 checkGLcall("glDisable(GL_TEXTURE_2D)");
2177                 glDisable(GL_TEXTURE_3D);
2178                 checkGLcall("glDisable(GL_TEXTURE_3D)");
2179                 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2180                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2181                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2182                 }
2183                 glEnable(GL_TEXTURE_RECTANGLE_ARB);
2184                 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
2185                 break;
2186             case GL_TEXTURE_3D:
2187                 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2188                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2189                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2190                 }
2191                 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2192                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
2193                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2194                 }
2195                 glDisable(GL_TEXTURE_2D);
2196                 checkGLcall("glDisable(GL_TEXTURE_2D)");
2197                 glEnable(GL_TEXTURE_3D);
2198                 checkGLcall("glEnable(GL_TEXTURE_3D)");
2199                 break;
2200             case GL_TEXTURE_CUBE_MAP_ARB:
2201                 glDisable(GL_TEXTURE_2D);
2202                 checkGLcall("glDisable(GL_TEXTURE_2D)");
2203                 glDisable(GL_TEXTURE_3D);
2204                 checkGLcall("glDisable(GL_TEXTURE_3D)");
2205                 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2206                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
2207                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2208                 }
2209                 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2210                 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
2211               break;
2212         }
2213     } else {
2214         glEnable(GL_TEXTURE_2D);
2215         checkGLcall("glEnable(GL_TEXTURE_2D)");
2216         glDisable(GL_TEXTURE_3D);
2217         checkGLcall("glDisable(GL_TEXTURE_3D)");
2218         if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2219             glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2220             checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2221         }
2222         if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2223             glDisable(GL_TEXTURE_RECTANGLE_ARB);
2224             checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2225         }
2226         /* Binding textures is done by samplers. A dummy texture will be bound */
2227     }
2228 }
2229
2230 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2231     DWORD sampler = state - STATE_SAMPLER(0);
2232     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2233
2234     /* No need to enable / disable anything here for unused samplers. The tex_colorop
2235     * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
2236     * will take care of this business
2237     */
2238     if(mapped_stage == -1 || mapped_stage >= GL_LIMITS(textures)) return;
2239     if(sampler >= stateblock->lowest_disabled_stage) return;
2240     if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
2241
2242     texture_activate_dimensions(sampler, stateblock, context);
2243 }
2244 #undef GLINFO_LOCATION
2245
2246 unsigned int ffp_frag_program_key_hash(const void *key)
2247 {
2248     const struct ffp_frag_settings *k = key;
2249     unsigned int hash = 0, i;
2250     const DWORD *blob;
2251
2252     /* This takes the texture op settings of stage 0 and 1 into account.
2253      * how exactly depends on the memory laybout of the compiler, but it
2254      * should not matter too much. Stages > 1 are used rarely, so there's
2255      * no need to process them. Even if they're used it is likely that
2256      * the ffp setup has distinct stage 0 and 1 settings.
2257      */
2258     for(i = 0; i < 2; i++) {
2259         blob = (const DWORD *)&k->op[i];
2260         hash ^= blob[0] ^ blob[1];
2261     }
2262
2263     hash += ~(hash << 15);
2264     hash ^=  (hash >> 10);
2265     hash +=  (hash << 3);
2266     hash ^=  (hash >> 6);
2267     hash += ~(hash << 11);
2268     hash ^=  (hash >> 16);
2269
2270     return hash;
2271 }
2272
2273 BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb)
2274 {
2275     const struct ffp_frag_settings *ka = keya;
2276     const struct ffp_frag_settings *kb = keyb;
2277
2278     return memcmp(ka, kb, sizeof(*ka)) == 0;
2279 }
2280
2281 UINT wined3d_log2i(UINT32 x)
2282 {
2283     static const BYTE l[] =
2284     {
2285         0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
2286         4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2287         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2288         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2289         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2290         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2291         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2292         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
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         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2298         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2299         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2300         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2301     };
2302     UINT32 i;
2303
2304     return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
2305 }