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