wined3d: Add gamma linerization support for D3DFMT_A4R4G4B4.
[wine.git] / dlls / wined3d / utils.c
blobd592bc46a81b3c5c3358c563d581ed98e4b062ad
1 /*
2 * Utility functions for the WineD3D Library
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-2007 Henri Verbeet
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "config.h"
26 #include "wined3d_private.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
30 #define GLINFO_LOCATION This->adapter->gl_info
32 /*****************************************************************************
33 * Pixel format array
35 static const PixelFormatDesc formats[] = {
36 /*{WINED3DFORMAT ,alphamask ,redmask ,greenmask ,bluemask ,bpp ,isFourcc ,internal ,srgbInternal ,format ,type }*/
37 {WINED3DFMT_UNKNOWN ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,0 ,0 ,0 ,0 },
38 /* FourCC formats, kept here to have WINED3DFMT_R8G8B8(=20) at position 20 */
39 {WINED3DFMT_UYVY ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 ,0 },
40 {WINED3DFMT_YUY2 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 ,0 },
41 {WINED3DFMT_DXT1 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
42 {WINED3DFMT_DXT2 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
43 {WINED3DFMT_DXT3 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
44 {WINED3DFMT_DXT4 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
45 {WINED3DFMT_DXT5 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
46 {WINED3DFMT_MULTI2_ARGB8,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 ,0 },
47 {WINED3DFMT_G8R8_G8B8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 ,0 },
48 {WINED3DFMT_R8G8_B8G8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 ,0 },
49 /* IEEE formats */
50 {WINED3DFMT_R32F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_RGB32F_ARB ,GL_RGB32F_ARB ,GL_RED ,GL_FLOAT },
51 {WINED3DFMT_G32R32F ,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,0 ,0 ,0 ,0 },
52 {WINED3DFMT_A32B32G32R32F,0x0 ,0x0 ,0x0 ,0x0 ,16 ,FALSE ,GL_RGBA32F_ARB ,GL_RGBA32F_ARB ,GL_RGBA ,GL_FLOAT },
53 /* Hmm? */
54 {WINED3DFMT_CxV8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,0 ,0 ,0 ,0 },
55 /* Float */
56 {WINED3DFMT_R16F ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_RGB16F_ARB ,GL_RGB16F_ARB ,GL_RED ,GL_HALF_FLOAT_ARB },
57 {WINED3DFMT_G16R16F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 ,0 },
58 {WINED3DFMT_A16B16G16R16F,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,GL_RGBA16F_ARB ,GL_RGBA16F_ARB ,GL_RGBA ,GL_HALF_FLOAT_ARB },
59 /* Palettized formats */
60 {WINED3DFMT_A8P8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,0 ,0 ,0 ,0 },
61 {WINED3DFMT_P8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX ,GL_UNSIGNED_BYTE },
62 /* Standard ARGB formats. Keep WINED3DFMT_R8G8B8(=20) at position 20 */
63 {WINED3DFMT_R8G8B8 ,0x0 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,3 ,FALSE ,GL_RGB8 ,GL_RGB8 ,GL_BGR ,GL_UNSIGNED_BYTE },
64 {WINED3DFMT_A8R8G8B8 ,0xff000000 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,FALSE ,GL_RGBA8 ,GL_SRGB8_ALPHA8_EXT ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
65 {WINED3DFMT_X8R8G8B8 ,0x0 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,FALSE ,GL_RGB8 ,GL_SRGB8_EXT ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
66 {WINED3DFMT_R5G6B5 ,0x0 ,0x0000F800 ,0x000007e0 ,0x0000001f ,2 ,FALSE ,GL_RGB5 ,GL_RGB5 ,GL_RGB ,GL_UNSIGNED_SHORT_5_6_5 },
67 {WINED3DFMT_X1R5G5B5 ,0x0 ,0x00007c00 ,0x000003e0 ,0x0000001f ,2 ,FALSE ,GL_RGB5_A1 ,GL_RGB5_A1 ,GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV },
68 {WINED3DFMT_A1R5G5B5 ,0x00008000 ,0x00007c00 ,0x000003e0 ,0x0000001f ,2 ,FALSE ,GL_RGB5_A1 ,GL_RGB5_A1 ,GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV },
69 {WINED3DFMT_A4R4G4B4 ,0x0000f000 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,FALSE ,GL_RGBA4 ,GL_SRGB8_ALPHA8_EXT ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
70 {WINED3DFMT_R3G3B2 ,0x0 ,0x000000e0 ,0x0000001c ,0x00000003 ,1 ,FALSE ,GL_R3_G3_B2 ,GL_R3_G3_B2 ,GL_RGB ,GL_UNSIGNED_BYTE_2_3_3_REV },
71 {WINED3DFMT_A8 ,0x000000ff ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,GL_ALPHA8 ,GL_ALPHA8 ,GL_ALPHA ,GL_UNSIGNED_BYTE },
72 {WINED3DFMT_A8R3G3B2 ,0x0000ff00 ,0x000000e0 ,0x0000001c ,0x00000003 ,2 ,FALSE ,0 ,0 ,0 ,0 },
73 {WINED3DFMT_X4R4G4B4 ,0x0 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,FALSE ,GL_RGB4 ,GL_RGB4 ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
74 {WINED3DFMT_A2B10G10R10 ,0xb0000000 ,0x000003ff ,0x000ffc00 ,0x3ff00000 ,4 ,FALSE ,GL_RGB ,GL_RGB ,GL_RGBA ,GL_UNSIGNED_INT_2_10_10_10_REV },
75 {WINED3DFMT_A8B8G8R8 ,0xff000000 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,FALSE ,GL_RGBA8 ,GL_RGBA8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
76 {WINED3DFMT_X8B8G8R8 ,0x0 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,FALSE ,GL_RGB8 ,GL_RGB8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
77 {WINED3DFMT_G16R16 ,0x0 ,0x0000ffff ,0xffff0000 ,0x0 ,4 ,FALSE ,0 ,0 ,0 ,0 },
78 {WINED3DFMT_A2R10G10B10 ,0xb0000000 ,0x3ff00000 ,0x000ffc00 ,0x000003ff ,4 ,FALSE ,GL_RGBA ,GL_RGBA ,GL_BGRA ,GL_UNSIGNED_INT_2_10_10_10_REV },
79 {WINED3DFMT_A16B16G16R16,0x0 ,0x0000ffff ,0xffff0000 ,0x0 ,8 ,FALSE ,GL_RGBA16_EXT ,GL_RGBA16_EXT ,GL_RGBA ,GL_UNSIGNED_SHORT },
80 /* Luminance */
81 {WINED3DFMT_L8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,GL_LUMINANCE8 ,GL_SLUMINANCE8_EXT ,GL_LUMINANCE ,GL_UNSIGNED_BYTE },
82 {WINED3DFMT_A8L8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_LUMINANCE8_ALPHA8 ,GL_SLUMINANCE8_ALPHA8_EXT ,GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE },
83 {WINED3DFMT_A4L4 ,0x000000f0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,GL_LUMINANCE4_ALPHA4 ,GL_LUMINANCE4_ALPHA4 ,GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE },
84 /* Bump mapping stuff */
85 {WINED3DFMT_V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_DSDT8_NV ,GL_DSDT8_NV ,GL_DSDT_NV ,GL_BYTE },
86 {WINED3DFMT_L6V5U5 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX ,GL_UNSIGNED_SHORT_5_5_5_1 },
87 {WINED3DFMT_X8L8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT_MAG_INTENSITY_NV ,GL_BYTE },
88 {WINED3DFMT_Q8W8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_SIGNED_RGBA8_NV ,GL_SIGNED_RGBA8_NV ,GL_RGBA ,GL_BYTE },
89 {WINED3DFMT_V16U16 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_SIGNED_HILO16_NV ,GL_SIGNED_HILO16_NV ,GL_HILO_NV ,GL_SHORT },
90 {WINED3DFMT_W11V11U10 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 ,0 },
91 {WINED3DFMT_A2W10V10U10 ,0xb0000000 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 ,0 },
92 /* Depth stencil formats */
93 {WINED3DFMT_D16_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT },
94 {WINED3DFMT_D32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
95 {WINED3DFMT_D15S1 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT },
96 {WINED3DFMT_D24S8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
97 {WINED3DFMT_D24X8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT,GL_UNSIGNED_INT },
98 {WINED3DFMT_D24X4S4 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT,GL_UNSIGNED_INT },
99 {WINED3DFMT_D16 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT,GL_UNSIGNED_SHORT },
100 {WINED3DFMT_L16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_LUMINANCE16_EXT ,GL_LUMINANCE16_EXT ,GL_LUMINANCE ,GL_UNSIGNED_SHORT },
101 {WINED3DFMT_D32F_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT ,GL_FLOAT },
102 {WINED3DFMT_D24FS8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_FLOAT },
103 /* Is this a vertex buffer? */
104 {WINED3DFMT_VERTEXDATA ,0x0 ,0x0 ,0x0 ,0x0 ,0 ,FALSE ,0 ,0 ,0 ,0 },
105 {WINED3DFMT_INDEX16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,0 ,0 ,0 ,0 },
106 {WINED3DFMT_INDEX32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 ,0 },
107 {WINED3DFMT_Q16W16V16U16,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,GL_COLOR_INDEX ,GL_COLOR_INDEX ,GL_COLOR_INDEX ,GL_UNSIGNED_SHORT }
110 const PixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt)
112 /* First check if the format is at the position of its value.
113 * This will catch the argb formats before the loop is entered
115 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
116 return &formats[fmt];
117 } else {
118 unsigned int i;
119 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
120 if(formats[i].format == fmt) {
121 return &formats[i];
125 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
126 if(fmt == WINED3DFMT_UNKNOWN) {
127 ERR("Format table corrupt - Can't find WINED3DFMT_UNKNOWN\n");
128 return NULL;
130 /* Get the caller a valid pointer */
131 return getFormatDescEntry(WINED3DFMT_UNKNOWN);
134 /*****************************************************************************
135 * Trace formatting of useful values
137 const char* debug_d3dformat(WINED3DFORMAT fmt) {
138 switch (fmt) {
139 #define FMT_TO_STR(fmt) case fmt: return #fmt
140 FMT_TO_STR(WINED3DFMT_UNKNOWN);
141 FMT_TO_STR(WINED3DFMT_R8G8B8);
142 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
143 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
144 FMT_TO_STR(WINED3DFMT_R5G6B5);
145 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
146 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
147 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
148 FMT_TO_STR(WINED3DFMT_R3G3B2);
149 FMT_TO_STR(WINED3DFMT_A8);
150 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
151 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
152 FMT_TO_STR(WINED3DFMT_A2B10G10R10);
153 FMT_TO_STR(WINED3DFMT_A8B8G8R8);
154 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
155 FMT_TO_STR(WINED3DFMT_G16R16);
156 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
157 FMT_TO_STR(WINED3DFMT_A16B16G16R16);
158 FMT_TO_STR(WINED3DFMT_A8P8);
159 FMT_TO_STR(WINED3DFMT_P8);
160 FMT_TO_STR(WINED3DFMT_L8);
161 FMT_TO_STR(WINED3DFMT_A8L8);
162 FMT_TO_STR(WINED3DFMT_A4L4);
163 FMT_TO_STR(WINED3DFMT_V8U8);
164 FMT_TO_STR(WINED3DFMT_L6V5U5);
165 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
166 FMT_TO_STR(WINED3DFMT_Q8W8V8U8);
167 FMT_TO_STR(WINED3DFMT_V16U16);
168 FMT_TO_STR(WINED3DFMT_W11V11U10);
169 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
170 FMT_TO_STR(WINED3DFMT_UYVY);
171 FMT_TO_STR(WINED3DFMT_YUY2);
172 FMT_TO_STR(WINED3DFMT_DXT1);
173 FMT_TO_STR(WINED3DFMT_DXT2);
174 FMT_TO_STR(WINED3DFMT_DXT3);
175 FMT_TO_STR(WINED3DFMT_DXT4);
176 FMT_TO_STR(WINED3DFMT_DXT5);
177 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
178 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
179 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
180 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
181 FMT_TO_STR(WINED3DFMT_D32);
182 FMT_TO_STR(WINED3DFMT_D15S1);
183 FMT_TO_STR(WINED3DFMT_D24S8);
184 FMT_TO_STR(WINED3DFMT_D24X8);
185 FMT_TO_STR(WINED3DFMT_D24X4S4);
186 FMT_TO_STR(WINED3DFMT_D16);
187 FMT_TO_STR(WINED3DFMT_L16);
188 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
189 FMT_TO_STR(WINED3DFMT_D24FS8);
190 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
191 FMT_TO_STR(WINED3DFMT_INDEX16);
192 FMT_TO_STR(WINED3DFMT_INDEX32);
193 FMT_TO_STR(WINED3DFMT_Q16W16V16U16);
194 FMT_TO_STR(WINED3DFMT_R16F);
195 FMT_TO_STR(WINED3DFMT_G16R16F);
196 FMT_TO_STR(WINED3DFMT_A16B16G16R16F);
197 FMT_TO_STR(WINED3DFMT_R32F);
198 FMT_TO_STR(WINED3DFMT_G32R32F);
199 FMT_TO_STR(WINED3DFMT_A32B32G32R32F);
200 FMT_TO_STR(WINED3DFMT_CxV8U8);
201 #undef FMT_TO_STR
202 default:
204 char fourcc[5];
205 fourcc[0] = (char)(fmt);
206 fourcc[1] = (char)(fmt >> 8);
207 fourcc[2] = (char)(fmt >> 16);
208 fourcc[3] = (char)(fmt >> 24);
209 fourcc[4] = 0;
210 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
211 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
212 else
213 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
215 return "unrecognized";
219 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
220 switch (devtype) {
221 #define DEVTYPE_TO_STR(dev) case dev: return #dev
222 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
223 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
224 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
225 #undef DEVTYPE_TO_STR
226 default:
227 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
228 return "unrecognized";
232 const char* debug_d3dusage(DWORD usage) {
233 switch (usage & WINED3DUSAGE_MASK) {
234 #define WINED3DUSAGE_TO_STR(u) case u: return #u
235 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
236 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
237 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
238 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
239 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
240 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
241 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
242 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
243 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
244 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
245 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
246 #undef WINED3DUSAGE_TO_STR
247 case 0: return "none";
248 default:
249 FIXME("Unrecognized %u Usage!\n", usage);
250 return "unrecognized";
254 const char* debug_d3dusagequery(DWORD usagequery) {
255 switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
256 #define WINED3DUSAGEQUERY_TO_STR(u) case u: return #u
257 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
258 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
259 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
260 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
261 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
262 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
263 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
264 #undef WINED3DUSAGEQUERY_TO_STR
265 case 0: return "none";
266 default:
267 FIXME("Unrecognized %u Usage Query!\n", usagequery);
268 return "unrecognized";
272 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
273 switch (method) {
274 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
275 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
276 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
277 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
278 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
279 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
280 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
281 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
282 #undef WINED3DDECLMETHOD_TO_STR
283 default:
284 FIXME("Unrecognized %u declaration method!\n", method);
285 return "unrecognized";
289 const char* debug_d3ddecltype(WINED3DDECLTYPE type) {
290 switch (type) {
291 #define WINED3DDECLTYPE_TO_STR(u) case u: return #u
292 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT1);
293 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT2);
294 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT3);
295 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT4);
296 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_D3DCOLOR);
297 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4);
298 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2);
299 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4);
300 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4N);
301 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2N);
302 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4N);
303 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT2N);
304 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT4N);
305 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UDEC3);
306 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_DEC3N);
307 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_2);
308 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_4);
309 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UNUSED);
310 #undef WINED3DDECLTYPE_TO_STR
311 default:
312 FIXME("Unrecognized %u declaration type!\n", type);
313 return "unrecognized";
317 const char* debug_d3ddeclusage(BYTE usage) {
318 switch (usage) {
319 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
320 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
321 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
322 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
323 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
324 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
325 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
326 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
327 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
328 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
329 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
330 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
331 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
332 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
333 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
334 #undef WINED3DDECLUSAGE_TO_STR
335 default:
336 FIXME("Unrecognized %u declaration usage!\n", usage);
337 return "unrecognized";
341 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
342 switch (res) {
343 #define RES_TO_STR(res) case res: return #res;
344 RES_TO_STR(WINED3DRTYPE_SURFACE);
345 RES_TO_STR(WINED3DRTYPE_VOLUME);
346 RES_TO_STR(WINED3DRTYPE_TEXTURE);
347 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
348 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
349 RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER);
350 RES_TO_STR(WINED3DRTYPE_INDEXBUFFER);
351 #undef RES_TO_STR
352 default:
353 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
354 return "unrecognized";
358 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
359 switch (PrimitiveType) {
360 #define PRIM_TO_STR(prim) case prim: return #prim;
361 PRIM_TO_STR(WINED3DPT_POINTLIST);
362 PRIM_TO_STR(WINED3DPT_LINELIST);
363 PRIM_TO_STR(WINED3DPT_LINESTRIP);
364 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
365 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
366 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
367 #undef PRIM_TO_STR
368 default:
369 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
370 return "unrecognized";
374 const char* debug_d3drenderstate(DWORD state) {
375 switch (state) {
376 #define D3DSTATE_TO_STR(u) case u: return #u
377 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
378 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
379 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
380 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
381 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
382 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
383 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
384 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
385 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
386 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
387 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
388 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
389 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
390 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
391 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
392 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
393 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
394 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
395 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
396 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
397 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
398 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
399 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
400 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
401 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
402 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
403 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
404 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
405 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
406 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
407 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
408 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
409 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
410 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
411 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
412 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
413 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
414 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
415 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
416 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
417 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
418 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
419 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
420 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
421 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
422 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
423 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
424 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
425 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
426 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
427 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
428 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
429 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
430 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
431 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
432 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
433 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
434 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
435 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
436 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
437 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
438 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
439 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
440 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
441 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
442 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
443 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
444 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
445 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
446 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
447 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
448 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
449 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
450 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
451 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
452 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
453 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
454 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
455 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
456 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
457 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
458 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
459 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
460 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
461 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
462 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
463 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
464 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
465 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
466 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
467 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
468 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
469 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
470 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
471 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
472 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
473 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
474 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
475 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
476 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
477 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
478 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
479 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
480 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
481 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
482 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
483 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
484 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
485 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
486 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
487 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
488 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
489 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
490 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
491 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
492 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
493 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
494 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
495 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
496 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
497 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
498 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
499 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
500 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
501 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
502 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
503 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
504 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
505 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
506 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
507 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
508 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
509 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
510 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
511 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
512 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
513 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
514 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
515 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
516 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
517 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
518 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
519 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
520 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
521 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
522 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
523 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
524 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
525 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
526 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
527 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
528 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
529 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
530 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
531 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
532 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
533 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
534 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
535 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
536 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
537 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
538 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
539 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
540 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
541 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
542 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
543 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
544 #undef D3DSTATE_TO_STR
545 default:
546 FIXME("Unrecognized %u render state!\n", state);
547 return "unrecognized";
551 const char* debug_d3dsamplerstate(DWORD state) {
552 switch (state) {
553 #define D3DSTATE_TO_STR(u) case u: return #u
554 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
555 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
556 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
557 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
558 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
559 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
560 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
561 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
562 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
563 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
564 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
565 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
566 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
567 #undef D3DSTATE_TO_STR
568 default:
569 FIXME("Unrecognized %u sampler state!\n", state);
570 return "unrecognized";
574 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
575 switch (filter_type) {
576 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
577 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
578 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
579 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
580 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
581 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
582 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
583 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
584 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
585 #undef D3DTEXTUREFILTERTYPE_TO_STR
586 default:
587 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
588 return "unrecognized";
592 const char* debug_d3dtexturestate(DWORD state) {
593 switch (state) {
594 #define D3DSTATE_TO_STR(u) case u: return #u
595 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
596 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
597 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
598 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
599 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
600 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
601 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
602 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
603 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
604 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
605 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
606 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
607 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
608 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
609 D3DSTATE_TO_STR(WINED3DTSS_ADDRESSW );
610 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
611 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
612 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
613 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
614 #undef D3DSTATE_TO_STR
615 case 12:
616 /* Note WINED3DTSS are not consecutive, so skip these */
617 return "unused";
618 break;
619 default:
620 FIXME("Unrecognized %u texture state!\n", state);
621 return "unrecognized";
625 static const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
626 switch (d3dtop) {
627 #define D3DTOP_TO_STR(u) case u: return #u
628 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
629 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
630 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
631 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
632 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
633 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
634 D3DTOP_TO_STR(WINED3DTOP_ADD);
635 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
636 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
637 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
638 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
639 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
640 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
641 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
642 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
643 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
644 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
645 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
646 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
647 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
648 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
649 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
650 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
651 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
652 D3DTOP_TO_STR(WINED3DTOP_LERP);
653 #undef D3DTOP_TO_STR
654 default:
655 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
656 return "unrecognized";
660 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
661 switch (tstype) {
662 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
663 TSTYPE_TO_STR(WINED3DTS_VIEW);
664 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
665 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
666 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
667 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
668 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
669 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
670 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
671 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
672 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
673 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
674 #undef TSTYPE_TO_STR
675 default:
676 if (tstype > 256 && tstype < 512) {
677 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
678 return ("WINED3DTS_WORLDMATRIX > 0");
680 FIXME("Unrecognized %u WINED3DTS\n", tstype);
681 return "unrecognized";
685 const char* debug_d3dpool(WINED3DPOOL Pool) {
686 switch (Pool) {
687 #define POOL_TO_STR(p) case p: return #p;
688 POOL_TO_STR(WINED3DPOOL_DEFAULT);
689 POOL_TO_STR(WINED3DPOOL_MANAGED);
690 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
691 POOL_TO_STR(WINED3DPOOL_SCRATCH);
692 #undef POOL_TO_STR
693 default:
694 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
695 return "unrecognized";
699 const char *debug_fbostatus(GLenum status) {
700 switch(status) {
701 #define FBOSTATUS_TO_STR(u) case u: return #u
702 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
703 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
704 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
705 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
706 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
707 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
708 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
709 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
710 #undef FBOSTATUS_TO_STR
711 default:
712 FIXME("Unrecognied FBO status 0x%08x\n", status);
713 return "unrecognized";
717 const char *debug_glerror(GLenum error) {
718 switch(error) {
719 #define GLERROR_TO_STR(u) case u: return #u
720 GLERROR_TO_STR(GL_NO_ERROR);
721 GLERROR_TO_STR(GL_INVALID_ENUM);
722 GLERROR_TO_STR(GL_INVALID_VALUE);
723 GLERROR_TO_STR(GL_INVALID_OPERATION);
724 GLERROR_TO_STR(GL_STACK_OVERFLOW);
725 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
726 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
727 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
728 #undef GLERROR_TO_STR
729 default:
730 FIXME("Unrecognied GL error 0x%08x\n", error);
731 return "unrecognized";
735 /*****************************************************************************
736 * Useful functions mapping GL <-> D3D values
738 GLenum StencilOp(DWORD op) {
739 switch(op) {
740 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
741 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
742 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
743 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
744 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
745 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
746 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
747 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
748 default:
749 FIXME("Unrecognized stencil op %d\n", op);
750 return GL_KEEP;
754 GLenum CompareFunc(DWORD func) {
755 switch ((WINED3DCMPFUNC)func) {
756 case WINED3DCMP_NEVER : return GL_NEVER;
757 case WINED3DCMP_LESS : return GL_LESS;
758 case WINED3DCMP_EQUAL : return GL_EQUAL;
759 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
760 case WINED3DCMP_GREATER : return GL_GREATER;
761 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
762 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
763 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
764 default:
765 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
766 return 0;
770 static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) {
771 switch (d3dta) {
772 case WINED3DTA_DIFFUSE:
773 return GL_PRIMARY_COLOR_NV;
775 case WINED3DTA_CURRENT:
776 if (stage) return GL_SPARE0_NV;
777 else return GL_PRIMARY_COLOR_NV;
779 case WINED3DTA_TEXTURE:
780 if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx;
781 else return GL_PRIMARY_COLOR_NV;
783 case WINED3DTA_TFACTOR:
784 return GL_CONSTANT_COLOR0_NV;
786 case WINED3DTA_SPECULAR:
787 return GL_SECONDARY_COLOR_NV;
789 case WINED3DTA_TEMP:
790 /* TODO: Support WINED3DTSS_RESULTARG */
791 FIXME("WINED3DTA_TEMP, not properly supported.\n");
792 return GL_SPARE1_NV;
794 case WINED3DTA_CONSTANT:
795 /* TODO: Support per stage constants (WINED3DTSS_CONSTANT, NV_register_combiners2) */
796 FIXME("WINED3DTA_CONSTANT, not properly supported.\n");
797 return GL_CONSTANT_COLOR1_NV;
799 default:
800 FIXME("Unrecognized texture arg %#x\n", d3dta);
801 return GL_TEXTURE;
805 static GLenum invert_mapping(GLenum mapping) {
806 if (mapping == GL_UNSIGNED_INVERT_NV) return GL_SIGNED_IDENTITY_NV;
807 else if (mapping == GL_SIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV;
809 FIXME("Unhandled mapping %#x\n", mapping);
810 return mapping;
813 static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) {
814 /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should
815 * be used. */
816 if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV;
817 else *mapping = GL_SIGNED_IDENTITY_NV;
819 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input
820 * should be used for all input components. */
821 if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA;
822 else *component_usage = GL_RGB;
824 *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx);
827 typedef struct {
828 GLenum input[3];
829 GLenum mapping[3];
830 GLenum component_usage[3];
831 } tex_op_args;
833 static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
834 if (op == WINED3DTOP_DISABLE) return FALSE;
835 if (This->stateBlock->textures[stage]) return FALSE;
837 if (arg1 == WINED3DTA_TEXTURE && op != WINED3DTOP_SELECTARG2) return TRUE;
838 if (arg2 == WINED3DTA_TEXTURE && op != WINED3DTOP_SELECTARG1) return TRUE;
839 if (arg3 == WINED3DTA_TEXTURE && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
841 return FALSE;
844 void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx) {
845 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface;
846 tex_op_args tex_op_args = {{0}, {0}, {0}};
847 GLenum portion = is_alpha ? GL_ALPHA : GL_RGB;
848 GLenum target = GL_COMBINER0_NV + stage;
850 TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
851 stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx);
853 /* If a texture stage references an invalid texture unit the stage just
854 * passes through the result from the previous stage */
855 if (is_invalid_op(This, stage, op, arg1, arg2, arg3)) {
856 arg1 = WINED3DTA_CURRENT;
857 op = WINED3DTOP_SELECTARG1;
860 get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0],
861 &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx);
862 get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1],
863 &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx);
864 get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2],
865 &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx);
868 /* This is called by a state handler which has the gl lock held and a context for the thread */
869 switch(op)
871 case WINED3DTOP_DISABLE:
872 /* Only for alpha */
873 if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n");
874 /* Input, prev_alpha*1 */
875 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
876 GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
877 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
878 GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
880 /* Output */
881 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
882 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
883 break;
885 case WINED3DTOP_SELECTARG1:
886 case WINED3DTOP_SELECTARG2:
887 /* Input, arg*1 */
888 if (op == WINED3DTOP_SELECTARG1) {
889 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
890 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
891 } else {
892 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
893 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
895 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
896 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
898 /* Output */
899 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
900 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
901 break;
903 case WINED3DTOP_MODULATE:
904 case WINED3DTOP_MODULATE2X:
905 case WINED3DTOP_MODULATE4X:
906 /* Input, arg1*arg2 */
907 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
908 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
909 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
910 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
912 /* Output */
913 if (op == WINED3DTOP_MODULATE) {
914 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
915 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
916 } else if (op == WINED3DTOP_MODULATE2X) {
917 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
918 GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
919 } else if (op == WINED3DTOP_MODULATE4X) {
920 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
921 GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
923 break;
925 case WINED3DTOP_ADD:
926 case WINED3DTOP_ADDSIGNED:
927 case WINED3DTOP_ADDSIGNED2X:
928 /* Input, arg1*1+arg2*1 */
929 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
930 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
931 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
932 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
933 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
934 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
935 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
936 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
938 /* Output */
939 if (op == WINED3DTOP_ADD) {
940 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
941 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
942 } else if (op == WINED3DTOP_ADDSIGNED) {
943 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
944 GL_SPARE0_NV, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
945 } else if (op == WINED3DTOP_ADDSIGNED2X) {
946 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
947 GL_SPARE0_NV, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
949 break;
951 case WINED3DTOP_SUBTRACT:
952 /* Input, arg1*1+-arg2*1 */
953 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
954 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
955 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
956 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
957 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
958 tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1]));
959 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
960 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
962 /* Output */
963 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
964 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
965 break;
967 case WINED3DTOP_ADDSMOOTH:
968 /* Input, arg1*1+(1-arg1)*arg2 */
969 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
970 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
971 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
972 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
973 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
974 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
975 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
976 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
978 /* Output */
979 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
980 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
981 break;
983 case WINED3DTOP_BLENDDIFFUSEALPHA:
984 case WINED3DTOP_BLENDTEXTUREALPHA:
985 case WINED3DTOP_BLENDFACTORALPHA:
986 case WINED3DTOP_BLENDTEXTUREALPHAPM:
987 case WINED3DTOP_BLENDCURRENTALPHA:
989 GLenum alpha_src = GL_PRIMARY_COLOR_NV;
990 if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx);
991 else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
992 else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx);
993 else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
994 else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx);
995 else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op));
997 /* Input, arg1*alpha_src+arg2*(1-alpha_src) */
998 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
999 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1000 if (op == WINED3DTOP_BLENDTEXTUREALPHAPM)
1002 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1003 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1004 } else {
1005 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1006 alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
1008 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1009 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1010 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1011 alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
1013 /* Output */
1014 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1015 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1016 break;
1019 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1020 /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */
1021 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n");
1022 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1023 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1024 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1025 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1026 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1027 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1028 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1029 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1031 /* Output */
1032 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1033 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1034 break;
1036 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1037 /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */
1038 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n");
1039 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1040 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1041 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1042 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1043 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1044 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1045 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1046 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1048 /* Output */
1049 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1050 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1051 break;
1053 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1054 /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */
1055 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n");
1056 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1057 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA));
1058 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1059 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1060 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1061 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1062 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1063 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1065 /* Output */
1066 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1067 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1068 break;
1070 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1071 /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */
1072 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n");
1073 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1074 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1075 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1076 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1077 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1078 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1079 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1080 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1082 /* Output */
1083 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1084 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1085 break;
1087 case WINED3DTOP_DOTPRODUCT3:
1088 /* Input, arg1 . arg2 */
1089 /* FIXME: DX7 uses a different calculation? */
1090 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1091 tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0]));
1092 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1093 tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1]));
1095 /* Output */
1096 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1097 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE));
1098 break;
1100 case WINED3DTOP_MULTIPLYADD:
1101 /* Input, arg1*1+arg2*arg3 */
1102 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1103 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1104 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1105 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1106 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1107 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1108 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1109 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1111 /* Output */
1112 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1113 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1114 break;
1116 case WINED3DTOP_LERP:
1117 /* Input, arg1*arg2+(1-arg1)*arg3 */
1118 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1119 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1120 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1121 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1122 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1123 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1124 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1125 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1127 /* Output */
1128 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1129 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1130 break;
1132 case WINED3DTOP_BUMPENVMAPLUMINANCE:
1133 case WINED3DTOP_BUMPENVMAP:
1134 if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
1135 /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to
1136 * perform bump mapping and source from the current stage. Pretty much a SELECTARG2.
1137 * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1
1138 * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the next stage
1140 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1141 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1142 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1143 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1144 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1145 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1146 break;
1149 default:
1150 FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1151 stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
1154 checkGLcall("set_tex_op_nvrc()\n");
1158 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
1159 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
1160 * input should be used for all input components. The WINED3DTA_COMPLEMENT
1161 * flag specifies the complement of the input should be used. */
1162 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
1163 BOOL complement = arg & WINED3DTA_COMPLEMENT;
1165 /* Calculate the operand */
1166 if (complement) {
1167 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
1168 else *operand = GL_ONE_MINUS_SRC_COLOR;
1169 } else {
1170 if (from_alpha) *operand = GL_SRC_ALPHA;
1171 else *operand = GL_SRC_COLOR;
1174 /* Calculate the source */
1175 switch (arg & WINED3DTA_SELECTMASK) {
1176 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
1177 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
1178 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
1179 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
1180 case WINED3DTA_SPECULAR:
1182 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
1183 * 'Secondary color' and isn't supported until base GL supports it
1184 * There is no concept of temp registers as far as I can tell
1186 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
1187 *source = GL_TEXTURE;
1188 break;
1189 default:
1190 FIXME("Unrecognized texture arg %#x\n", arg);
1191 *source = GL_TEXTURE;
1192 break;
1196 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
1197 #if defined (GL_VERSION_1_3)
1198 # define useext(A) A
1199 # define combine_ext 1
1200 #elif defined (GL_EXT_texture_env_combine)
1201 # define useext(A) A##_EXT
1202 # define combine_ext 1
1203 #elif defined (GL_ARB_texture_env_combine)
1204 # define useext(A) A##_ARB
1205 # define combine_ext 1
1206 #else
1207 # undef combine_ext
1208 #endif
1210 #if !defined(combine_ext)
1211 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1213 FIXME("Requires opengl combine extensions to work\n");
1214 return;
1216 #else
1217 /* Setup the texture operations texture stage states */
1218 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1220 GLenum src1, src2, src3;
1221 GLenum opr1, opr2, opr3;
1222 GLenum comb_target;
1223 GLenum src0_target, src1_target, src2_target;
1224 GLenum opr0_target, opr1_target, opr2_target;
1225 GLenum scal_target;
1226 GLenum opr=0, invopr, src3_target, opr3_target;
1227 BOOL Handled = FALSE;
1228 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
1230 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
1232 /* This is called by a state handler which has the gl lock held and a context for the thread */
1234 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
1235 the form (a1 <operation> a2). However, some of the more complex operations
1236 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
1237 in a third parameter called a0. Therefore these are operations of the form
1238 a0 <operation> a1 <operation> a2, ie the new parameter goes to the front.
1240 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
1241 functions below, expect their syntax to differ slightly to those listed in the
1242 manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
1243 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
1245 if (isAlpha) {
1246 comb_target = useext(GL_COMBINE_ALPHA);
1247 src0_target = useext(GL_SOURCE0_ALPHA);
1248 src1_target = useext(GL_SOURCE1_ALPHA);
1249 src2_target = useext(GL_SOURCE2_ALPHA);
1250 opr0_target = useext(GL_OPERAND0_ALPHA);
1251 opr1_target = useext(GL_OPERAND1_ALPHA);
1252 opr2_target = useext(GL_OPERAND2_ALPHA);
1253 scal_target = GL_ALPHA_SCALE;
1255 else {
1256 comb_target = useext(GL_COMBINE_RGB);
1257 src0_target = useext(GL_SOURCE0_RGB);
1258 src1_target = useext(GL_SOURCE1_RGB);
1259 src2_target = useext(GL_SOURCE2_RGB);
1260 opr0_target = useext(GL_OPERAND0_RGB);
1261 opr1_target = useext(GL_OPERAND1_RGB);
1262 opr2_target = useext(GL_OPERAND2_RGB);
1263 scal_target = useext(GL_RGB_SCALE);
1266 /* If a texture stage references an invalid texture unit the stage just
1267 * passes through the result from the previous stage */
1268 if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) {
1269 arg1 = WINED3DTA_CURRENT;
1270 op = WINED3DTOP_SELECTARG1;
1273 /* From MSDN (WINED3DTSS_ALPHAARG1) :
1274 The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage,
1275 then the default argument is WINED3DTA_DIFFUSE.
1276 FIXME? If texture added/removed, may need to reset back as well? */
1277 if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
1278 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
1279 } else {
1280 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
1282 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
1283 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
1285 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
1287 Handled = TRUE; /* Assume will be handled */
1289 /* Other texture operations require special extensions: */
1290 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1291 if (isAlpha) {
1292 opr = GL_SRC_ALPHA;
1293 invopr = GL_ONE_MINUS_SRC_ALPHA;
1294 src3_target = GL_SOURCE3_ALPHA_NV;
1295 opr3_target = GL_OPERAND3_ALPHA_NV;
1296 } else {
1297 opr = GL_SRC_COLOR;
1298 invopr = GL_ONE_MINUS_SRC_COLOR;
1299 src3_target = GL_SOURCE3_RGB_NV;
1300 opr3_target = GL_OPERAND3_RGB_NV;
1302 switch (op) {
1303 case WINED3DTOP_DISABLE: /* Only for alpha */
1304 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1305 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1306 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1307 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1308 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1309 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1310 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1311 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1312 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1313 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1314 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1315 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1316 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1317 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1318 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1319 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1320 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1321 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1322 break;
1323 case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */
1324 case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
1325 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1326 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1327 if (op == WINED3DTOP_SELECTARG1) {
1328 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1329 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1330 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1331 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1332 } else {
1333 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1334 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1335 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1336 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1338 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1339 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1340 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1341 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1342 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1343 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1344 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1345 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1346 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1347 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1348 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1349 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1350 break;
1352 case WINED3DTOP_MODULATE:
1353 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1354 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1355 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1356 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1357 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1358 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1359 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1360 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1361 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1362 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1363 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1364 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1365 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1366 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1367 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1368 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1369 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1370 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1371 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1372 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1373 break;
1374 case WINED3DTOP_MODULATE2X:
1375 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1376 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1377 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1378 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1379 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1380 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1381 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1382 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1383 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1384 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1385 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1386 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1387 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1388 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1389 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1390 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1391 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1392 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1393 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1394 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1395 break;
1396 case WINED3DTOP_MODULATE4X:
1397 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1398 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1399 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1400 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1401 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1402 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1403 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1404 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1405 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1406 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1407 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1408 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1409 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1410 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1411 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1412 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1413 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1414 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1415 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
1416 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
1417 break;
1419 case WINED3DTOP_ADD:
1420 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1421 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1422 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1423 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1424 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1425 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1426 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1427 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1428 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1429 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1430 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1431 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1432 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1433 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1434 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1435 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1436 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1437 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1438 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1439 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1440 break;
1442 case WINED3DTOP_ADDSIGNED:
1443 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1444 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1445 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1446 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1447 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1448 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1449 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1450 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1451 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1452 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1453 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1454 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1455 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1456 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1457 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1458 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1459 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1460 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1461 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1462 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1463 break;
1465 case WINED3DTOP_ADDSIGNED2X:
1466 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1467 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1468 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1469 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1470 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1471 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1472 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1473 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1474 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1475 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1476 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1477 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1478 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1479 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1480 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1481 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1482 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1483 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1484 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1485 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1486 break;
1488 case WINED3DTOP_ADDSMOOTH:
1489 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1490 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1491 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1492 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1493 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1494 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1495 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1496 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1497 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1498 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1499 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1500 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1501 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1502 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1503 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1504 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1505 switch (opr1) {
1506 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1507 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1508 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1509 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1511 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1512 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1513 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1514 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1515 break;
1517 case WINED3DTOP_BLENDDIFFUSEALPHA:
1518 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1519 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1520 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1521 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1522 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1523 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1524 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
1525 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
1526 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1527 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1528 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1529 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1530 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1531 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1532 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
1533 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
1534 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1535 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1536 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1537 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1538 break;
1539 case WINED3DTOP_BLENDTEXTUREALPHA:
1540 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1541 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1542 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1543 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1544 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1545 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1546 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
1547 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
1548 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1549 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1550 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1551 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1552 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1553 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1554 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1555 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1556 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1557 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1558 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1559 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1560 break;
1561 case WINED3DTOP_BLENDFACTORALPHA:
1562 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1563 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1564 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1565 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1566 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1567 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1568 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
1569 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
1570 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1571 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1572 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1573 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1574 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1575 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1576 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
1577 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
1578 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1579 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1580 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1581 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1582 break;
1583 case WINED3DTOP_BLENDTEXTUREALPHAPM:
1584 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1585 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1586 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1587 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1588 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1589 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1590 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1591 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1592 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1593 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1594 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1595 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1596 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1597 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1598 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1599 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1600 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1601 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1602 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1603 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1604 break;
1605 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1606 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1607 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1608 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
1609 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1610 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1611 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
1612 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1613 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1614 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1615 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1616 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
1617 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1618 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1619 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
1620 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1621 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1622 switch (opr) {
1623 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1624 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1626 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1627 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1628 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1629 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1630 break;
1631 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1632 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1633 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1634 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1635 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1636 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1637 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1638 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1639 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1640 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1641 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1642 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1643 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1644 switch (opr1) {
1645 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1646 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1648 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1649 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1650 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1651 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1652 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1653 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1654 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1655 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1656 break;
1657 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1658 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1659 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1660 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1661 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1662 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1663 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1664 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1665 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1666 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1667 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1668 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1669 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1670 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1671 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1672 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1673 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1674 switch (opr1) {
1675 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1676 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1677 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1678 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1680 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1681 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1682 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1683 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1684 break;
1685 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1686 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1687 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1688 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1689 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1690 switch (opr1) {
1691 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1692 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1693 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1694 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1696 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
1697 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
1698 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1699 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1700 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1701 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1702 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1703 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1704 switch (opr1) {
1705 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1706 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1708 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1709 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1710 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1711 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1712 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1713 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1714 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1715 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1716 break;
1717 case WINED3DTOP_MULTIPLYADD:
1718 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1719 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1720 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
1721 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1722 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
1723 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1724 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1725 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1726 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1727 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1728 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1729 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1730 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1731 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1732 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
1733 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
1734 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
1735 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
1736 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1737 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1738 break;
1740 case WINED3DTOP_BUMPENVMAP:
1744 case WINED3DTOP_BUMPENVMAPLUMINANCE:
1745 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
1747 default:
1748 Handled = FALSE;
1750 if (Handled) {
1751 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
1752 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
1754 return;
1756 } /* GL_NV_texture_env_combine4 */
1758 Handled = TRUE; /* Again, assume handled */
1759 switch (op) {
1760 case WINED3DTOP_DISABLE: /* Only for alpha */
1761 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1762 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1763 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1764 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
1765 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1766 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
1767 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1768 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1769 break;
1770 case WINED3DTOP_SELECTARG1:
1771 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1772 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1773 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1774 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1775 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1776 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1777 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1778 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1779 break;
1780 case WINED3DTOP_SELECTARG2:
1781 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1782 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1783 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1784 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1785 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1786 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1787 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1788 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1789 break;
1790 case WINED3DTOP_MODULATE:
1791 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1792 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1793 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1794 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1795 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1796 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1797 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1798 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1799 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1800 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1801 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1802 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1803 break;
1804 case WINED3DTOP_MODULATE2X:
1805 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1806 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1807 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1808 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1809 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1810 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1811 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1812 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1813 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1814 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1815 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1816 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1817 break;
1818 case WINED3DTOP_MODULATE4X:
1819 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1820 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1821 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1822 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1823 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1824 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1825 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1826 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1827 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1828 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1829 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
1830 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
1831 break;
1832 case WINED3DTOP_ADD:
1833 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1834 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1835 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1836 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1837 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1838 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1839 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1840 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1841 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1842 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1843 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1844 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1845 break;
1846 case WINED3DTOP_ADDSIGNED:
1847 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1848 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
1849 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1850 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1851 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1852 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1853 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1854 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1855 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1856 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1857 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1858 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1859 break;
1860 case WINED3DTOP_ADDSIGNED2X:
1861 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1862 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1863 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1864 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1865 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1866 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1867 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1868 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1869 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1870 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1871 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1872 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1873 break;
1874 case WINED3DTOP_SUBTRACT:
1875 if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
1876 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
1877 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
1878 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1879 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1880 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1881 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1882 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1883 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1884 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1885 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1886 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1887 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1888 } else {
1889 FIXME("This version of opengl does not support GL_SUBTRACT\n");
1891 break;
1893 case WINED3DTOP_BLENDDIFFUSEALPHA:
1894 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1895 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1896 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1897 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1898 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1899 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1900 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1901 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1902 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1903 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1904 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
1905 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
1906 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1907 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1908 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1909 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1910 break;
1911 case WINED3DTOP_BLENDTEXTUREALPHA:
1912 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1913 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1914 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1915 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1916 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1917 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1918 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1919 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1920 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1921 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1922 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
1923 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
1924 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1925 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1926 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1927 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1928 break;
1929 case WINED3DTOP_BLENDFACTORALPHA:
1930 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1931 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1932 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1933 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1934 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1935 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1936 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1937 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1938 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1939 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1940 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
1941 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
1942 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1943 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1944 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1945 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1946 break;
1947 case WINED3DTOP_BLENDCURRENTALPHA:
1948 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1949 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1950 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1951 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1952 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1953 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1954 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1955 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1956 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1957 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1958 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
1959 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
1960 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1961 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1962 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1963 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1964 break;
1965 case WINED3DTOP_DOTPRODUCT3:
1966 if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
1967 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
1968 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
1969 } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
1970 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
1971 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
1972 } else {
1973 FIXME("This version of opengl does not support GL_DOT3\n");
1975 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1976 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1977 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1978 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1979 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1980 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1981 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1982 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1983 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1984 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1985 break;
1986 case WINED3DTOP_LERP:
1987 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1988 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1989 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1990 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1991 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1992 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1993 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1994 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1995 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1996 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1997 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
1998 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
1999 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2000 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2001 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2002 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2003 break;
2004 case WINED3DTOP_ADDSMOOTH:
2005 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2006 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2007 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2008 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2009 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2010 switch (opr1) {
2011 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2012 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2013 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2014 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2016 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2017 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2018 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2019 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2020 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2021 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2022 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2023 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2024 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2025 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2026 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2027 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2028 } else
2029 Handled = FALSE;
2030 break;
2031 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2032 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2033 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2034 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2035 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2036 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2037 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2038 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2039 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2040 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2041 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2042 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2043 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2044 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2045 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2046 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2047 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2048 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2049 } else
2050 Handled = FALSE;
2051 break;
2052 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2053 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2054 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2055 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2056 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2057 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2058 switch (opr1) {
2059 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2060 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2061 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2062 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2064 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2065 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2066 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2067 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2068 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2069 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2070 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2071 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2072 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2073 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2074 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2075 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2076 } else
2077 Handled = FALSE;
2078 break;
2079 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2080 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2081 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2082 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2083 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2084 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2085 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2086 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2087 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2088 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2089 switch (opr1) {
2090 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2091 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2092 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2093 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2095 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2096 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2097 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2098 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2099 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2100 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2101 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2102 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2103 } else
2104 Handled = FALSE;
2105 break;
2106 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2107 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2108 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2109 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2110 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2111 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2112 switch (opr1) {
2113 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2114 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2115 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2116 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2118 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2119 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2120 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2121 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2122 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2123 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2124 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2125 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2126 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2127 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2128 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2129 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2130 } else
2131 Handled = FALSE;
2132 break;
2133 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2134 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2135 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2136 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2137 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2138 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2139 switch (opr1) {
2140 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2141 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2142 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2143 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2145 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2146 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2147 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2148 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2149 switch (opr1) {
2150 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2151 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2152 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2153 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2155 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2156 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2157 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2158 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2159 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2160 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2161 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2162 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2163 } else
2164 Handled = FALSE;
2165 break;
2166 case WINED3DTOP_MULTIPLYADD:
2167 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2168 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2169 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2170 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2171 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2172 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2173 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2174 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2175 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2176 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2177 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2178 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2179 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2180 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2181 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2182 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2183 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2184 } else
2185 Handled = FALSE;
2186 break;
2187 case WINED3DTOP_BUMPENVMAPLUMINANCE:
2188 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2189 /* Some apps use BUMPENVMAPLUMINANCE instead of D3DTOP_BUMPENVMAP, although
2190 * they check for the non-luminance cap flag. Well, give them what they asked
2191 * for :-)
2193 WARN("Application uses WINED3DTOP_BUMPENVMAPLUMINANCE\n");
2194 } else {
2195 Handled = FALSE;
2196 break;
2198 /* Fall through */
2199 case WINED3DTOP_BUMPENVMAP:
2200 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2201 TRACE("Using ati bumpmap on stage %d, target %d\n", Stage, Stage + 1);
2202 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI);
2203 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI)");
2204 glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1);
2205 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1)");
2206 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2207 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2208 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2209 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2210 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2211 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2212 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2213 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2214 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2215 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2216 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2217 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2219 Handled = TRUE;
2220 break;
2221 } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2222 /* Technically texture shader support without register combiners is possible, but not expected to occur
2223 * on real world cards, so for now a fixme should be enough
2225 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
2227 default:
2228 Handled = FALSE;
2231 if (Handled) {
2232 BOOL combineOK = TRUE;
2233 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2234 DWORD op2;
2236 if (isAlpha) {
2237 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP];
2238 } else {
2239 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP];
2242 /* Note: If COMBINE4 in effect can't go back to combine! */
2243 switch (op2) {
2244 case WINED3DTOP_ADDSMOOTH:
2245 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2246 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2247 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2248 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2249 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2250 case WINED3DTOP_MULTIPLYADD:
2251 /* Ignore those implemented in both cases */
2252 switch (op) {
2253 case WINED3DTOP_SELECTARG1:
2254 case WINED3DTOP_SELECTARG2:
2255 combineOK = FALSE;
2256 Handled = FALSE;
2257 break;
2258 default:
2259 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
2260 return;
2265 if (combineOK) {
2266 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
2267 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
2269 return;
2273 /* After all the extensions, if still unhandled, report fixme */
2274 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
2275 #undef GLINFO_LOCATION
2277 #endif
2279 /* Setup this textures matrix according to the texture flags*/
2280 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords)
2282 float mat[16];
2284 glMatrixMode(GL_TEXTURE);
2285 checkGLcall("glMatrixMode(GL_TEXTURE)");
2287 if (flags == WINED3DTTFF_DISABLE) {
2288 glLoadIdentity();
2289 checkGLcall("glLoadIdentity()");
2290 return;
2293 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2294 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2295 return;
2298 memcpy(mat, smat, 16 * sizeof(float));
2300 switch (flags & ~WINED3DTTFF_PROJECTED) {
2301 case WINED3DTTFF_COUNT1: mat[1] = mat[5] = mat[13] = 0;
2302 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2303 default: mat[3] = mat[7] = mat[11] = 0, mat[15] = 1;
2306 if (flags & WINED3DTTFF_PROJECTED) {
2307 switch (flags & ~WINED3DTTFF_PROJECTED) {
2308 case WINED3DTTFF_COUNT2:
2309 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2310 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2311 break;
2312 case WINED3DTTFF_COUNT3:
2313 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2314 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2315 break;
2317 } else if(!calculatedCoords) { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2318 mat[12] = mat[8];
2319 mat[13] = mat[9];
2322 glLoadMatrixf(mat);
2323 checkGLcall("glLoadMatrixf(mat)");
2326 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
2328 /* Convertes a D3D format into a OpenGL configuration format */
2329 int D3DFmtMakeGlCfg(WINED3DFORMAT BackBufferFormat, WINED3DFORMAT StencilBufferFormat, int *attribs, int* nAttribs, BOOL alternate){
2330 #define PUSH1(att) attribs[(*nAttribs)++] = (att);
2331 #define PUSH2(att,value) attribs[(*nAttribs)++] = (att); attribs[(*nAttribs)++] = (value);
2332 /*We need to do some Card specific stuff in here at some point,
2333 D3D now supports floating point format buffers, and there are a number of different OpelGl ways of managing these e.g.
2334 GLX_ATI_pixel_format_float
2336 switch (BackBufferFormat) {
2337 /* color buffer */
2338 case WINED3DFMT_P8:
2339 PUSH2(GLX_RENDER_TYPE, GLX_COLOR_INDEX_BIT);
2340 PUSH2(GLX_BUFFER_SIZE, 8);
2341 PUSH2(GLX_DOUBLEBUFFER, TRUE);
2342 break;
2344 case WINED3DFMT_R3G3B2:
2345 PUSH2(GLX_RENDER_TYPE, GLX_RGBA_BIT);
2346 PUSH2(GLX_RED_SIZE, 3);
2347 PUSH2(GLX_GREEN_SIZE, 3);
2348 PUSH2(GLX_BLUE_SIZE, 2);
2349 break;
2351 case WINED3DFMT_A1R5G5B5:
2352 PUSH2(GLX_ALPHA_SIZE, 1);
2353 case WINED3DFMT_X1R5G5B5:
2354 PUSH2(GLX_RED_SIZE, 5);
2355 PUSH2(GLX_GREEN_SIZE, 5);
2356 PUSH2(GLX_BLUE_SIZE, 5);
2357 break;
2359 case WINED3DFMT_R5G6B5:
2360 PUSH2(GLX_RED_SIZE, 5);
2361 PUSH2(GLX_GREEN_SIZE, 6);
2362 PUSH2(GLX_BLUE_SIZE, 5);
2363 break;
2365 case WINED3DFMT_A4R4G4B4:
2366 PUSH2(GLX_ALPHA_SIZE, 4);
2367 case WINED3DFMT_X4R4G4B4:
2368 PUSH2(GLX_RED_SIZE, 4);
2369 PUSH2(GLX_GREEN_SIZE, 4);
2370 PUSH2(GLX_BLUE_SIZE, 4);
2371 break;
2373 case WINED3DFMT_A8R8G8B8:
2374 PUSH2(GLX_ALPHA_SIZE, 8);
2375 case WINED3DFMT_R8G8B8:
2376 case WINED3DFMT_X8R8G8B8:
2377 PUSH2(GLX_RED_SIZE, 8);
2378 PUSH2(GLX_GREEN_SIZE, 8);
2379 PUSH2(GLX_BLUE_SIZE, 8);
2380 break;
2382 case WINED3DFMT_A2R10G10B10:
2383 PUSH2(GLX_ALPHA_SIZE, 2);
2384 PUSH2(GLX_RED_SIZE, 10);
2385 PUSH2(GLX_GREEN_SIZE, 10);
2386 PUSH2(GLX_BLUE_SIZE, 10);
2387 break;
2389 case WINED3DFMT_A16B16G16R16:
2390 PUSH2(GLX_ALPHA_SIZE, 16);
2391 PUSH2(GLX_RED_SIZE, 16);
2392 PUSH2(GLX_GREEN_SIZE, 16);
2393 PUSH2(GLX_BLUE_SIZE, 16);
2394 break;
2396 default:
2397 FIXME("Unsupported color format: %s\n", debug_d3dformat(BackBufferFormat));
2398 break;
2400 if(!alternate){
2401 switch (StencilBufferFormat) {
2402 case 0:
2403 break;
2405 case WINED3DFMT_D16_LOCKABLE:
2406 case WINED3DFMT_D16:
2407 PUSH2(GLX_DEPTH_SIZE, 16);
2408 break;
2410 case WINED3DFMT_D15S1:
2411 PUSH2(GLX_DEPTH_SIZE, 15);
2412 PUSH2(GLX_STENCIL_SIZE, 1);
2413 /*Does openGl support a 1bit stencil?, I've seen it used elsewhere
2414 e.g. http://www.ks.uiuc.edu/Research/vmd/doxygen/OpenGLDisplayDevice_8C-source.html*/
2415 break;
2417 case WINED3DFMT_D24X8:
2418 PUSH2(GLX_DEPTH_SIZE, 24);
2419 break;
2421 case WINED3DFMT_D24X4S4:
2422 PUSH2(GLX_DEPTH_SIZE, 24);
2423 PUSH2(GLX_STENCIL_SIZE, 4);
2424 break;
2426 case WINED3DFMT_D24S8:
2427 PUSH2(GLX_DEPTH_SIZE, 24);
2428 PUSH2(GLX_STENCIL_SIZE, 8);
2429 break;
2431 case WINED3DFMT_D24FS8:
2432 PUSH2(GLX_DEPTH_SIZE, 24);
2433 PUSH2(GLX_STENCIL_SIZE, 8);
2434 break;
2436 case WINED3DFMT_D32:
2437 PUSH2(GLX_DEPTH_SIZE, 32);
2438 break;
2440 default:
2441 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(StencilBufferFormat));
2442 break;
2445 } else { /* it the device doesn't support the 'exact' format, try to find something close */
2446 switch (StencilBufferFormat) {
2447 case 0:
2448 break;
2450 case WINED3DFMT_D16_LOCKABLE:
2451 case WINED3DFMT_D16:
2452 PUSH2(GLX_DEPTH_SIZE, 1);
2453 break;
2455 case WINED3DFMT_D15S1:
2456 PUSH2(GLX_DEPTH_SIZE, 1);
2457 PUSH2(GLX_STENCIL_SIZE, 1);
2458 /*Does openGl support a 1bit stencil?, I've seen it used elsewhere
2459 e.g. http://www.ks.uiuc.edu/Research/vmd/doxygen/OpenGLDisplayDevice_8C-source.html*/
2460 break;
2462 case WINED3DFMT_D24X8:
2463 PUSH2(GLX_DEPTH_SIZE, 1);
2464 break;
2466 case WINED3DFMT_D24X4S4:
2467 PUSH2(GLX_DEPTH_SIZE, 1);
2468 PUSH2(GLX_STENCIL_SIZE, 1);
2469 break;
2471 case WINED3DFMT_D24S8:
2472 PUSH2(GLX_DEPTH_SIZE, 1);
2473 PUSH2(GLX_STENCIL_SIZE, 1);
2474 break;
2476 case WINED3DFMT_D24FS8:
2477 PUSH2(GLX_DEPTH_SIZE, 1);
2478 PUSH2(GLX_STENCIL_SIZE, 1);
2479 break;
2481 case WINED3DFMT_D32:
2482 PUSH2(GLX_DEPTH_SIZE, 1);
2483 break;
2485 default:
2486 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(StencilBufferFormat));
2487 break;
2491 return *nAttribs;
2494 #undef GLINFO_LOCATION
2496 /* DirectDraw stuff */
2497 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2498 switch(depth) {
2499 case 8: return WINED3DFMT_P8; break;
2500 case 15: return WINED3DFMT_X1R5G5B5; break;
2501 case 16: return WINED3DFMT_R5G6B5; break;
2502 case 24: return WINED3DFMT_R8G8B8; break;
2503 case 32: return WINED3DFMT_X8R8G8B8; break;
2504 default: return WINED3DFMT_UNKNOWN;
2508 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2509 WINED3DMATRIX temp;
2511 /* Now do the multiplication 'by hand'.
2512 I know that all this could be optimised, but this will be done later :-) */
2513 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);
2514 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);
2515 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);
2516 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);
2518 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);
2519 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);
2520 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);
2521 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);
2523 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);
2524 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);
2525 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);
2526 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);
2528 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);
2529 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);
2530 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);
2531 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);
2533 /* And copy the new matrix in the good storage.. */
2534 memcpy(dest, &temp, 16 * sizeof(float));
2537 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2538 DWORD size = 0;
2539 int i;
2540 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2542 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2543 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2544 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2545 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2546 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2547 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2548 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2549 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2550 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2551 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2552 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2553 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2554 default: ERR("Unexpected position mask\n");
2556 for (i = 0; i < numTextures; i++) {
2557 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2560 return size;
2563 /***********************************************************************
2564 * CalculateTexRect
2566 * Calculates the dimensions of the opengl texture used for blits.
2567 * Handled oversized opengl textures and updates the source rectangle
2568 * accordingly
2570 * Params:
2571 * This: Surface to operate on
2572 * Rect: Requested rectangle
2574 * Returns:
2575 * TRUE if the texture part can be loaded,
2576 * FALSE otherwise
2578 *********************************************************************/
2579 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
2581 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
2582 int x1 = Rect->left, x2 = Rect->right;
2583 int y1 = Rect->top, y2 = Rect->bottom;
2584 GLint maxSize = GL_LIMITS(texture_size);
2586 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2587 Rect->left, Rect->top, Rect->right, Rect->bottom);
2589 /* The sizes might be reversed */
2590 if(Rect->left > Rect->right) {
2591 x1 = Rect->right;
2592 x2 = Rect->left;
2594 if(Rect->top > Rect->bottom) {
2595 y1 = Rect->bottom;
2596 y2 = Rect->top;
2599 /* No oversized texture? This is easy */
2600 if(!(This->Flags & SFLAG_OVERSIZE)) {
2601 /* Which rect from the texture do I need? */
2602 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2603 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2604 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2605 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2607 return TRUE;
2608 } else {
2609 /* Check if we can succeed at all */
2610 if( (x2 - x1) > maxSize ||
2611 (y2 - y1) > maxSize ) {
2612 TRACE("Requested rectangle is too large for gl\n");
2613 return FALSE;
2616 /* A part of the texture has to be picked. First, check if
2617 * some texture part is loaded already, if yes try to re-use it.
2618 * If the texture is dirty, or the part can't be used,
2619 * re-position the part to load
2621 if(This->Flags & SFLAG_INTEXTURE) {
2622 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2623 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2624 /* Ok, the rectangle is ok, re-use it */
2625 TRACE("Using existing gl Texture\n");
2626 } else {
2627 /* Rectangle is not ok, dirtify the texture to reload it */
2628 TRACE("Dirtifying texture to force reload\n");
2629 This->Flags &= ~SFLAG_INTEXTURE;
2633 /* Now if we are dirty(no else if!) */
2634 if(!(This->Flags & SFLAG_INTEXTURE)) {
2635 /* Set the new rectangle. Use the following strategy:
2636 * 1) Use as big textures as possible.
2637 * 2) Place the texture part in the way that the requested
2638 * part is in the middle of the texture(well, almost)
2639 * 3) If the texture is moved over the edges of the
2640 * surface, replace it nicely
2641 * 4) If the coord is not limiting the texture size,
2642 * use the whole size
2644 if((This->pow2Width) > maxSize) {
2645 This->glRect.left = x1 - maxSize / 2;
2646 if(This->glRect.left < 0) {
2647 This->glRect.left = 0;
2649 This->glRect.right = This->glRect.left + maxSize;
2650 if(This->glRect.right > This->currentDesc.Width) {
2651 This->glRect.right = This->currentDesc.Width;
2652 This->glRect.left = This->glRect.right - maxSize;
2654 } else {
2655 This->glRect.left = 0;
2656 This->glRect.right = This->pow2Width;
2659 if(This->pow2Height > maxSize) {
2660 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2661 if(This->glRect.top < 0) This->glRect.top = 0;
2662 This->glRect.bottom = This->glRect.left + maxSize;
2663 if(This->glRect.bottom > This->currentDesc.Height) {
2664 This->glRect.bottom = This->currentDesc.Height;
2665 This->glRect.top = This->glRect.bottom - maxSize;
2667 } else {
2668 This->glRect.top = 0;
2669 This->glRect.bottom = This->pow2Height;
2671 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2672 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2675 /* Re-calculate the rect to draw */
2676 Rect->left -= This->glRect.left;
2677 Rect->right -= This->glRect.left;
2678 Rect->top -= This->glRect.top;
2679 Rect->bottom -= This->glRect.top;
2681 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2682 * or the pow2Width / pow2Height of the surface
2684 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2685 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2686 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2687 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2689 return TRUE;
2691 #undef GLINFO_LOCATION
2693 /* Hash table functions */
2695 hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
2697 hash_table_t *table;
2698 unsigned int initial_size = 8;
2700 table = HeapAlloc(GetProcessHeap(), 0, sizeof(hash_table_t) + (initial_size * sizeof(struct list)));
2701 if (!table)
2703 ERR("Failed to allocate table, returning NULL.\n");
2704 return NULL;
2707 table->hash_function = hash_function;
2708 table->compare_function = compare_function;
2710 table->grow_size = initial_size - (initial_size >> 2);
2711 table->shrink_size = 0;
2713 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
2714 if (!table->buckets)
2716 ERR("Failed to allocate table buckets, returning NULL.\n");
2717 HeapFree(GetProcessHeap(), 0, table);
2718 return NULL;
2720 table->bucket_count = initial_size;
2722 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(hash_table_entry_t));
2723 if (!table->entries)
2725 ERR("Failed to allocate table entries, returning NULL.\n");
2726 HeapFree(GetProcessHeap(), 0, table->buckets);
2727 HeapFree(GetProcessHeap(), 0, table);
2728 return NULL;
2730 table->entry_count = 0;
2732 list_init(&table->free_entries);
2733 table->count = 0;
2735 return table;
2738 void hash_table_destroy(hash_table_t *table)
2740 unsigned int i = 0;
2742 for (i = 0; i < table->entry_count; ++i)
2744 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
2747 HeapFree(GetProcessHeap(), 0, table->entries);
2748 HeapFree(GetProcessHeap(), 0, table->buckets);
2749 HeapFree(GetProcessHeap(), 0, table);
2752 static inline hash_table_entry_t *hash_table_get_by_idx(hash_table_t *table, void *key, unsigned int idx)
2754 hash_table_entry_t *entry;
2756 if (table->buckets[idx].next)
2757 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), hash_table_entry_t, entry)
2758 if (table->compare_function(entry->key, key)) return entry;
2760 return NULL;
2763 static BOOL hash_table_resize(hash_table_t *table, unsigned int new_bucket_count)
2765 unsigned int new_entry_count = 0;
2766 hash_table_entry_t *new_entries;
2767 struct list *new_buckets;
2768 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
2769 unsigned int i;
2771 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
2772 if (!new_buckets)
2774 ERR("Failed to allocate new buckets, returning FALSE.\n");
2775 return FALSE;
2778 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(hash_table_entry_t));
2779 if (!new_entries)
2781 ERR("Failed to allocate new entries, returning FALSE.\n");
2782 HeapFree(GetProcessHeap(), 0, new_buckets);
2783 return FALSE;
2786 for (i = 0; i < table->bucket_count; ++i)
2788 if (table->buckets[i].next)
2790 hash_table_entry_t *entry, *entry2;
2792 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], hash_table_entry_t, entry)
2794 int j;
2795 hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
2796 *new_entry = *entry;
2798 j = new_entry->hash & (new_bucket_count - 1);
2800 if (!new_buckets[j].next) list_init(&new_buckets[j]);
2801 list_add_head(&new_buckets[j], &new_entry->entry);
2806 HeapFree(GetProcessHeap(), 0, table->buckets);
2807 table->buckets = new_buckets;
2809 HeapFree(GetProcessHeap(), 0, table->entries);
2810 table->entries = new_entries;
2812 table->entry_count = new_entry_count;
2813 list_init(&table->free_entries);
2815 table->bucket_count = new_bucket_count;
2816 table->grow_size = grow_size;
2817 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
2819 return TRUE;
2822 void hash_table_put(hash_table_t *table, void *key, void *value)
2824 unsigned int idx;
2825 unsigned int hash;
2826 hash_table_entry_t *entry;
2828 hash = table->hash_function(key);
2829 idx = hash & (table->bucket_count - 1);
2830 entry = hash_table_get_by_idx(table, key, idx);
2832 if (entry)
2834 HeapFree(GetProcessHeap(), 0, key);
2835 entry->value = value;
2837 if (!value)
2839 HeapFree(GetProcessHeap(), 0, entry->key);
2840 entry->key = NULL;
2842 /* Remove the entry */
2843 list_remove(&entry->entry);
2844 list_add_head(&table->free_entries, &entry->entry);
2846 --table->count;
2848 /* Shrink if necessary */
2849 if (table->count < table->shrink_size) {
2850 if (!hash_table_resize(table, table->bucket_count >> 1))
2852 ERR("Failed to shrink the table...\n");
2857 return;
2860 if (!value) return;
2862 /* Grow if necessary */
2863 if (table->count >= table->grow_size)
2865 if (!hash_table_resize(table, table->bucket_count << 1))
2867 ERR("Failed to grow the table, returning.\n");
2868 return;
2871 idx = hash & (table->bucket_count - 1);
2874 /* Find an entry to insert */
2875 if (!list_empty(&table->free_entries))
2877 struct list *elem = list_head(&table->free_entries);
2879 list_remove(elem);
2880 entry = LIST_ENTRY(elem, hash_table_entry_t, entry);
2881 } else {
2882 entry = table->entries + (table->entry_count++);
2885 /* Insert the entry */
2886 entry->key = key;
2887 entry->value = value;
2888 entry->hash = hash;
2889 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
2890 list_add_head(&table->buckets[idx], &entry->entry);
2892 ++table->count;
2895 void hash_table_remove(hash_table_t *table, void *key)
2897 hash_table_put(table, key, NULL);
2900 void *hash_table_get(hash_table_t *table, void *key)
2902 unsigned int idx;
2903 hash_table_entry_t *entry;
2905 idx = table->hash_function(key) & (table->bucket_count - 1);
2906 entry = hash_table_get_by_idx(table, key, idx);
2908 return entry ? entry->value : NULL;