d3d: Calculate the size of WINED3DFVF_XYZBx FVFs.
[wine/multimedia.git] / dlls / wined3d / utils.c
blob9ab4e767c5996685c2e9db456ef58f6501d230f4
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 ((IWineD3DImpl *)(This->wineD3D))->gl_info
32 /*****************************************************************************
33 * Pixel format array
35 static const PixelFormatDesc formats[] = {
36 /*{WINED3DFORMAT ,alphamask ,redmask ,greenmask ,bluemask ,bpp ,isFourcc ,internal ,format ,type }*/
37 {WINED3DFMT_UNKNOWN ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,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 },
40 {WINED3DFMT_YUY2 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 },
41 {WINED3DFMT_DXT1 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,GL_RGBA ,GL_UNSIGNED_BYTE },
42 {WINED3DFMT_DXT2 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,GL_RGBA ,GL_UNSIGNED_BYTE },
43 {WINED3DFMT_DXT3 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,GL_RGBA ,GL_UNSIGNED_BYTE },
44 {WINED3DFMT_DXT4 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,GL_RGBA ,GL_UNSIGNED_BYTE },
45 {WINED3DFMT_DXT5 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,GL_RGBA ,GL_UNSIGNED_BYTE },
46 {WINED3DFMT_MULTI2_ARGB8,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 },
47 {WINED3DFMT_G8R8_G8B8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 },
48 {WINED3DFMT_R8G8_B8G8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,TRUE ,0 ,0 ,0 },
49 /* IEEE formats */
50 {WINED3DFMT_R32F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_RGB32F_ARB ,GL_RED ,GL_FLOAT },
51 {WINED3DFMT_G32R32F ,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,0 ,0 ,0 },
52 {WINED3DFMT_A32B32G32R32F,0x0 ,0x0 ,0x0 ,0x0 ,16 ,FALSE ,GL_RGBA32F_ARB ,GL_RGBA ,GL_FLOAT },
53 /* Hmm? */
54 {WINED3DFMT_CxV8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,0 ,0 ,0 },
55 /* Float */
56 {WINED3DFMT_R16F ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_RGB16F_ARB ,GL_RED ,GL_HALF_FLOAT_ARB },
57 {WINED3DFMT_G16R16F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 },
58 {WINED3DFMT_A16B16G16R16F,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,GL_RGBA16F_ARB ,GL_RGBA ,GL_HALF_FLOAT_ARB },
59 /* Palettized formats */
60 {WINED3DFMT_A8P8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,0 ,0 ,0 },
61 {WINED3DFMT_P8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,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_BGR ,GL_UNSIGNED_BYTE },
64 {WINED3DFMT_A8R8G8B8 ,0xff000000 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,FALSE ,GL_RGBA8 ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
65 {WINED3DFMT_X8R8G8B8 ,0x0 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,FALSE ,GL_RGB8 ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
66 {WINED3DFMT_R5G6B5 ,0x0 ,0x0000F800 ,0x000007e0 ,0x0000001f ,2 ,FALSE ,GL_RGB5 ,GL_RGB ,GL_UNSIGNED_SHORT_5_6_5 },
67 {WINED3DFMT_X1R5G5B5 ,0x0 ,0x00007c00 ,0x000003e0 ,0x0000001f ,2 ,FALSE ,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_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV },
69 {WINED3DFMT_A4R4G4B4 ,0x0000f000 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,FALSE ,GL_RGBA4 ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
70 {WINED3DFMT_R3G3B2 ,0x0 ,0x000000e0 ,0x0000001c ,0x00000003 ,1 ,FALSE ,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_ALPHA ,GL_UNSIGNED_BYTE },
72 {WINED3DFMT_A8R3G3B2 ,0x0000ff00 ,0x000000e0 ,0x0000001c ,0x00000003 ,2 ,FALSE ,0 ,0 ,0 },
73 {WINED3DFMT_X4R4G4B4 ,0x0 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,FALSE ,GL_RGB4 ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
74 {WINED3DFMT_A2B10G10R10 ,0xb0000000 ,0x000003ff ,0x000ffc00 ,0x3ff00000 ,4 ,FALSE ,GL_RGB ,GL_RGBA ,GL_UNSIGNED_INT_2_10_10_10_REV },
75 {WINED3DFMT_A8B8G8R8 ,0xff000000 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,FALSE ,GL_RGBA8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
76 {WINED3DFMT_X8B8G8R8 ,0x0 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,FALSE ,GL_RGB8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
77 {WINED3DFMT_G16R16 ,0x0 ,0x0000ffff ,0xffff0000 ,0x0 ,4 ,FALSE ,0 ,0 ,0 },
78 {WINED3DFMT_A2R10G10B10 ,0xb0000000 ,0x3ff00000 ,0x000ffc00 ,0x000003ff ,4 ,FALSE ,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_RGBA ,GL_UNSIGNED_SHORT },
80 /* Luminance */
81 {WINED3DFMT_L8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,GL_LUMINANCE8 ,GL_LUMINANCE ,GL_UNSIGNED_BYTE },
82 {WINED3DFMT_A8L8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_LUMINANCE8_ALPHA8 ,GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE },
83 {WINED3DFMT_A4L4 ,0x000000f0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,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_DSDT_NV ,GL_BYTE },
86 {WINED3DFMT_L6V5U5 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,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_DSDT_MAG_INTENSITY_NV,GL_BYTE },
88 {WINED3DFMT_Q8W8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_SIGNED_RGBA8_NV ,GL_RGBA ,GL_BYTE },
89 {WINED3DFMT_V16U16 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_SIGNED_HILO16_NV ,GL_HILO_NV ,GL_SHORT },
90 {WINED3DFMT_W11V11U10 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 },
91 {WINED3DFMT_A2W10V10U10 ,0xb0000000 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 },
92 /* Depth stencil formats */
93 {WINED3DFMT_D16_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,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_COMPONENT,GL_UNSIGNED_INT },
95 {WINED3DFMT_D15S1 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,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_COMPONENT,GL_UNSIGNED_INT },
97 {WINED3DFMT_D24X8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,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_COMPONENT,GL_UNSIGNED_INT },
99 {WINED3DFMT_D16 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT24_ARB,GL_DEPTH_COMPONENT,GL_UNSIGNED_SHORT },
100 {WINED3DFMT_L16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_LUMINANCE16_EXT ,GL_LUMINANCE ,GL_UNSIGNED_SHORT },
101 {WINED3DFMT_D32F_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DEPTH_COMPONENT32_ARB,GL_DEPTH_COMPONENT,GL_FLOAT },
102 {WINED3DFMT_D24FS8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,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 },
105 {WINED3DFMT_INDEX16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,0 ,0 ,0 },
106 {WINED3DFMT_INDEX32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 },
107 {WINED3DFMT_Q16W16V16U16,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,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 */
870 switch(op)
872 case WINED3DTOP_DISABLE:
873 /* Only for alpha */
874 if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n");
875 /* Input, prev_alpha*1 */
876 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
877 GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
878 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
879 GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
881 /* Output */
882 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
883 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
884 break;
886 case WINED3DTOP_SELECTARG1:
887 case WINED3DTOP_SELECTARG2:
888 /* Input, arg*1 */
889 if (op == WINED3DTOP_SELECTARG1) {
890 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
891 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
892 } else {
893 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
894 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
896 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
897 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
899 /* Output */
900 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
901 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
902 break;
904 case WINED3DTOP_MODULATE:
905 case WINED3DTOP_MODULATE2X:
906 case WINED3DTOP_MODULATE4X:
907 /* Input, arg1*arg2 */
908 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
909 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
910 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
911 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
913 /* Output */
914 if (op == WINED3DTOP_MODULATE) {
915 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
916 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
917 } else if (op == WINED3DTOP_MODULATE2X) {
918 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
919 GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
920 } else if (op == WINED3DTOP_MODULATE4X) {
921 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
922 GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
924 break;
926 case WINED3DTOP_ADD:
927 case WINED3DTOP_ADDSIGNED:
928 case WINED3DTOP_ADDSIGNED2X:
929 /* Input, arg1*1+arg2*1 */
930 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
931 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
932 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
933 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
934 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
935 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
936 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
937 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
939 /* Output */
940 if (op == WINED3DTOP_ADD) {
941 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
942 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
943 } else if (op == WINED3DTOP_ADDSIGNED) {
944 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
945 GL_SPARE0_NV, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
946 } else if (op == WINED3DTOP_ADDSIGNED2X) {
947 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
948 GL_SPARE0_NV, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
950 break;
952 case WINED3DTOP_SUBTRACT:
953 /* Input, arg1*1+-arg2*1 */
954 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
955 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
956 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
957 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
958 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
959 tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1]));
960 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
961 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
963 /* Output */
964 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
965 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
966 break;
968 case WINED3DTOP_ADDSMOOTH:
969 /* Input, arg1*1+(1-arg1)*arg2 */
970 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
971 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
972 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
973 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
974 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
975 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
976 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
977 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
979 /* Output */
980 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
981 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
982 break;
984 case WINED3DTOP_BLENDDIFFUSEALPHA:
985 case WINED3DTOP_BLENDTEXTUREALPHA:
986 case WINED3DTOP_BLENDFACTORALPHA:
987 case WINED3DTOP_BLENDTEXTUREALPHAPM:
988 case WINED3DTOP_BLENDCURRENTALPHA:
990 GLenum alpha_src = GL_PRIMARY_COLOR_NV;
991 if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx);
992 else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
993 else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx);
994 else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
995 else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx);
996 else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op));
998 /* Input, arg1*alpha_src+arg2*(1-alpha_src) */
999 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1000 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1001 if (op == WINED3DTOP_BLENDTEXTUREALPHAPM)
1003 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1004 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1005 } else {
1006 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1007 alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
1009 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1010 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1011 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1012 alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
1014 /* Output */
1015 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1016 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1017 break;
1020 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1021 /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */
1022 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n");
1023 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1024 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1025 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1026 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1027 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1028 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1029 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1030 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1032 /* Output */
1033 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1034 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1035 break;
1037 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1038 /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */
1039 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n");
1040 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1041 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1042 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1043 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1044 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1045 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1046 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1047 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1049 /* Output */
1050 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1051 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1052 break;
1054 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1055 /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */
1056 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n");
1057 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1058 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA));
1059 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1060 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1061 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1062 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1063 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1064 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1066 /* Output */
1067 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1068 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1069 break;
1071 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1072 /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */
1073 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n");
1074 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1075 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1076 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1077 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1078 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1079 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1080 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1081 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1083 /* Output */
1084 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1085 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1086 break;
1088 case WINED3DTOP_DOTPRODUCT3:
1089 /* Input, arg1 . arg2 */
1090 /* FIXME: DX7 uses a different calculation? */
1091 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1092 tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0]));
1093 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1094 tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1]));
1096 /* Output */
1097 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1098 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE));
1099 break;
1101 case WINED3DTOP_MULTIPLYADD:
1102 /* Input, arg1*1+arg2*arg3 */
1103 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1104 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1105 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1106 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1107 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1108 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1109 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1110 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1112 /* Output */
1113 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1114 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1115 break;
1117 case WINED3DTOP_LERP:
1118 /* Input, arg1*arg2+(1-arg1)*arg3 */
1119 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1120 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1121 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1122 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1123 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1124 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1125 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1126 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1128 /* Output */
1129 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1130 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1131 break;
1133 default:
1134 FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1135 stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
1138 checkGLcall("set_tex_op_nvrc()\n");
1142 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
1143 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
1144 * input should be used for all input components. The WINED3DTA_COMPLEMENT
1145 * flag specifies the complement of the input should be used. */
1146 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
1147 BOOL complement = arg & WINED3DTA_COMPLEMENT;
1149 /* Calculate the operand */
1150 if (complement) {
1151 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
1152 else *operand = GL_ONE_MINUS_SRC_COLOR;
1153 } else {
1154 if (from_alpha) *operand = GL_SRC_ALPHA;
1155 else *operand = GL_SRC_COLOR;
1158 /* Calculate the source */
1159 switch (arg & WINED3DTA_SELECTMASK) {
1160 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
1161 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
1162 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
1163 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
1164 case WINED3DTA_SPECULAR:
1166 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
1167 * 'Secondary color' and isn't supported until base GL supports it
1168 * There is no concept of temp registers as far as I can tell
1170 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
1171 *source = GL_TEXTURE;
1172 break;
1173 default:
1174 FIXME("Unrecognized texture arg %#x\n", arg);
1175 *source = GL_TEXTURE;
1176 break;
1180 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
1181 #if defined (GL_VERSION_1_3)
1182 # define useext(A) A
1183 # define combine_ext 1
1184 #elif defined (GL_EXT_texture_env_combine)
1185 # define useext(A) A##_EXT
1186 # define combine_ext 1
1187 #elif defined (GL_ARB_texture_env_combine)
1188 # define useext(A) A##_ARB
1189 # define combine_ext 1
1190 #else
1191 # undef combine_ext
1192 #endif
1194 #if !defined(combine_ext)
1195 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1197 FIXME("Requires opengl combine extensions to work\n");
1198 return;
1200 #else
1201 /* Setup the texture operations texture stage states */
1202 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1204 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
1205 GLenum src1, src2, src3;
1206 GLenum opr1, opr2, opr3;
1207 GLenum comb_target;
1208 GLenum src0_target, src1_target, src2_target;
1209 GLenum opr0_target, opr1_target, opr2_target;
1210 GLenum scal_target;
1211 GLenum opr=0, invopr, src3_target, opr3_target;
1212 BOOL Handled = FALSE;
1213 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
1215 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
1217 /* This is called by a state handler which has the gl lock held and a context for the thread */
1219 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
1220 the form (a1 <operation> a2). However, some of the more complex operations
1221 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
1222 in a third parameter called a0. Therefore these are operations of the form
1223 a0 <operation> a1 <operation> a2, ie the new parameter goes to the front.
1225 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
1226 functions below, expect their syntax to differ slightly to those listed in the
1227 manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
1228 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
1230 if (isAlpha) {
1231 comb_target = useext(GL_COMBINE_ALPHA);
1232 src0_target = useext(GL_SOURCE0_ALPHA);
1233 src1_target = useext(GL_SOURCE1_ALPHA);
1234 src2_target = useext(GL_SOURCE2_ALPHA);
1235 opr0_target = useext(GL_OPERAND0_ALPHA);
1236 opr1_target = useext(GL_OPERAND1_ALPHA);
1237 opr2_target = useext(GL_OPERAND2_ALPHA);
1238 scal_target = GL_ALPHA_SCALE;
1240 else {
1241 comb_target = useext(GL_COMBINE_RGB);
1242 src0_target = useext(GL_SOURCE0_RGB);
1243 src1_target = useext(GL_SOURCE1_RGB);
1244 src2_target = useext(GL_SOURCE2_RGB);
1245 opr0_target = useext(GL_OPERAND0_RGB);
1246 opr1_target = useext(GL_OPERAND1_RGB);
1247 opr2_target = useext(GL_OPERAND2_RGB);
1248 scal_target = useext(GL_RGB_SCALE);
1251 /* If a texture stage references an invalid texture unit the stage just
1252 * passes through the result from the previous stage */
1253 if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) {
1254 arg1 = WINED3DTA_CURRENT;
1255 op = WINED3DTOP_SELECTARG1;
1258 /* From MSDN (WINED3DTSS_ALPHAARG1) :
1259 The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage,
1260 then the default argument is WINED3DTA_DIFFUSE.
1261 FIXME? If texture added/removed, may need to reset back as well? */
1262 if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
1263 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
1264 } else {
1265 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
1267 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
1268 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
1270 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
1272 Handled = TRUE; /* Assume will be handled */
1274 /* Other texture operations require special extensions: */
1275 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1276 if (isAlpha) {
1277 opr = GL_SRC_ALPHA;
1278 invopr = GL_ONE_MINUS_SRC_ALPHA;
1279 src3_target = GL_SOURCE3_ALPHA_NV;
1280 opr3_target = GL_OPERAND3_ALPHA_NV;
1281 } else {
1282 opr = GL_SRC_COLOR;
1283 invopr = GL_ONE_MINUS_SRC_COLOR;
1284 src3_target = GL_SOURCE3_RGB_NV;
1285 opr3_target = GL_OPERAND3_RGB_NV;
1287 switch (op) {
1288 case WINED3DTOP_DISABLE: /* Only for alpha */
1289 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1290 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1291 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1292 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1293 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1294 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1295 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1296 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1297 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1298 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1299 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1300 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1301 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1302 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1303 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1304 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1305 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1306 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1307 break;
1308 case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */
1309 case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
1310 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1311 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1312 if (op == WINED3DTOP_SELECTARG1) {
1313 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1314 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1315 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1316 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1317 } else {
1318 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1319 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1320 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1321 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1323 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1324 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1325 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1326 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1327 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1328 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1329 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1330 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1331 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1332 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1333 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1334 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1335 break;
1337 case WINED3DTOP_MODULATE:
1338 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1339 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1340 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1341 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1342 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1343 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1344 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1345 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1346 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1347 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1348 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1349 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1350 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1351 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1352 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1353 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1354 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1355 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1356 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1357 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1358 break;
1359 case WINED3DTOP_MODULATE2X:
1360 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1361 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1362 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1363 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1364 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1365 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1366 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1367 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1368 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1369 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1370 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1371 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1372 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1373 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1374 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1375 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1376 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1377 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1378 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1379 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1380 break;
1381 case WINED3DTOP_MODULATE4X:
1382 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1383 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1384 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1385 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1386 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1387 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1388 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1389 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1390 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1391 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1392 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1393 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1394 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1395 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1396 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1397 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1398 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1399 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1400 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
1401 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
1402 break;
1404 case WINED3DTOP_ADD:
1405 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1406 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1407 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1408 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1409 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1410 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1411 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1412 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1413 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1414 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1415 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1416 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1417 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1418 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1419 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1420 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1421 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1422 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1423 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1424 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1425 break;
1427 case WINED3DTOP_ADDSIGNED:
1428 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1429 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1430 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1431 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1432 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1433 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1434 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1435 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1436 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1437 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1438 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1439 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1440 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1441 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1442 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1443 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1444 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1445 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1446 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1447 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1448 break;
1450 case WINED3DTOP_ADDSIGNED2X:
1451 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1452 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1453 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1454 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1455 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1456 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1457 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1458 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1459 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1460 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1461 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1462 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1463 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1464 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1465 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1466 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1467 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1468 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1469 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1470 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1471 break;
1473 case WINED3DTOP_ADDSMOOTH:
1474 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1475 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1476 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1477 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1478 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1479 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1480 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1481 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1482 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1483 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1484 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1485 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1486 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1487 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1488 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1489 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1490 switch (opr1) {
1491 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1492 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1493 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1494 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1496 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1497 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1498 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1499 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1500 break;
1502 case WINED3DTOP_BLENDDIFFUSEALPHA:
1503 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1504 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1505 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1506 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1507 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1508 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1509 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
1510 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
1511 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1512 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1513 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1514 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1515 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1516 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1517 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
1518 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
1519 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1520 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1521 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1522 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1523 break;
1524 case WINED3DTOP_BLENDTEXTUREALPHA:
1525 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1526 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1527 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1528 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1529 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1530 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1531 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
1532 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
1533 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1534 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1535 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1536 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1537 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1538 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1539 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1540 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1541 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1542 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1543 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1544 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1545 break;
1546 case WINED3DTOP_BLENDFACTORALPHA:
1547 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1548 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1549 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1550 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1551 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1552 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1553 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
1554 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
1555 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1556 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1557 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1558 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1559 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1560 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1561 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
1562 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
1563 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1564 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1565 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1566 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1567 break;
1568 case WINED3DTOP_BLENDTEXTUREALPHAPM:
1569 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1570 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1571 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1572 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1573 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1574 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1575 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1576 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1577 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1578 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1579 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1580 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1581 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1582 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1583 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1584 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1585 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1586 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1587 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1588 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1589 break;
1590 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1591 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1592 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1593 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
1594 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1595 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1596 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
1597 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1598 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1599 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1600 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1601 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
1602 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1603 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1604 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
1605 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1606 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1607 switch (opr) {
1608 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1609 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1611 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1612 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1613 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1614 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1615 break;
1616 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1617 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1618 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1619 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1620 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1621 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1622 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1623 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1624 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1625 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1626 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1627 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1628 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1629 switch (opr1) {
1630 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1631 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1633 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1634 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1635 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1636 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1637 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1638 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1639 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1640 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1641 break;
1642 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1643 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1644 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1645 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1646 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1647 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1648 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1649 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1650 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1651 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1652 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1653 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1654 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1655 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1656 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1657 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1658 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1659 switch (opr1) {
1660 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1661 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1662 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1663 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1665 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1666 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1667 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1668 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1669 break;
1670 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1671 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1672 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1673 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1674 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1675 switch (opr1) {
1676 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1677 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1678 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1679 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1681 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
1682 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
1683 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1684 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1685 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1686 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1687 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1688 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1689 switch (opr1) {
1690 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1691 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1693 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1694 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1695 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1696 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1697 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1698 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1699 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1700 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1701 break;
1702 case WINED3DTOP_MULTIPLYADD:
1703 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1704 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1705 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
1706 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1707 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
1708 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1709 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1710 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1711 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1712 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1713 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1714 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1715 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1716 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1717 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
1718 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
1719 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
1720 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
1721 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1722 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1723 break;
1725 case WINED3DTOP_BUMPENVMAP:
1729 case WINED3DTOP_BUMPENVMAPLUMINANCE:
1731 default:
1732 Handled = FALSE;
1734 if (Handled) {
1735 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
1736 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
1738 return;
1740 } /* GL_NV_texture_env_combine4 */
1742 Handled = TRUE; /* Again, assume handled */
1743 switch (op) {
1744 case WINED3DTOP_DISABLE: /* Only for alpha */
1745 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1746 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1747 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1748 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
1749 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1750 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
1751 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1752 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1753 break;
1754 case WINED3DTOP_SELECTARG1:
1755 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1756 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1757 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1758 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1759 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1760 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1761 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1762 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1763 break;
1764 case WINED3DTOP_SELECTARG2:
1765 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1766 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1767 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1768 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1769 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1770 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1771 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1772 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1773 break;
1774 case WINED3DTOP_MODULATE:
1775 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1776 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1777 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1778 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1779 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1780 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1781 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1782 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1783 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1784 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1785 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1786 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1787 break;
1788 case WINED3DTOP_MODULATE2X:
1789 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1790 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1791 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1792 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1793 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1794 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1795 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1796 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1797 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1798 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1799 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1800 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1801 break;
1802 case WINED3DTOP_MODULATE4X:
1803 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1804 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1805 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1806 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1807 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1808 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1809 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1810 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1811 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1812 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1813 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
1814 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
1815 break;
1816 case WINED3DTOP_ADD:
1817 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1818 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1819 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1820 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1821 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1822 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1823 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1824 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1825 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1826 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1827 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1828 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1829 break;
1830 case WINED3DTOP_ADDSIGNED:
1831 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1832 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
1833 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1834 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1835 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1836 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1837 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1838 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1839 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1840 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1841 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1842 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1843 break;
1844 case WINED3DTOP_ADDSIGNED2X:
1845 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1846 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1847 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1848 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1849 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1850 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1851 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1852 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1853 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1854 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1855 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1856 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1857 break;
1858 case WINED3DTOP_SUBTRACT:
1859 if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
1860 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
1861 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
1862 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1863 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1864 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1865 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1866 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1867 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1868 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1869 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1870 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1871 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1872 } else {
1873 FIXME("This version of opengl does not support GL_SUBTRACT\n");
1875 break;
1877 case WINED3DTOP_BLENDDIFFUSEALPHA:
1878 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1879 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1880 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1881 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1882 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1883 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1884 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1885 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1886 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1887 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1888 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
1889 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
1890 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1891 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1892 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1893 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1894 break;
1895 case WINED3DTOP_BLENDTEXTUREALPHA:
1896 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1897 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1898 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1899 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1900 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1901 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1902 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1903 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1904 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1905 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1906 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
1907 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
1908 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1909 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1910 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1911 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1912 break;
1913 case WINED3DTOP_BLENDFACTORALPHA:
1914 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1915 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1916 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1917 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1918 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1919 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1920 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1921 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1922 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1923 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1924 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
1925 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
1926 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1927 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1928 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1929 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1930 break;
1931 case WINED3DTOP_BLENDCURRENTALPHA:
1932 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1933 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1934 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1935 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1936 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1937 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1938 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1939 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1940 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1941 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1942 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
1943 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
1944 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
1945 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
1946 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1947 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1948 break;
1949 case WINED3DTOP_DOTPRODUCT3:
1950 if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
1951 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
1952 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
1953 } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
1954 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
1955 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
1956 } else {
1957 FIXME("This version of opengl does not support GL_DOT3\n");
1959 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1960 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1961 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1962 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1963 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1964 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1965 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1966 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1967 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1968 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1969 break;
1970 case WINED3DTOP_LERP:
1971 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
1972 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
1973 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1974 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1975 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1976 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1977 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1978 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1979 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1980 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1981 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
1982 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
1983 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
1984 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
1985 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1986 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1987 break;
1988 case WINED3DTOP_ADDSMOOTH:
1989 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
1990 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
1991 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
1992 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1993 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1994 switch (opr1) {
1995 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1996 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1997 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1998 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2000 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2001 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2002 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2003 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2004 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2005 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2006 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2007 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2008 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2009 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2010 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2011 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2012 } else
2013 Handled = FALSE;
2014 break;
2015 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2016 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2017 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2018 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2019 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2020 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2021 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2022 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2023 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2024 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2025 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2026 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2027 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2028 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2029 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2030 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2031 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2032 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2033 } else
2034 Handled = FALSE;
2035 break;
2036 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2037 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2038 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2039 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2040 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2041 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2042 switch (opr1) {
2043 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2044 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2045 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2046 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2048 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2049 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2050 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2051 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2052 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2053 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2054 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2055 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2056 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2057 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2058 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2059 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2060 } else
2061 Handled = FALSE;
2062 break;
2063 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2064 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2065 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2066 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2067 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2068 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2069 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2070 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2071 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2072 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2073 switch (opr1) {
2074 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2075 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2076 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2077 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2079 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2080 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2081 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2082 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2083 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2084 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2085 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2086 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2087 } else
2088 Handled = FALSE;
2089 break;
2090 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2091 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2092 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2093 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2094 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2095 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2096 switch (opr1) {
2097 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2098 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2099 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2100 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2102 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2103 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2104 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2105 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2106 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2107 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2108 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2109 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2110 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2111 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2112 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2113 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2114 } else
2115 Handled = FALSE;
2116 break;
2117 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2118 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2119 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2120 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2121 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2122 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2123 switch (opr1) {
2124 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2125 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2126 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2127 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2129 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2130 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2131 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2132 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2133 switch (opr1) {
2134 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2135 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2136 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2137 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2139 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2140 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2141 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2142 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2143 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2144 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2145 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2146 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2147 } else
2148 Handled = FALSE;
2149 break;
2150 case WINED3DTOP_MULTIPLYADD:
2151 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2152 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2153 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2154 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2155 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2156 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2157 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2158 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2159 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2160 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2161 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2162 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2163 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2164 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2165 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2166 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2167 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2168 } else
2169 Handled = FALSE;
2170 break;
2171 default:
2172 Handled = FALSE;
2175 if (Handled) {
2176 BOOL combineOK = TRUE;
2177 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2178 DWORD op2;
2180 if (isAlpha) {
2181 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP];
2182 } else {
2183 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP];
2186 /* Note: If COMBINE4 in effect can't go back to combine! */
2187 switch (op2) {
2188 case WINED3DTOP_ADDSMOOTH:
2189 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2190 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2191 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2192 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2193 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2194 case WINED3DTOP_MULTIPLYADD:
2195 /* Ignore those implemented in both cases */
2196 switch (op) {
2197 case WINED3DTOP_SELECTARG1:
2198 case WINED3DTOP_SELECTARG2:
2199 combineOK = FALSE;
2200 Handled = FALSE;
2201 break;
2202 default:
2203 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
2204 return;
2209 if (combineOK) {
2210 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
2211 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
2213 return;
2217 /* After all the extensions, if still unhandled, report fixme */
2218 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
2219 #undef GLINFO_LOCATION
2221 #endif
2223 /* Setup this textures matrix according to the texture flags*/
2224 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords)
2226 float mat[16];
2228 glMatrixMode(GL_TEXTURE);
2229 checkGLcall("glMatrixMode(GL_TEXTURE)");
2231 if (flags == WINED3DTTFF_DISABLE) {
2232 glLoadIdentity();
2233 checkGLcall("glLoadIdentity()");
2234 return;
2237 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2238 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2239 return;
2242 memcpy(mat, smat, 16 * sizeof(float));
2244 switch (flags & ~WINED3DTTFF_PROJECTED) {
2245 case WINED3DTTFF_COUNT1: mat[1] = mat[5] = mat[13] = 0;
2246 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2247 default: mat[3] = mat[7] = mat[11] = 0, mat[15] = 1;
2250 if (flags & WINED3DTTFF_PROJECTED) {
2251 switch (flags & ~WINED3DTTFF_PROJECTED) {
2252 case WINED3DTTFF_COUNT2:
2253 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2254 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2255 break;
2256 case WINED3DTTFF_COUNT3:
2257 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2258 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2259 break;
2261 } else if(!calculatedCoords) { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2262 mat[12] = mat[8];
2263 mat[13] = mat[9];
2266 glLoadMatrixf(mat);
2267 checkGLcall("glLoadMatrixf(mat)");
2270 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
2272 /* Convertes a D3D format into a OpenGL configuration format */
2273 int D3DFmtMakeGlCfg(WINED3DFORMAT BackBufferFormat, WINED3DFORMAT StencilBufferFormat, int *attribs, int* nAttribs, BOOL alternate){
2274 #define PUSH1(att) attribs[(*nAttribs)++] = (att);
2275 #define PUSH2(att,value) attribs[(*nAttribs)++] = (att); attribs[(*nAttribs)++] = (value);
2276 /*We need to do some Card specific stuff in here at some point,
2277 D3D now supports floating point format buffers, and there are a number of different OpelGl ways of managing these e.g.
2278 GLX_ATI_pixel_format_float
2280 switch (BackBufferFormat) {
2281 /* color buffer */
2282 case WINED3DFMT_P8:
2283 PUSH2(GLX_RENDER_TYPE, GLX_COLOR_INDEX_BIT);
2284 PUSH2(GLX_BUFFER_SIZE, 8);
2285 PUSH2(GLX_DOUBLEBUFFER, TRUE);
2286 break;
2288 case WINED3DFMT_R3G3B2:
2289 PUSH2(GLX_RENDER_TYPE, GLX_RGBA_BIT);
2290 PUSH2(GLX_RED_SIZE, 3);
2291 PUSH2(GLX_GREEN_SIZE, 3);
2292 PUSH2(GLX_BLUE_SIZE, 2);
2293 break;
2295 case WINED3DFMT_A1R5G5B5:
2296 PUSH2(GLX_ALPHA_SIZE, 1);
2297 case WINED3DFMT_X1R5G5B5:
2298 PUSH2(GLX_RED_SIZE, 5);
2299 PUSH2(GLX_GREEN_SIZE, 5);
2300 PUSH2(GLX_BLUE_SIZE, 5);
2301 break;
2303 case WINED3DFMT_R5G6B5:
2304 PUSH2(GLX_RED_SIZE, 5);
2305 PUSH2(GLX_GREEN_SIZE, 6);
2306 PUSH2(GLX_BLUE_SIZE, 5);
2307 break;
2309 case WINED3DFMT_A4R4G4B4:
2310 PUSH2(GLX_ALPHA_SIZE, 4);
2311 case WINED3DFMT_X4R4G4B4:
2312 PUSH2(GLX_RED_SIZE, 4);
2313 PUSH2(GLX_GREEN_SIZE, 4);
2314 PUSH2(GLX_BLUE_SIZE, 4);
2315 break;
2317 case WINED3DFMT_A8R8G8B8:
2318 PUSH2(GLX_ALPHA_SIZE, 8);
2319 case WINED3DFMT_R8G8B8:
2320 case WINED3DFMT_X8R8G8B8:
2321 PUSH2(GLX_RED_SIZE, 8);
2322 PUSH2(GLX_GREEN_SIZE, 8);
2323 PUSH2(GLX_BLUE_SIZE, 8);
2324 break;
2326 case WINED3DFMT_A2R10G10B10:
2327 PUSH2(GLX_ALPHA_SIZE, 2);
2328 PUSH2(GLX_RED_SIZE, 10);
2329 PUSH2(GLX_GREEN_SIZE, 10);
2330 PUSH2(GLX_BLUE_SIZE, 10);
2331 break;
2333 case WINED3DFMT_A16B16G16R16:
2334 PUSH2(GLX_ALPHA_SIZE, 16);
2335 PUSH2(GLX_RED_SIZE, 16);
2336 PUSH2(GLX_GREEN_SIZE, 16);
2337 PUSH2(GLX_BLUE_SIZE, 16);
2338 break;
2340 default:
2341 FIXME("Unsupported color format: %s\n", debug_d3dformat(BackBufferFormat));
2342 break;
2344 if(!alternate){
2345 switch (StencilBufferFormat) {
2346 case 0:
2347 break;
2349 case WINED3DFMT_D16_LOCKABLE:
2350 case WINED3DFMT_D16:
2351 PUSH2(GLX_DEPTH_SIZE, 16);
2352 break;
2354 case WINED3DFMT_D15S1:
2355 PUSH2(GLX_DEPTH_SIZE, 15);
2356 PUSH2(GLX_STENCIL_SIZE, 1);
2357 /*Does openGl support a 1bit stencil?, I've seen it used elsewhere
2358 e.g. http://www.ks.uiuc.edu/Research/vmd/doxygen/OpenGLDisplayDevice_8C-source.html*/
2359 break;
2361 case WINED3DFMT_D24X8:
2362 PUSH2(GLX_DEPTH_SIZE, 24);
2363 break;
2365 case WINED3DFMT_D24X4S4:
2366 PUSH2(GLX_DEPTH_SIZE, 24);
2367 PUSH2(GLX_STENCIL_SIZE, 4);
2368 break;
2370 case WINED3DFMT_D24S8:
2371 PUSH2(GLX_DEPTH_SIZE, 24);
2372 PUSH2(GLX_STENCIL_SIZE, 8);
2373 break;
2375 case WINED3DFMT_D24FS8:
2376 PUSH2(GLX_DEPTH_SIZE, 24);
2377 PUSH2(GLX_STENCIL_SIZE, 8);
2378 break;
2380 case WINED3DFMT_D32:
2381 PUSH2(GLX_DEPTH_SIZE, 32);
2382 break;
2384 default:
2385 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(StencilBufferFormat));
2386 break;
2389 } else { /* it the device doesn't support the 'exact' format, try to find something close */
2390 switch (StencilBufferFormat) {
2391 case 0:
2392 break;
2394 case WINED3DFMT_D16_LOCKABLE:
2395 case WINED3DFMT_D16:
2396 PUSH2(GLX_DEPTH_SIZE, 1);
2397 break;
2399 case WINED3DFMT_D15S1:
2400 PUSH2(GLX_DEPTH_SIZE, 1);
2401 PUSH2(GLX_STENCIL_SIZE, 1);
2402 /*Does openGl support a 1bit stencil?, I've seen it used elsewhere
2403 e.g. http://www.ks.uiuc.edu/Research/vmd/doxygen/OpenGLDisplayDevice_8C-source.html*/
2404 break;
2406 case WINED3DFMT_D24X8:
2407 PUSH2(GLX_DEPTH_SIZE, 1);
2408 break;
2410 case WINED3DFMT_D24X4S4:
2411 PUSH2(GLX_DEPTH_SIZE, 1);
2412 PUSH2(GLX_STENCIL_SIZE, 1);
2413 break;
2415 case WINED3DFMT_D24S8:
2416 PUSH2(GLX_DEPTH_SIZE, 1);
2417 PUSH2(GLX_STENCIL_SIZE, 1);
2418 break;
2420 case WINED3DFMT_D24FS8:
2421 PUSH2(GLX_DEPTH_SIZE, 1);
2422 PUSH2(GLX_STENCIL_SIZE, 1);
2423 break;
2425 case WINED3DFMT_D32:
2426 PUSH2(GLX_DEPTH_SIZE, 1);
2427 break;
2429 default:
2430 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(StencilBufferFormat));
2431 break;
2435 return *nAttribs;
2438 #undef GLINFO_LOCATION
2440 /* DirectDraw stuff */
2441 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2442 switch(depth) {
2443 case 8: return WINED3DFMT_P8; break;
2444 case 15: return WINED3DFMT_X1R5G5B5; break;
2445 case 16: return WINED3DFMT_R5G6B5; break;
2446 case 24: return WINED3DFMT_R8G8B8; break;
2447 case 32: return WINED3DFMT_X8R8G8B8; break;
2448 default: return WINED3DFMT_UNKNOWN;
2452 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2453 WINED3DMATRIX temp;
2455 /* Now do the multiplication 'by hand'.
2456 I know that all this could be optimised, but this will be done later :-) */
2457 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);
2458 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);
2459 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);
2460 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);
2462 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);
2463 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);
2464 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);
2465 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);
2467 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);
2468 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);
2469 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);
2470 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);
2472 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);
2473 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);
2474 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);
2475 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);
2477 /* And copy the new matrix in the good storage.. */
2478 memcpy(dest, &temp, 16 * sizeof(float));
2481 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2482 DWORD size = 0;
2483 int i;
2484 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2486 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2487 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2488 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2489 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2490 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2491 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2492 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2493 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2494 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2495 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2496 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2497 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2498 default: ERR("Unexpected position mask\n");
2500 for (i = 0; i < numTextures; i++) {
2501 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2504 return size;
2507 /***********************************************************************
2508 * CalculateTexRect
2510 * Calculates the dimensions of the opengl texture used for blits.
2511 * Handled oversized opengl textures and updates the source rectangle
2512 * accordingly
2514 * Params:
2515 * This: Surface to operate on
2516 * Rect: Requested rectangle
2518 * Returns:
2519 * TRUE if the texture part can be loaded,
2520 * FALSE otherwise
2522 *********************************************************************/
2523 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->resource.wineD3DDevice->wineD3D))->gl_info
2525 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
2526 int x1 = Rect->left, x2 = Rect->right;
2527 int y1 = Rect->top, y2 = Rect->bottom;
2528 GLint maxSize = GL_LIMITS(texture_size);
2530 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2531 Rect->left, Rect->top, Rect->right, Rect->bottom);
2533 /* The sizes might be reversed */
2534 if(Rect->left > Rect->right) {
2535 x1 = Rect->right;
2536 x2 = Rect->left;
2538 if(Rect->top > Rect->bottom) {
2539 y1 = Rect->bottom;
2540 y2 = Rect->top;
2543 /* No oversized texture? This is easy */
2544 if(!(This->Flags & SFLAG_OVERSIZE)) {
2545 /* Which rect from the texture do I need? */
2546 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2547 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2548 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2549 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2551 return TRUE;
2552 } else {
2553 /* Check if we can succeed at all */
2554 if( (x2 - x1) > maxSize ||
2555 (y2 - y1) > maxSize ) {
2556 TRACE("Requested rectangle is too large for gl\n");
2557 return FALSE;
2560 /* A part of the texture has to be picked. First, check if
2561 * some texture part is loaded already, if yes try to re-use it.
2562 * If the texture is dirty, or the part can't be used,
2563 * re-position the part to load
2565 if(This->Flags & SFLAG_INTEXTURE) {
2566 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2567 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2568 /* Ok, the rectangle is ok, re-use it */
2569 TRACE("Using existing gl Texture\n");
2570 } else {
2571 /* Rectangle is not ok, dirtify the texture to reload it */
2572 TRACE("Dirtifying texture to force reload\n");
2573 This->Flags &= ~SFLAG_INTEXTURE;
2577 /* Now if we are dirty(no else if!) */
2578 if(!(This->Flags & SFLAG_INTEXTURE)) {
2579 /* Set the new rectangle. Use the following strategy:
2580 * 1) Use as big textures as possible.
2581 * 2) Place the texture part in the way that the requested
2582 * part is in the middle of the texture(well, almost)
2583 * 3) If the texture is moved over the edges of the
2584 * surface, replace it nicely
2585 * 4) If the coord is not limiting the texture size,
2586 * use the whole size
2588 if((This->pow2Width) > maxSize) {
2589 This->glRect.left = x1 - maxSize / 2;
2590 if(This->glRect.left < 0) {
2591 This->glRect.left = 0;
2593 This->glRect.right = This->glRect.left + maxSize;
2594 if(This->glRect.right > This->currentDesc.Width) {
2595 This->glRect.right = This->currentDesc.Width;
2596 This->glRect.left = This->glRect.right - maxSize;
2598 } else {
2599 This->glRect.left = 0;
2600 This->glRect.right = This->pow2Width;
2603 if(This->pow2Height > maxSize) {
2604 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2605 if(This->glRect.top < 0) This->glRect.top = 0;
2606 This->glRect.bottom = This->glRect.left + maxSize;
2607 if(This->glRect.bottom > This->currentDesc.Height) {
2608 This->glRect.bottom = This->currentDesc.Height;
2609 This->glRect.top = This->glRect.bottom - maxSize;
2611 } else {
2612 This->glRect.top = 0;
2613 This->glRect.bottom = This->pow2Height;
2615 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2616 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2619 /* Re-calculate the rect to draw */
2620 Rect->left -= This->glRect.left;
2621 Rect->right -= This->glRect.left;
2622 Rect->top -= This->glRect.top;
2623 Rect->bottom -= This->glRect.top;
2625 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2626 * or the pow2Width / pow2Height of the surface
2628 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2629 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2630 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2631 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2633 return TRUE;
2635 #undef GLINFO_LOCATION
2637 /* Hash table functions */
2639 hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
2641 hash_table_t *table;
2642 unsigned int initial_size = 8;
2644 table = HeapAlloc(GetProcessHeap(), 0, sizeof(hash_table_t) + (initial_size * sizeof(struct list)));
2645 if (!table)
2647 ERR("Failed to allocate table, returning NULL.\n");
2648 return NULL;
2651 table->hash_function = hash_function;
2652 table->compare_function = compare_function;
2654 table->grow_size = initial_size - (initial_size >> 2);
2655 table->shrink_size = 0;
2657 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
2658 if (!table->buckets)
2660 ERR("Failed to allocate table buckets, returning NULL.\n");
2661 HeapFree(GetProcessHeap(), 0, table);
2662 return NULL;
2664 table->bucket_count = initial_size;
2666 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(hash_table_entry_t));
2667 if (!table->entries)
2669 ERR("Failed to allocate table entries, returning NULL.\n");
2670 HeapFree(GetProcessHeap(), 0, table->buckets);
2671 HeapFree(GetProcessHeap(), 0, table);
2672 return NULL;
2674 table->entry_count = 0;
2676 list_init(&table->free_entries);
2677 table->count = 0;
2679 return table;
2682 void hash_table_destroy(hash_table_t *table)
2684 unsigned int i = 0;
2686 for (i = 0; i < table->entry_count; ++i)
2688 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
2691 HeapFree(GetProcessHeap(), 0, table->entries);
2692 HeapFree(GetProcessHeap(), 0, table->buckets);
2693 HeapFree(GetProcessHeap(), 0, table);
2696 static inline hash_table_entry_t *hash_table_get_by_idx(hash_table_t *table, void *key, unsigned int idx)
2698 hash_table_entry_t *entry;
2700 if (table->buckets[idx].next)
2701 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), hash_table_entry_t, entry)
2702 if (table->compare_function(entry->key, key)) return entry;
2704 return NULL;
2707 static BOOL hash_table_resize(hash_table_t *table, unsigned int new_bucket_count)
2709 unsigned int new_entry_count = 0;
2710 hash_table_entry_t *new_entries;
2711 struct list *new_buckets;
2712 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
2713 unsigned int i;
2715 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
2716 if (!new_buckets)
2718 ERR("Failed to allocate new buckets, returning FALSE.\n");
2719 return FALSE;
2722 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(hash_table_entry_t));
2723 if (!new_entries)
2725 ERR("Failed to allocate new entries, returning FALSE.\n");
2726 HeapFree(GetProcessHeap(), 0, new_buckets);
2727 return FALSE;
2730 for (i = 0; i < table->bucket_count; ++i)
2732 if (table->buckets[i].next)
2734 hash_table_entry_t *entry, *entry2;
2736 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], hash_table_entry_t, entry)
2738 int j;
2739 hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
2740 *new_entry = *entry;
2742 j = new_entry->hash & (new_bucket_count - 1);
2744 if (!new_buckets[j].next) list_init(&new_buckets[j]);
2745 list_add_head(&new_buckets[j], &new_entry->entry);
2750 HeapFree(GetProcessHeap(), 0, table->buckets);
2751 table->buckets = new_buckets;
2753 HeapFree(GetProcessHeap(), 0, table->entries);
2754 table->entries = new_entries;
2756 table->entry_count = new_entry_count;
2757 list_init(&table->free_entries);
2759 table->bucket_count = new_bucket_count;
2760 table->grow_size = grow_size;
2761 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
2763 return TRUE;
2766 void hash_table_put(hash_table_t *table, void *key, void *value)
2768 unsigned int idx;
2769 unsigned int hash;
2770 hash_table_entry_t *entry;
2772 hash = table->hash_function(key);
2773 idx = hash & (table->bucket_count - 1);
2774 entry = hash_table_get_by_idx(table, key, idx);
2776 if (entry)
2778 HeapFree(GetProcessHeap(), 0, key);
2779 entry->value = value;
2781 if (!value)
2783 HeapFree(GetProcessHeap(), 0, entry->key);
2784 entry->key = NULL;
2786 /* Remove the entry */
2787 list_remove(&entry->entry);
2788 list_add_head(&table->free_entries, &entry->entry);
2790 --table->count;
2792 /* Shrink if necessary */
2793 if (table->count < table->shrink_size) {
2794 if (!hash_table_resize(table, table->bucket_count >> 1))
2796 ERR("Failed to shrink the table...\n");
2801 return;
2804 if (!value) return;
2806 /* Grow if necessary */
2807 if (table->count >= table->grow_size)
2809 if (!hash_table_resize(table, table->bucket_count << 1))
2811 ERR("Failed to grow the table, returning.\n");
2812 return;
2815 idx = hash & (table->bucket_count - 1);
2818 /* Find an entry to insert */
2819 if (!list_empty(&table->free_entries))
2821 struct list *elem = list_head(&table->free_entries);
2823 list_remove(elem);
2824 entry = LIST_ENTRY(elem, hash_table_entry_t, entry);
2825 } else {
2826 entry = table->entries + (table->entry_count++);
2829 /* Insert the entry */
2830 entry->key = key;
2831 entry->value = value;
2832 entry->hash = hash;
2833 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
2834 list_add_head(&table->buckets[idx], &entry->entry);
2836 ++table->count;
2839 void hash_table_remove(hash_table_t *table, void *key)
2841 hash_table_put(table, key, NULL);
2844 void *hash_table_get(hash_table_t *table, void *key)
2846 unsigned int idx;
2847 hash_table_entry_t *entry;
2849 idx = table->hash_function(key) & (table->bucket_count - 1);
2850 entry = hash_table_get_by_idx(table, key, idx);
2852 return entry ? entry->value : NULL;