wined3d: Remove some #ifdefs.
[wine/wine-gecko.git] / dlls / wined3d / utils.c
blob245c2c24a78dd27f1420b5d643fd0936ed2b687b
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
9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "config.h"
27 #include "wined3d_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
31 /*****************************************************************************
32 * Pixel format array
34 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
35 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
36 * high masks do not fit into the 32 bit values needed for ddraw. It is only
37 * used for ddraw mostly, and to figure out if the format has alpha at all, so
38 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
39 * formats are not usable in 2D rendering because ddraw doesn't support them.
41 static const StaticPixelFormatDesc formats[] = {
42 /*{WINED3DFORMAT ,alphamask ,redmask ,greenmask ,bluemask ,bpp ,depth ,stencil, isFourcc*/
43 {WINED3DFMT_UNKNOWN ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
44 /* FourCC formats, kept here to have WINED3DFMT_R8G8B8(=20) at position 20 */
45 {WINED3DFMT_UYVY ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
46 {WINED3DFMT_YUY2 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
47 {WINED3DFMT_YV12 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
48 {WINED3DFMT_DXT1 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
49 {WINED3DFMT_DXT2 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
50 {WINED3DFMT_DXT3 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
51 {WINED3DFMT_DXT4 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
52 {WINED3DFMT_DXT5 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
53 {WINED3DFMT_MULTI2_ARGB8,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
54 {WINED3DFMT_G8R8_G8B8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
55 {WINED3DFMT_R8G8_B8G8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
56 /* IEEE formats */
57 {WINED3DFMT_R32F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
58 {WINED3DFMT_G32R32F ,0x0 ,0x0 ,0x0 ,0x0 ,8 ,0 ,0 ,FALSE },
59 {WINED3DFMT_A32B32G32R32F,0x1 ,0x0 ,0x0 ,0x0 ,16 ,0 ,0 ,FALSE },
60 /* Hmm? */
61 {WINED3DFMT_CxV8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
62 /* Float */
63 {WINED3DFMT_R16F ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
64 {WINED3DFMT_G16R16F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
65 {WINED3DFMT_A16B16G16R16F,0x1 ,0x0 ,0x0 ,0x0 ,8 ,0 ,0 ,FALSE },
66 /* Palettized formats */
67 {WINED3DFMT_A8P8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
68 {WINED3DFMT_P8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
69 /* Standard ARGB formats. Keep WINED3DFMT_R8G8B8(=20) at position 20 */
70 {WINED3DFMT_R8G8B8 ,0x0 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,3 ,0 ,0 ,FALSE },
71 {WINED3DFMT_A8R8G8B8 ,0xff000000 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,0 ,0 ,FALSE },
72 {WINED3DFMT_X8R8G8B8 ,0x0 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,0 ,0 ,FALSE },
73 {WINED3DFMT_R5G6B5 ,0x0 ,0x0000F800 ,0x000007e0 ,0x0000001f ,2 ,0 ,0 ,FALSE },
74 {WINED3DFMT_X1R5G5B5 ,0x0 ,0x00007c00 ,0x000003e0 ,0x0000001f ,2 ,0 ,0 ,FALSE },
75 {WINED3DFMT_A1R5G5B5 ,0x00008000 ,0x00007c00 ,0x000003e0 ,0x0000001f ,2 ,0 ,0 ,FALSE },
76 {WINED3DFMT_A4R4G4B4 ,0x0000f000 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,0 ,0 ,FALSE },
77 {WINED3DFMT_R3G3B2 ,0x0 ,0x000000e0 ,0x0000001c ,0x00000003 ,1 ,0 ,0 ,FALSE },
78 {WINED3DFMT_A8 ,0x000000ff ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
79 {WINED3DFMT_A8R3G3B2 ,0x0000ff00 ,0x000000e0 ,0x0000001c ,0x00000003 ,2 ,0 ,0 ,FALSE },
80 {WINED3DFMT_X4R4G4B4 ,0x0 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,0 ,0 ,FALSE },
81 {WINED3DFMT_A2B10G10R10 ,0xb0000000 ,0x000003ff ,0x000ffc00 ,0x3ff00000 ,4 ,0 ,0 ,FALSE },
82 {WINED3DFMT_A8B8G8R8 ,0xff000000 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,0 ,0 ,FALSE },
83 {WINED3DFMT_X8B8G8R8 ,0x0 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,0 ,0 ,FALSE },
84 {WINED3DFMT_G16R16 ,0x0 ,0x0000ffff ,0xffff0000 ,0x0 ,4 ,0 ,0 ,FALSE },
85 {WINED3DFMT_A2R10G10B10 ,0xb0000000 ,0x3ff00000 ,0x000ffc00 ,0x000003ff ,4 ,0 ,0 ,FALSE },
86 {WINED3DFMT_A16B16G16R16,0x1 ,0x0000ffff ,0xffff0000 ,0x0 ,8 ,0 ,0 ,FALSE },
87 /* Luminance */
88 {WINED3DFMT_L8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
89 {WINED3DFMT_A8L8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
90 {WINED3DFMT_A4L4 ,0x000000f0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
91 /* Bump mapping stuff */
92 {WINED3DFMT_V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
93 {WINED3DFMT_L6V5U5 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
94 {WINED3DFMT_X8L8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
95 {WINED3DFMT_Q8W8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
96 {WINED3DFMT_V16U16 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
97 {WINED3DFMT_W11V11U10 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
98 {WINED3DFMT_A2W10V10U10 ,0xb0000000 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
99 /* Depth stencil formats */
100 {WINED3DFMT_D16_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,2 ,16 ,0 ,FALSE },
101 {WINED3DFMT_D32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,32 ,0 ,FALSE },
102 {WINED3DFMT_D15S1 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,15 ,1 ,FALSE },
103 {WINED3DFMT_D24S8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,8 ,FALSE },
104 {WINED3DFMT_D24X8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,0 ,FALSE },
105 {WINED3DFMT_D24X4S4 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,4 ,FALSE },
106 {WINED3DFMT_D16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,16 ,0 ,FALSE },
107 {WINED3DFMT_L16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,16 ,0 ,FALSE },
108 {WINED3DFMT_D32F_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,4 ,32 ,0 ,FALSE },
109 {WINED3DFMT_D24FS8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,8 ,FALSE },
110 /* Is this a vertex buffer? */
111 {WINED3DFMT_VERTEXDATA ,0x0 ,0x0 ,0x0 ,0x0 ,0 ,0 ,0 ,FALSE },
112 {WINED3DFMT_INDEX16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
113 {WINED3DFMT_INDEX32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
114 {WINED3DFMT_Q16W16V16U16,0x0 ,0x0 ,0x0 ,0x0 ,8 ,0 ,0 ,FALSE },
117 typedef struct {
118 WINED3DFORMAT fmt;
119 GLint glInternal, glGammaInternal, rtInternal, glFormat, glType;
120 unsigned int Flags;
121 } GlPixelFormatDescTemplate;
123 /*****************************************************************************
124 * OpenGL format template. Contains unexciting formats which do not need
125 * extension checks. The order in this table is independent of the order in
126 * the table StaticPixelFormatDesc above. Not all formats have to be in this
127 * table.
129 static const GlPixelFormatDescTemplate gl_formats_template[] = {
130 /*{ internal ,srgbInternal , rtInternal, format ,type \
131 ,Flags }*/
132 {WINED3DFMT_UNKNOWN ,0 ,0 , 0, 0 ,0
133 ,0 },
134 /* FourCC formats */
135 {WINED3DFMT_UYVY ,0 ,0 , 0, 0 ,0
136 ,0 },
137 {WINED3DFMT_YUY2 ,0 ,0 , 0, 0 ,0
138 ,0 },
139 {WINED3DFMT_DXT1 ,GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT , 0, GL_RGBA ,GL_UNSIGNED_BYTE
140 ,WINED3DFMT_FLAG_FILTERING },
141 {WINED3DFMT_DXT2 ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT , 0, GL_RGBA ,GL_UNSIGNED_BYTE
142 ,WINED3DFMT_FLAG_FILTERING },
143 {WINED3DFMT_DXT3 ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT , 0, GL_RGBA ,GL_UNSIGNED_BYTE
144 ,WINED3DFMT_FLAG_FILTERING },
145 {WINED3DFMT_DXT4 ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT , 0, GL_RGBA ,GL_UNSIGNED_BYTE
146 ,WINED3DFMT_FLAG_FILTERING },
147 {WINED3DFMT_DXT5 ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT , 0, GL_RGBA ,GL_UNSIGNED_BYTE
148 ,WINED3DFMT_FLAG_FILTERING },
149 {WINED3DFMT_MULTI2_ARGB8 ,0 ,0 , 0, 0 ,0
150 ,0 },
151 {WINED3DFMT_G8R8_G8B8 ,0 ,0 , 0, 0 ,0
152 ,0 },
153 {WINED3DFMT_R8G8_B8G8 ,0 ,0 , 0, 0 ,0
154 ,0 },
155 /* IEEE formats */
156 {WINED3DFMT_R32F ,GL_RGB32F_ARB ,GL_RGB32F_ARB , 0, GL_RED ,GL_FLOAT
157 ,WINED3DFMT_FLAG_RENDERTARGET },
158 {WINED3DFMT_G32R32F ,0 ,0 , 0, 0 ,0
159 ,WINED3DFMT_FLAG_RENDERTARGET },
160 {WINED3DFMT_A32B32G32R32F ,GL_RGBA32F_ARB ,GL_RGBA32F_ARB , 0, GL_RGBA ,GL_FLOAT
161 ,WINED3DFMT_FLAG_RENDERTARGET },
162 /* Hmm? */
163 {WINED3DFMT_CxV8U8 ,0 ,0 , 0, 0 ,0
164 ,0 },
165 /* Float */
166 {WINED3DFMT_R16F ,GL_RGB16F_ARB ,GL_RGB16F_ARB , 0, GL_RED ,GL_HALF_FLOAT_ARB
167 ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
168 {WINED3DFMT_G16R16F ,0 ,0 , 0, 0 ,0
169 ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
170 {WINED3DFMT_A16B16G16R16F ,GL_RGBA16F_ARB ,GL_RGBA16F_ARB , 0, GL_RGBA ,GL_HALF_FLOAT_ARB
171 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
172 /* Palettized formats */
173 {WINED3DFMT_A8P8, 0 ,0 , 0, 0 ,0
174 ,0 },
175 {WINED3DFMT_P8, GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX8_EXT , 0, GL_COLOR_INDEX ,GL_UNSIGNED_BYTE
176 ,0 },
177 /* Standard ARGB formats */
178 {WINED3DFMT_R8G8B8 ,GL_RGB8 ,GL_RGB8 , 0, GL_BGR ,GL_UNSIGNED_BYTE
179 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
180 {WINED3DFMT_A8R8G8B8 ,GL_RGBA8 ,GL_SRGB8_ALPHA8_EXT , 0, GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV
181 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
182 {WINED3DFMT_X8R8G8B8 ,GL_RGB8 ,GL_SRGB8_EXT , 0, GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV
183 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
184 {WINED3DFMT_R5G6B5 ,GL_RGB5 ,GL_RGB5 , GL_RGB8, GL_RGB ,GL_UNSIGNED_SHORT_5_6_5
185 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
186 {WINED3DFMT_X1R5G5B5 ,GL_RGB5 ,GL_RGB5_A1 , 0, GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV
187 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING },
188 {WINED3DFMT_A1R5G5B5 ,GL_RGB5_A1 ,GL_RGB5_A1 , 0, GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV
189 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING },
190 {WINED3DFMT_A4R4G4B4 ,GL_RGBA4 ,GL_SRGB8_ALPHA8_EXT , 0, GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV
191 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING },
192 {WINED3DFMT_R3G3B2 ,GL_R3_G3_B2 ,GL_R3_G3_B2 , 0, GL_RGB ,GL_UNSIGNED_BYTE_3_3_2
193 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING },
194 {WINED3DFMT_A8 ,GL_ALPHA8 ,GL_ALPHA8 , 0, GL_ALPHA ,GL_UNSIGNED_BYTE
195 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING },
196 {WINED3DFMT_A8R3G3B2 ,0 ,0 , 0, 0 ,0
197 ,0 },
198 {WINED3DFMT_X4R4G4B4 ,GL_RGB4 ,GL_RGB4 , 0, GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV
199 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
200 {WINED3DFMT_A2B10G10R10 ,GL_RGBA ,GL_RGBA , 0, GL_RGBA ,GL_UNSIGNED_INT_2_10_10_10_REV
201 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
202 {WINED3DFMT_A8B8G8R8 ,GL_RGBA8 ,GL_RGBA8 , 0, GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV
203 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
204 {WINED3DFMT_X8B8G8R8 ,GL_RGB8 ,GL_RGB8 , 0, GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV
205 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
206 {WINED3DFMT_G16R16 ,GL_RGB16_EXT ,GL_RGB16_EXT , 0, GL_RGB ,GL_UNSIGNED_SHORT
207 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING },
208 {WINED3DFMT_A2R10G10B10 ,GL_RGBA ,GL_RGBA , 0, GL_BGRA ,GL_UNSIGNED_INT_2_10_10_10_REV
209 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING },
210 {WINED3DFMT_A16B16G16R16 ,GL_RGBA16_EXT ,GL_RGBA16_EXT , 0, GL_RGBA ,GL_UNSIGNED_SHORT
211 ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
212 /* Luminance */
213 {WINED3DFMT_L8 ,GL_LUMINANCE8 ,GL_SLUMINANCE8_EXT , 0, GL_LUMINANCE ,GL_UNSIGNED_BYTE
214 ,WINED3DFMT_FLAG_FILTERING },
215 {WINED3DFMT_A8L8 ,GL_LUMINANCE8_ALPHA8 ,GL_SLUMINANCE8_ALPHA8_EXT , 0, GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE
216 ,WINED3DFMT_FLAG_FILTERING },
217 {WINED3DFMT_A4L4 ,GL_LUMINANCE4_ALPHA4 ,GL_LUMINANCE4_ALPHA4 , 0, GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE
218 ,0 },
219 /* Bump mapping stuff */
220 {WINED3DFMT_V8U8 ,GL_DSDT8_NV ,GL_DSDT8_NV , 0, GL_DSDT_NV ,GL_BYTE
221 ,WINED3DFMT_FLAG_FILTERING },
222 {WINED3DFMT_L6V5U5 ,GL_DSDT8_MAG8_NV ,GL_DSDT8_MAG8_NV , 0, GL_DSDT_MAG_NV ,GL_BYTE
223 ,WINED3DFMT_FLAG_FILTERING },
224 {WINED3DFMT_X8L8V8U8 ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT8_MAG8_INTENSITY8_NV , 0, GL_DSDT_MAG_VIB_NV ,GL_UNSIGNED_INT_8_8_S8_S8_REV_NV
225 ,WINED3DFMT_FLAG_FILTERING },
226 {WINED3DFMT_Q8W8V8U8 ,GL_SIGNED_RGBA8_NV ,GL_SIGNED_RGBA8_NV , 0, GL_RGBA ,GL_BYTE
227 ,WINED3DFMT_FLAG_FILTERING },
228 {WINED3DFMT_V16U16 ,GL_SIGNED_HILO16_NV ,GL_SIGNED_HILO16_NV , 0, GL_HILO_NV ,GL_SHORT
229 ,WINED3DFMT_FLAG_FILTERING },
230 {WINED3DFMT_W11V11U10 ,0 ,0 , 0, 0 ,0
231 ,0 },
232 {WINED3DFMT_A2W10V10U10 ,0 ,0 , 0, 0 ,0
233 ,0 },
234 /* Depth stencil formats */
235 {WINED3DFMT_D16_LOCKABLE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT
236 ,WINED3DFMT_FLAG_DEPTH },
237 {WINED3DFMT_D32 ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT32_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT
238 ,WINED3DFMT_FLAG_DEPTH },
239 {WINED3DFMT_D15S1 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT
240 ,WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL },
241 {WINED3DFMT_D24S8 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT
242 ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL },
243 {WINED3DFMT_D24X8 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT
244 ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH },
245 {WINED3DFMT_D24X4S4 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT
246 ,WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL },
247 {WINED3DFMT_D16 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT
248 ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH },
249 {WINED3DFMT_L16 ,GL_LUMINANCE16_EXT ,GL_LUMINANCE16_EXT , 0, GL_LUMINANCE ,GL_UNSIGNED_SHORT
250 ,WINED3DFMT_FLAG_FILTERING },
251 {WINED3DFMT_D32F_LOCKABLE ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT32_ARB , 0, GL_DEPTH_COMPONENT ,GL_FLOAT
252 ,WINED3DFMT_FLAG_DEPTH },
253 {WINED3DFMT_D24FS8 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB , 0, GL_DEPTH_COMPONENT ,GL_FLOAT
254 ,WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
255 /* Is this a vertex buffer? */
256 {WINED3DFMT_VERTEXDATA ,0 ,0 , 0, 0 ,0
257 ,0 },
258 {WINED3DFMT_INDEX16 ,0 ,0 , 0, 0 ,0
259 ,0 },
260 {WINED3DFMT_INDEX32 ,0 ,0 , 0, 0 ,0
261 ,0 },
262 {WINED3DFMT_Q16W16V16U16 ,GL_COLOR_INDEX ,GL_COLOR_INDEX , 0, GL_COLOR_INDEX ,GL_UNSIGNED_SHORT
263 ,0 }
266 static inline int getFmtIdx(WINED3DFORMAT fmt) {
267 /* First check if the format is at the position of its value.
268 * This will catch the argb formats before the loop is entered
270 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
271 return fmt;
272 } else {
273 unsigned int i;
274 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
275 if(formats[i].format == fmt) {
276 return i;
280 return -1;
283 #define GLINFO_LOCATION (*gl_info)
284 BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
286 unsigned int src;
287 int dst;
289 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
290 sizeof(formats) / sizeof(formats[0]) * sizeof(gl_info->gl_formats[0]));
291 if(!gl_info->gl_formats) return FALSE;
293 /* If a format depends on some extensions, remove them from the table above and initialize them
294 * after this loop
296 for(src = 0; src < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); src++) {
297 dst = getFmtIdx(gl_formats_template[src].fmt);
298 gl_info->gl_formats[dst].glInternal = gl_formats_template[src].glInternal;
299 gl_info->gl_formats[dst].glGammaInternal = gl_formats_template[src].glGammaInternal;
300 gl_info->gl_formats[dst].glFormat = gl_formats_template[src].glFormat;
301 gl_info->gl_formats[dst].glType = gl_formats_template[src].glType;
302 gl_info->gl_formats[dst].conversion_group= WINED3DFMT_UNKNOWN;
303 gl_info->gl_formats[dst].Flags = gl_formats_template[src].Flags;
305 if(wined3d_settings.offscreen_rendering_mode == ORM_FBO &&
306 gl_formats_template[src].rtInternal != 0) {
307 GLuint tex, fb;
308 GLenum status;
310 /* Check if the default internal format is supported as a frame buffer target, otherwise
311 * fall back to the render target internal.
313 * Try to stick to the standard format if possible, this limits precision differences
315 while(glGetError());
316 glGenTextures(1, &tex);
317 glBindTexture(GL_TEXTURE_2D, tex);
318 glTexImage2D(GL_TEXTURE_2D, 0, gl_formats_template[src].glInternal, 16, 16, 0,
319 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
321 GL_EXTCALL(glGenFramebuffersEXT(1, &fb));
322 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb));
323 GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
324 GL_TEXTURE_2D, tex, 0));
326 status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
327 GL_EXTCALL(glDeleteFramebuffersEXT(1, &fb));
328 glDeleteTextures(1, &tex);
330 checkGLcall("Framebuffer format check");
332 if(status != GL_FRAMEBUFFER_COMPLETE_EXT) {
333 TRACE("Internal format of %s not supported as frame buffer target, using render target internal instead\n",
334 debug_d3dformat(gl_formats_template[src].fmt));
335 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].rtInternal;
336 } else {
337 TRACE("Format %s is supported as fbo target\n", debug_d3dformat(gl_formats_template[src].fmt));
338 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].glInternal;
341 } else {
342 gl_info->gl_formats[dst].rtInternal = gl_formats_template[src].glInternal;
346 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
347 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
348 * their extensions are not available.
350 * In theory, V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
351 * returns 0.0 when sampling from it, DirectX 1.0. This is disabled until we find
352 * an application that needs this because it causes performance problems due to
353 * shader recompiling in some games.
355 if(!GL_SUPPORT(ATI_ENVMAP_BUMPMAP) && !GL_SUPPORT(NV_TEXTURE_SHADER2)) {
356 /* signed -> unsigned fixup */
357 dst = getFmtIdx(WINED3DFMT_V8U8);
358 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
359 dst = getFmtIdx(WINED3DFMT_V16U16);
360 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
361 } else if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
362 /* signed -> unsigned fixup */
363 dst = getFmtIdx(WINED3DFMT_V16U16);
364 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V16U16;
365 } else {
366 /* Blue = 1.0 fixup, disabled for now */
367 #if 0
368 dst = getFmtIdx(WINED3DFMT_V8U8);
369 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
370 dst = getFmtIdx(WINED3DFMT_V16U16);
371 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
372 #endif
375 if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
376 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
377 * with each other
379 dst = getFmtIdx(WINED3DFMT_L6V5U5);
380 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_L6V5U5;
381 dst = getFmtIdx(WINED3DFMT_X8L8V8U8);
382 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_X8L8V8U8;
383 dst = getFmtIdx(WINED3DFMT_Q8W8V8U8);
384 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_Q8W8V8U8;
385 } else {
386 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
387 * are converted at surface loading time, but they do not need any modification in
388 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
389 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
393 return TRUE;
396 /* NOTE: Make sure these are in the correct numerical order. (see /include/wined3d_types.h) */
397 static WINED3DGLTYPE const glTypeLookupTemplate[WINED3DDECLTYPE_UNUSED] = {
398 {WINED3DDECLTYPE_FLOAT1, 1, GL_FLOAT , GL_FALSE ,sizeof(float)},
399 {WINED3DDECLTYPE_FLOAT2, 2, GL_FLOAT , GL_FALSE ,sizeof(float)},
400 {WINED3DDECLTYPE_FLOAT3, 3, GL_FLOAT , GL_FALSE ,sizeof(float)},
401 {WINED3DDECLTYPE_FLOAT4, 4, GL_FLOAT , GL_FALSE ,sizeof(float)},
402 {WINED3DDECLTYPE_D3DCOLOR, 4, GL_UNSIGNED_BYTE , GL_TRUE ,sizeof(BYTE)},
403 {WINED3DDECLTYPE_UBYTE4, 4, GL_UNSIGNED_BYTE , GL_FALSE ,sizeof(BYTE)},
404 {WINED3DDECLTYPE_SHORT2, 2, GL_SHORT , GL_FALSE ,sizeof(short int)},
405 {WINED3DDECLTYPE_SHORT4, 4, GL_SHORT , GL_FALSE ,sizeof(short int)},
406 {WINED3DDECLTYPE_UBYTE4N, 4, GL_UNSIGNED_BYTE , GL_TRUE ,sizeof(BYTE)},
407 {WINED3DDECLTYPE_SHORT2N, 2, GL_SHORT , GL_TRUE ,sizeof(short int)},
408 {WINED3DDECLTYPE_SHORT4N, 4, GL_SHORT , GL_TRUE ,sizeof(short int)},
409 {WINED3DDECLTYPE_USHORT2N, 2, GL_UNSIGNED_SHORT , GL_TRUE ,sizeof(short int)},
410 {WINED3DDECLTYPE_USHORT4N, 4, GL_UNSIGNED_SHORT , GL_TRUE ,sizeof(short int)},
411 {WINED3DDECLTYPE_UDEC3, 3, GL_UNSIGNED_SHORT , GL_FALSE ,sizeof(short int)},
412 {WINED3DDECLTYPE_DEC3N, 3, GL_SHORT , GL_TRUE ,sizeof(short int)},
413 {WINED3DDECLTYPE_FLOAT16_2, 2, GL_HALF_FLOAT_NV , GL_FALSE ,sizeof(GLhalfNV)},
414 {WINED3DDECLTYPE_FLOAT16_4, 4, GL_HALF_FLOAT_NV , GL_FALSE ,sizeof(GLhalfNV)}};
416 void init_type_lookup(WineD3D_GL_Info *gl_info) {
417 memcpy(gl_info->glTypeLookup, glTypeLookupTemplate, sizeof(glTypeLookupTemplate));
418 if(!GL_SUPPORT(NV_HALF_FLOAT)) {
419 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
420 * It is the job of the vertex buffer code to make sure that the vbos have the right format
422 gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_2].glType = GL_FLOAT;
423 gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_4].glType = GL_FLOAT;
427 #undef GLINFO_LOCATION
429 #define GLINFO_LOCATION This->adapter->gl_info
431 const StaticPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, WineD3D_GL_Info *gl_info, const GlPixelFormatDesc **glDesc)
433 int idx = getFmtIdx(fmt);
435 if(idx == -1) {
436 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
437 /* Get the caller a valid pointer */
438 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
440 if(glDesc) {
441 if(!gl_info->gl_formats) {
442 /* If we do not have gl format information, provide a dummy NULL format. This is an easy way to make
443 * all gl caps check return "unsupported" than catching the lack of gl all over the code. ANSI C requires
444 * static variables to be initialized to 0.
446 static const GlPixelFormatDesc dummyFmt;
447 *glDesc = &dummyFmt;
448 } else {
449 *glDesc = &gl_info->gl_formats[idx];
452 return &formats[idx];
455 /*****************************************************************************
456 * Trace formatting of useful values
458 const char* debug_d3dformat(WINED3DFORMAT fmt) {
459 switch (fmt) {
460 #define FMT_TO_STR(fmt) case fmt: return #fmt
461 FMT_TO_STR(WINED3DFMT_UNKNOWN);
462 FMT_TO_STR(WINED3DFMT_R8G8B8);
463 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
464 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
465 FMT_TO_STR(WINED3DFMT_R5G6B5);
466 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
467 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
468 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
469 FMT_TO_STR(WINED3DFMT_R3G3B2);
470 FMT_TO_STR(WINED3DFMT_A8);
471 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
472 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
473 FMT_TO_STR(WINED3DFMT_A2B10G10R10);
474 FMT_TO_STR(WINED3DFMT_A8B8G8R8);
475 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
476 FMT_TO_STR(WINED3DFMT_G16R16);
477 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
478 FMT_TO_STR(WINED3DFMT_A16B16G16R16);
479 FMT_TO_STR(WINED3DFMT_A8P8);
480 FMT_TO_STR(WINED3DFMT_P8);
481 FMT_TO_STR(WINED3DFMT_L8);
482 FMT_TO_STR(WINED3DFMT_A8L8);
483 FMT_TO_STR(WINED3DFMT_A4L4);
484 FMT_TO_STR(WINED3DFMT_V8U8);
485 FMT_TO_STR(WINED3DFMT_L6V5U5);
486 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
487 FMT_TO_STR(WINED3DFMT_Q8W8V8U8);
488 FMT_TO_STR(WINED3DFMT_V16U16);
489 FMT_TO_STR(WINED3DFMT_W11V11U10);
490 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
491 FMT_TO_STR(WINED3DFMT_UYVY);
492 FMT_TO_STR(WINED3DFMT_YUY2);
493 FMT_TO_STR(WINED3DFMT_DXT1);
494 FMT_TO_STR(WINED3DFMT_DXT2);
495 FMT_TO_STR(WINED3DFMT_DXT3);
496 FMT_TO_STR(WINED3DFMT_DXT4);
497 FMT_TO_STR(WINED3DFMT_DXT5);
498 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
499 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
500 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
501 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
502 FMT_TO_STR(WINED3DFMT_D32);
503 FMT_TO_STR(WINED3DFMT_D15S1);
504 FMT_TO_STR(WINED3DFMT_D24S8);
505 FMT_TO_STR(WINED3DFMT_D24X8);
506 FMT_TO_STR(WINED3DFMT_D24X4S4);
507 FMT_TO_STR(WINED3DFMT_D16);
508 FMT_TO_STR(WINED3DFMT_L16);
509 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
510 FMT_TO_STR(WINED3DFMT_D24FS8);
511 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
512 FMT_TO_STR(WINED3DFMT_INDEX16);
513 FMT_TO_STR(WINED3DFMT_INDEX32);
514 FMT_TO_STR(WINED3DFMT_Q16W16V16U16);
515 FMT_TO_STR(WINED3DFMT_R16F);
516 FMT_TO_STR(WINED3DFMT_G16R16F);
517 FMT_TO_STR(WINED3DFMT_A16B16G16R16F);
518 FMT_TO_STR(WINED3DFMT_R32F);
519 FMT_TO_STR(WINED3DFMT_G32R32F);
520 FMT_TO_STR(WINED3DFMT_A32B32G32R32F);
521 FMT_TO_STR(WINED3DFMT_CxV8U8);
522 #undef FMT_TO_STR
523 default:
525 char fourcc[5];
526 fourcc[0] = (char)(fmt);
527 fourcc[1] = (char)(fmt >> 8);
528 fourcc[2] = (char)(fmt >> 16);
529 fourcc[3] = (char)(fmt >> 24);
530 fourcc[4] = 0;
531 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
532 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
533 else
534 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
536 return "unrecognized";
540 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
541 switch (devtype) {
542 #define DEVTYPE_TO_STR(dev) case dev: return #dev
543 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
544 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
545 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
546 #undef DEVTYPE_TO_STR
547 default:
548 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
549 return "unrecognized";
553 const char* debug_d3dusage(DWORD usage) {
554 switch (usage & WINED3DUSAGE_MASK) {
555 #define WINED3DUSAGE_TO_STR(u) case u: return #u
556 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
557 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
558 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
559 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
560 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
561 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
562 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
563 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
564 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
565 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
566 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
567 #undef WINED3DUSAGE_TO_STR
568 case 0: return "none";
569 default:
570 FIXME("Unrecognized %u Usage!\n", usage);
571 return "unrecognized";
575 const char* debug_d3dusagequery(DWORD usagequery) {
576 switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
577 #define WINED3DUSAGEQUERY_TO_STR(u) case u: return #u
578 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
579 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
580 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
581 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
582 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
583 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
584 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
585 #undef WINED3DUSAGEQUERY_TO_STR
586 case 0: return "none";
587 default:
588 FIXME("Unrecognized %u Usage Query!\n", usagequery);
589 return "unrecognized";
593 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
594 switch (method) {
595 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
596 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
597 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
598 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
599 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
600 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
601 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
602 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
603 #undef WINED3DDECLMETHOD_TO_STR
604 default:
605 FIXME("Unrecognized %u declaration method!\n", method);
606 return "unrecognized";
610 const char* debug_d3ddecltype(WINED3DDECLTYPE type) {
611 switch (type) {
612 #define WINED3DDECLTYPE_TO_STR(u) case u: return #u
613 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT1);
614 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT2);
615 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT3);
616 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT4);
617 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_D3DCOLOR);
618 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4);
619 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2);
620 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4);
621 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4N);
622 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2N);
623 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4N);
624 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT2N);
625 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT4N);
626 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UDEC3);
627 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_DEC3N);
628 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_2);
629 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_4);
630 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UNUSED);
631 #undef WINED3DDECLTYPE_TO_STR
632 default:
633 FIXME("Unrecognized %u declaration type!\n", type);
634 return "unrecognized";
638 const char* debug_d3ddeclusage(BYTE usage) {
639 switch (usage) {
640 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
641 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
642 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
643 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
644 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
645 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
646 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
647 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
648 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
649 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
650 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
651 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
652 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
653 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
654 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
655 #undef WINED3DDECLUSAGE_TO_STR
656 default:
657 FIXME("Unrecognized %u declaration usage!\n", usage);
658 return "unrecognized";
662 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
663 switch (res) {
664 #define RES_TO_STR(res) case res: return #res;
665 RES_TO_STR(WINED3DRTYPE_SURFACE);
666 RES_TO_STR(WINED3DRTYPE_VOLUME);
667 RES_TO_STR(WINED3DRTYPE_TEXTURE);
668 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
669 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
670 RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER);
671 RES_TO_STR(WINED3DRTYPE_INDEXBUFFER);
672 #undef RES_TO_STR
673 default:
674 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
675 return "unrecognized";
679 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
680 switch (PrimitiveType) {
681 #define PRIM_TO_STR(prim) case prim: return #prim;
682 PRIM_TO_STR(WINED3DPT_POINTLIST);
683 PRIM_TO_STR(WINED3DPT_LINELIST);
684 PRIM_TO_STR(WINED3DPT_LINESTRIP);
685 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
686 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
687 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
688 #undef PRIM_TO_STR
689 default:
690 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
691 return "unrecognized";
695 const char* debug_d3drenderstate(DWORD state) {
696 switch (state) {
697 #define D3DSTATE_TO_STR(u) case u: return #u
698 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
699 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
700 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
701 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
702 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
703 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
704 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
705 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
706 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
707 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
708 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
709 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
710 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
711 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
712 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
713 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
714 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
715 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
716 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
717 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
718 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
719 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
720 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
721 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
722 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
723 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
724 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
725 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
726 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
727 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
728 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
729 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
730 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
731 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
732 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
733 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
734 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
735 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
736 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
737 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
738 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
739 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
740 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
741 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
742 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
743 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
744 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
745 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
746 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
747 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
748 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
749 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
750 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
751 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
752 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
753 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
754 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
755 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
756 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
757 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
758 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
759 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
760 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
761 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
762 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
763 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
764 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
765 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
766 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
767 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
768 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
769 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
770 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
771 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
772 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
773 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
774 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
775 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
776 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
777 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
778 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
779 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
780 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
781 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
782 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
783 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
784 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
785 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
786 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
787 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
788 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
789 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
790 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
791 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
792 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
793 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
794 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
795 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
796 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
797 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
798 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
799 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
800 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
801 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
802 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
803 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
804 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
805 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
806 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
807 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
808 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
809 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
810 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
811 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
812 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
813 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
814 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
815 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
816 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
817 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
818 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
819 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
820 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
821 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
822 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
823 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
824 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
825 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
826 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
827 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
828 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
829 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
830 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
831 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
832 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
833 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
834 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
835 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
836 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
837 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
838 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
839 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
840 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
841 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
842 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
843 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
844 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
845 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
846 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
847 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
848 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
849 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
850 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
851 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
852 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
853 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
854 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
855 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
856 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
857 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
858 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
859 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
860 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
861 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
862 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
863 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
864 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
865 #undef D3DSTATE_TO_STR
866 default:
867 FIXME("Unrecognized %u render state!\n", state);
868 return "unrecognized";
872 const char* debug_d3dsamplerstate(DWORD state) {
873 switch (state) {
874 #define D3DSTATE_TO_STR(u) case u: return #u
875 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
876 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
877 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
878 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
879 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
880 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
881 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
882 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
883 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
884 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
885 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
886 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
887 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
888 #undef D3DSTATE_TO_STR
889 default:
890 FIXME("Unrecognized %u sampler state!\n", state);
891 return "unrecognized";
895 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
896 switch (filter_type) {
897 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
898 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
899 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
900 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
901 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
902 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
903 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
904 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
905 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
906 #undef D3DTEXTUREFILTERTYPE_TO_STR
907 default:
908 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
909 return "unrecognized";
913 const char* debug_d3dtexturestate(DWORD state) {
914 switch (state) {
915 #define D3DSTATE_TO_STR(u) case u: return #u
916 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
917 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
918 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
919 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
920 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
921 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
922 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
923 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
924 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
925 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
926 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
927 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
928 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
929 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
930 D3DSTATE_TO_STR(WINED3DTSS_ADDRESSW );
931 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
932 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
933 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
934 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
935 #undef D3DSTATE_TO_STR
936 case 12:
937 /* Note WINED3DTSS are not consecutive, so skip these */
938 return "unused";
939 default:
940 FIXME("Unrecognized %u texture state!\n", state);
941 return "unrecognized";
945 static const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
946 switch (d3dtop) {
947 #define D3DTOP_TO_STR(u) case u: return #u
948 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
949 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
950 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
951 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
952 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
953 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
954 D3DTOP_TO_STR(WINED3DTOP_ADD);
955 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
956 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED2X);
957 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
958 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
959 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
960 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
961 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
962 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
963 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
964 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
965 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
966 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
967 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
968 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
969 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
970 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
971 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
972 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
973 D3DTOP_TO_STR(WINED3DTOP_LERP);
974 #undef D3DTOP_TO_STR
975 default:
976 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
977 return "unrecognized";
981 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
982 switch (tstype) {
983 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
984 TSTYPE_TO_STR(WINED3DTS_VIEW);
985 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
986 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
987 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
988 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
989 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
990 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
991 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
992 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
993 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
994 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
995 #undef TSTYPE_TO_STR
996 default:
997 if (tstype > 256 && tstype < 512) {
998 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
999 return ("WINED3DTS_WORLDMATRIX > 0");
1001 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1002 return "unrecognized";
1006 const char* debug_d3dpool(WINED3DPOOL Pool) {
1007 switch (Pool) {
1008 #define POOL_TO_STR(p) case p: return #p;
1009 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1010 POOL_TO_STR(WINED3DPOOL_MANAGED);
1011 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1012 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1013 #undef POOL_TO_STR
1014 default:
1015 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1016 return "unrecognized";
1020 const char *debug_fbostatus(GLenum status) {
1021 switch(status) {
1022 #define FBOSTATUS_TO_STR(u) case u: return #u
1023 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1024 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1025 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1026 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1027 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1028 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1029 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1030 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1031 #undef FBOSTATUS_TO_STR
1032 default:
1033 FIXME("Unrecognied FBO status 0x%08x\n", status);
1034 return "unrecognized";
1038 const char *debug_glerror(GLenum error) {
1039 switch(error) {
1040 #define GLERROR_TO_STR(u) case u: return #u
1041 GLERROR_TO_STR(GL_NO_ERROR);
1042 GLERROR_TO_STR(GL_INVALID_ENUM);
1043 GLERROR_TO_STR(GL_INVALID_VALUE);
1044 GLERROR_TO_STR(GL_INVALID_OPERATION);
1045 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1046 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1047 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1048 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1049 #undef GLERROR_TO_STR
1050 default:
1051 FIXME("Unrecognied GL error 0x%08x\n", error);
1052 return "unrecognized";
1056 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1057 switch(basis) {
1058 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1059 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1060 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1061 default: return "unrecognized";
1065 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1066 switch(degree) {
1067 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1068 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1069 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1070 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1071 default: return "unrecognized";
1075 /*****************************************************************************
1076 * Useful functions mapping GL <-> D3D values
1078 GLenum StencilOp(DWORD op) {
1079 switch(op) {
1080 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1081 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1082 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1083 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1084 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1085 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1086 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1087 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1088 default:
1089 FIXME("Unrecognized stencil op %d\n", op);
1090 return GL_KEEP;
1094 GLenum CompareFunc(DWORD func) {
1095 switch ((WINED3DCMPFUNC)func) {
1096 case WINED3DCMP_NEVER : return GL_NEVER;
1097 case WINED3DCMP_LESS : return GL_LESS;
1098 case WINED3DCMP_EQUAL : return GL_EQUAL;
1099 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1100 case WINED3DCMP_GREATER : return GL_GREATER;
1101 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1102 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1103 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1104 default:
1105 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1106 return 0;
1110 static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) {
1111 switch (d3dta) {
1112 case WINED3DTA_DIFFUSE:
1113 return GL_PRIMARY_COLOR_NV;
1115 case WINED3DTA_CURRENT:
1116 if (stage) return GL_SPARE0_NV;
1117 else return GL_PRIMARY_COLOR_NV;
1119 case WINED3DTA_TEXTURE:
1120 if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx;
1121 else return GL_PRIMARY_COLOR_NV;
1123 case WINED3DTA_TFACTOR:
1124 return GL_CONSTANT_COLOR0_NV;
1126 case WINED3DTA_SPECULAR:
1127 return GL_SECONDARY_COLOR_NV;
1129 case WINED3DTA_TEMP:
1130 return GL_SPARE1_NV;
1132 case WINED3DTA_CONSTANT:
1133 /* TODO: Support per stage constants (WINED3DTSS_CONSTANT, NV_register_combiners2) */
1134 FIXME("WINED3DTA_CONSTANT, not properly supported.\n");
1135 return GL_CONSTANT_COLOR1_NV;
1137 default:
1138 FIXME("Unrecognized texture arg %#x\n", d3dta);
1139 return GL_TEXTURE;
1143 static GLenum invert_mapping(GLenum mapping) {
1144 if (mapping == GL_UNSIGNED_INVERT_NV) return GL_SIGNED_IDENTITY_NV;
1145 else if (mapping == GL_SIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV;
1147 FIXME("Unhandled mapping %#x\n", mapping);
1148 return mapping;
1151 static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) {
1152 /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should
1153 * be used. */
1154 if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV;
1155 else *mapping = GL_SIGNED_IDENTITY_NV;
1157 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input
1158 * should be used for all input components. */
1159 if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA;
1160 else *component_usage = GL_RGB;
1162 *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx);
1165 typedef struct {
1166 GLenum input[3];
1167 GLenum mapping[3];
1168 GLenum component_usage[3];
1169 } tex_op_args;
1171 static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1172 if (op == WINED3DTOP_DISABLE) return FALSE;
1173 if (This->stateBlock->textures[stage]) return FALSE;
1175 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1176 && op != WINED3DTOP_SELECTARG2) return TRUE;
1177 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1178 && op != WINED3DTOP_SELECTARG1) return TRUE;
1179 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1180 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1182 return FALSE;
1185 void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst) {
1186 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface;
1187 tex_op_args tex_op_args = {{0}, {0}, {0}};
1188 GLenum portion = is_alpha ? GL_ALPHA : GL_RGB;
1189 GLenum target = GL_COMBINER0_NV + stage;
1190 GLenum output;
1192 TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1193 stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx);
1195 /* If a texture stage references an invalid texture unit the stage just
1196 * passes through the result from the previous stage */
1197 if (is_invalid_op(This, stage, op, arg1, arg2, arg3)) {
1198 arg1 = WINED3DTA_CURRENT;
1199 op = WINED3DTOP_SELECTARG1;
1202 get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0],
1203 &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx);
1204 get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1],
1205 &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx);
1206 get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2],
1207 &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx);
1210 if(dst == WINED3DTA_TEMP) {
1211 output = GL_SPARE1_NV;
1212 } else {
1213 output = GL_SPARE0_NV;
1216 /* This is called by a state handler which has the gl lock held and a context for the thread */
1217 switch(op)
1219 case WINED3DTOP_DISABLE:
1220 /* Only for alpha */
1221 if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n");
1222 /* Input, prev_alpha*1 */
1223 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1224 GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
1225 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1226 GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
1228 /* Output */
1229 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1230 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1231 break;
1233 case WINED3DTOP_SELECTARG1:
1234 case WINED3DTOP_SELECTARG2:
1235 /* Input, arg*1 */
1236 if (op == WINED3DTOP_SELECTARG1) {
1237 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1238 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1239 } else {
1240 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1241 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1243 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1244 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1246 /* Output */
1247 GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
1248 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1249 break;
1251 case WINED3DTOP_MODULATE:
1252 case WINED3DTOP_MODULATE2X:
1253 case WINED3DTOP_MODULATE4X:
1254 /* Input, arg1*arg2 */
1255 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1256 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1257 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1258 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1260 /* Output */
1261 if (op == WINED3DTOP_MODULATE) {
1262 GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
1263 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1264 } else if (op == WINED3DTOP_MODULATE2X) {
1265 GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
1266 GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1267 } else if (op == WINED3DTOP_MODULATE4X) {
1268 GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
1269 GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1271 break;
1273 case WINED3DTOP_ADD:
1274 case WINED3DTOP_ADDSIGNED:
1275 case WINED3DTOP_ADDSIGNED2X:
1276 /* Input, arg1*1+arg2*1 */
1277 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1278 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1279 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1280 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1281 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1282 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1283 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1284 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1286 /* Output */
1287 if (op == WINED3DTOP_ADD) {
1288 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1289 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1290 } else if (op == WINED3DTOP_ADDSIGNED) {
1291 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1292 output, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
1293 } else if (op == WINED3DTOP_ADDSIGNED2X) {
1294 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1295 output, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
1297 break;
1299 case WINED3DTOP_SUBTRACT:
1300 /* Input, arg1*1+-arg2*1 */
1301 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1302 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1303 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1304 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1305 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1306 tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1]));
1307 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1308 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1310 /* Output */
1311 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1312 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1313 break;
1315 case WINED3DTOP_ADDSMOOTH:
1316 /* Input, arg1*1+(1-arg1)*arg2 */
1317 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1318 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1319 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1320 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1321 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1322 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1323 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1324 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1326 /* Output */
1327 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1328 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1329 break;
1331 case WINED3DTOP_BLENDDIFFUSEALPHA:
1332 case WINED3DTOP_BLENDTEXTUREALPHA:
1333 case WINED3DTOP_BLENDFACTORALPHA:
1334 case WINED3DTOP_BLENDTEXTUREALPHAPM:
1335 case WINED3DTOP_BLENDCURRENTALPHA:
1337 GLenum alpha_src = GL_PRIMARY_COLOR_NV;
1338 if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx);
1339 else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
1340 else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx);
1341 else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
1342 else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx);
1343 else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op));
1345 /* Input, arg1*alpha_src+arg2*(1-alpha_src) */
1346 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1347 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1348 if (op == WINED3DTOP_BLENDTEXTUREALPHAPM)
1350 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1351 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1352 } else {
1353 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1354 alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
1356 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1357 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1358 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1359 alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
1361 /* Output */
1362 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1363 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1364 break;
1367 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1368 /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */
1369 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n");
1370 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1371 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1372 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1373 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1374 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1375 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1376 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1377 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1379 /* Output */
1380 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1381 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1382 break;
1384 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1385 /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */
1386 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n");
1387 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1388 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1389 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1390 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1391 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1392 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1393 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1394 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1396 /* Output */
1397 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1398 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1399 break;
1401 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1402 /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */
1403 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n");
1404 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1405 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA));
1406 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1407 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1408 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1409 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1410 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1411 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1413 /* Output */
1414 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1415 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1416 break;
1418 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1419 /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */
1420 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n");
1421 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1422 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1423 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1424 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1425 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1426 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1427 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1428 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1430 /* Output */
1431 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1432 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1433 break;
1435 case WINED3DTOP_DOTPRODUCT3:
1436 /* Input, arg1 . arg2 */
1437 /* FIXME: DX7 uses a different calculation? */
1438 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1439 tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0]));
1440 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1441 tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1]));
1443 /* Output */
1444 GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
1445 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE));
1446 break;
1448 case WINED3DTOP_MULTIPLYADD:
1449 /* Input, arg3*1+arg1*arg2 */
1450 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1451 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1452 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1453 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1454 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1455 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1456 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1457 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1459 /* Output */
1460 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1461 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1462 break;
1464 case WINED3DTOP_LERP:
1465 /* Input, arg3*arg1+(1-arg3)*arg2 */
1466 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1467 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1468 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1469 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1470 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1471 tex_op_args.input[2], invert_mapping(tex_op_args.mapping[2]), tex_op_args.component_usage[2]));
1472 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1473 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1475 /* Output */
1476 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1477 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1478 break;
1480 case WINED3DTOP_BUMPENVMAPLUMINANCE:
1481 case WINED3DTOP_BUMPENVMAP:
1482 if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
1483 /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to
1484 * perform bump mapping and source from the current stage. Pretty much a SELECTARG2.
1485 * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1
1486 * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the next stage
1488 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1489 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1490 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1491 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1492 /* Always pass through to CURRENT, ignore temp arg */
1493 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1494 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1495 break;
1498 default:
1499 FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1500 stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
1503 checkGLcall("set_tex_op_nvrc()\n");
1507 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
1508 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
1509 * input should be used for all input components. The WINED3DTA_COMPLEMENT
1510 * flag specifies the complement of the input should be used. */
1511 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
1512 BOOL complement = arg & WINED3DTA_COMPLEMENT;
1514 /* Calculate the operand */
1515 if (complement) {
1516 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
1517 else *operand = GL_ONE_MINUS_SRC_COLOR;
1518 } else {
1519 if (from_alpha) *operand = GL_SRC_ALPHA;
1520 else *operand = GL_SRC_COLOR;
1523 /* Calculate the source */
1524 switch (arg & WINED3DTA_SELECTMASK) {
1525 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
1526 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
1527 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
1528 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
1529 case WINED3DTA_SPECULAR:
1531 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
1532 * 'Secondary color' and isn't supported until base GL supports it
1533 * There is no concept of temp registers as far as I can tell
1535 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
1536 *source = GL_TEXTURE;
1537 break;
1538 default:
1539 FIXME("Unrecognized texture arg %#x\n", arg);
1540 *source = GL_TEXTURE;
1541 break;
1545 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
1546 #if defined (GL_VERSION_1_3)
1547 # define useext(A) A
1548 #elif defined (GL_EXT_texture_env_combine)
1549 # define useext(A) A##_EXT
1550 #elif defined (GL_ARB_texture_env_combine)
1551 # define useext(A) A##_ARB
1552 #endif
1554 /* Setup the texture operations texture stage states */
1555 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1557 GLenum src1, src2, src3;
1558 GLenum opr1, opr2, opr3;
1559 GLenum comb_target;
1560 GLenum src0_target, src1_target, src2_target;
1561 GLenum opr0_target, opr1_target, opr2_target;
1562 GLenum scal_target;
1563 GLenum opr=0, invopr, src3_target, opr3_target;
1564 BOOL Handled = FALSE;
1565 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
1567 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
1569 /* This is called by a state handler which has the gl lock held and a context for the thread */
1571 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
1572 the form (a1 <operation> a2). However, some of the more complex operations
1573 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
1574 in a third parameter called a0. Therefore these are operations of the form
1575 a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
1577 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
1578 functions below, expect their syntax to differ slightly to those listed in the
1579 manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
1580 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
1582 if (isAlpha) {
1583 comb_target = useext(GL_COMBINE_ALPHA);
1584 src0_target = useext(GL_SOURCE0_ALPHA);
1585 src1_target = useext(GL_SOURCE1_ALPHA);
1586 src2_target = useext(GL_SOURCE2_ALPHA);
1587 opr0_target = useext(GL_OPERAND0_ALPHA);
1588 opr1_target = useext(GL_OPERAND1_ALPHA);
1589 opr2_target = useext(GL_OPERAND2_ALPHA);
1590 scal_target = GL_ALPHA_SCALE;
1592 else {
1593 comb_target = useext(GL_COMBINE_RGB);
1594 src0_target = useext(GL_SOURCE0_RGB);
1595 src1_target = useext(GL_SOURCE1_RGB);
1596 src2_target = useext(GL_SOURCE2_RGB);
1597 opr0_target = useext(GL_OPERAND0_RGB);
1598 opr1_target = useext(GL_OPERAND1_RGB);
1599 opr2_target = useext(GL_OPERAND2_RGB);
1600 scal_target = useext(GL_RGB_SCALE);
1603 /* If a texture stage references an invalid texture unit the stage just
1604 * passes through the result from the previous stage */
1605 if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) {
1606 arg1 = WINED3DTA_CURRENT;
1607 op = WINED3DTOP_SELECTARG1;
1610 /* From MSDN (WINED3DTSS_ALPHAARG1) :
1611 The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage,
1612 then the default argument is WINED3DTA_DIFFUSE.
1613 FIXME? If texture added/removed, may need to reset back as well? */
1614 if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
1615 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
1616 } else {
1617 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
1619 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
1620 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
1622 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
1624 Handled = TRUE; /* Assume will be handled */
1626 /* Other texture operations require special extensions: */
1627 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1628 if (isAlpha) {
1629 opr = GL_SRC_ALPHA;
1630 invopr = GL_ONE_MINUS_SRC_ALPHA;
1631 src3_target = GL_SOURCE3_ALPHA_NV;
1632 opr3_target = GL_OPERAND3_ALPHA_NV;
1633 } else {
1634 opr = GL_SRC_COLOR;
1635 invopr = GL_ONE_MINUS_SRC_COLOR;
1636 src3_target = GL_SOURCE3_RGB_NV;
1637 opr3_target = GL_OPERAND3_RGB_NV;
1639 switch (op) {
1640 case WINED3DTOP_DISABLE: /* Only for alpha */
1641 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1642 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1643 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1644 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1645 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1646 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1647 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1648 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1649 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1650 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1651 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1652 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1653 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1654 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1655 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1656 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1657 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1658 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1659 break;
1660 case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */
1661 case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
1662 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1663 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1664 if (op == WINED3DTOP_SELECTARG1) {
1665 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1666 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1667 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1668 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1669 } else {
1670 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1671 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1672 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1673 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1675 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1676 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1677 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1678 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1679 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1680 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1681 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1682 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1683 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1684 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1685 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1686 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1687 break;
1689 case WINED3DTOP_MODULATE:
1690 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1691 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1692 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1693 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1694 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1695 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1696 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1697 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1698 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1699 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1700 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1701 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1702 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1703 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1704 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1705 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1706 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1707 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1708 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1709 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1710 break;
1711 case WINED3DTOP_MODULATE2X:
1712 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1713 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1714 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1715 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1716 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1717 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1718 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1719 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1720 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1721 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1722 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1723 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1724 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1725 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1726 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1727 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1728 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1729 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1730 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1731 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1732 break;
1733 case WINED3DTOP_MODULATE4X:
1734 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1735 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1736 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1737 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1738 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1739 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1740 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1741 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1742 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1743 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1744 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1745 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1746 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1747 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1748 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1749 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1750 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1751 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1752 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
1753 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
1754 break;
1756 case WINED3DTOP_ADD:
1757 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1758 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1759 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1760 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1761 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1762 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1763 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1764 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1765 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1766 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1767 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1768 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1769 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1770 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1771 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1772 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1773 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1774 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1775 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1776 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1777 break;
1779 case WINED3DTOP_ADDSIGNED:
1780 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1781 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1782 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1783 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1784 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1785 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1786 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1787 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1788 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1789 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1790 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1791 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1792 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1793 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1794 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1795 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1796 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1797 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1798 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1799 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1800 break;
1802 case WINED3DTOP_ADDSIGNED2X:
1803 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1804 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
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, GL_ZERO);
1810 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1811 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1812 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1813 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1814 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1815 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1816 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1817 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1818 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1819 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1820 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1821 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1822 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1823 break;
1825 case WINED3DTOP_ADDSMOOTH:
1826 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1827 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1828 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1829 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1830 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1831 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1832 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1833 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1834 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1835 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1836 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1837 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1838 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1839 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1840 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1841 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1842 switch (opr1) {
1843 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1844 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1845 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1846 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1848 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1849 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1850 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1851 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1852 break;
1854 case WINED3DTOP_BLENDDIFFUSEALPHA:
1855 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1856 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1857 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1858 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1859 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1860 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1861 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
1862 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
1863 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1864 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1865 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1866 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1867 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1868 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1869 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
1870 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
1871 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1872 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1873 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1874 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1875 break;
1876 case WINED3DTOP_BLENDTEXTUREALPHA:
1877 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1878 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1879 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1880 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1881 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1882 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1883 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
1884 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
1885 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1886 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1887 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1888 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1889 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1890 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1891 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1892 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1893 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1894 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1895 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1896 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1897 break;
1898 case WINED3DTOP_BLENDFACTORALPHA:
1899 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1900 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1901 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1902 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1903 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1904 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1905 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
1906 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
1907 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1908 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1909 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1910 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1911 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1912 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1913 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
1914 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
1915 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1916 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1917 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1918 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1919 break;
1920 case WINED3DTOP_BLENDTEXTUREALPHAPM:
1921 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1922 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1923 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1924 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1925 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1926 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1927 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1928 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1929 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1930 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1931 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1932 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1933 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1934 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1935 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1936 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1937 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1938 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1939 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1940 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1941 break;
1942 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1943 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1944 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1945 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
1946 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1947 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1948 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
1949 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1950 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1951 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1952 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1953 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
1954 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1955 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1956 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
1957 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1958 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1959 switch (opr) {
1960 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1961 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1963 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1964 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1965 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1966 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1967 break;
1968 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1969 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1970 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1971 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1972 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1973 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1974 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1975 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1976 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1977 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1978 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1979 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1980 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1981 switch (opr1) {
1982 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1983 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1985 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1986 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1987 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1988 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1989 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1990 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1991 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1992 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1993 break;
1994 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1995 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1996 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1997 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1998 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1999 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2000 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2001 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2002 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2003 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2004 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2005 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2006 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2007 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2008 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2009 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2010 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2011 switch (opr1) {
2012 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2013 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2014 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2015 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2017 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2018 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2019 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2020 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2021 break;
2022 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2023 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2024 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2025 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2026 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2027 switch (opr1) {
2028 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2029 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2030 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2031 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2033 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2034 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2035 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2036 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2037 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2038 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2039 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2040 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2041 switch (opr1) {
2042 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2043 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2045 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2046 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2047 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2048 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2049 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2050 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2051 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2052 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2053 break;
2054 case WINED3DTOP_MULTIPLYADD:
2055 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2056 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2057 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2058 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2059 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2060 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2061 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2062 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2063 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2064 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2065 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2066 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2067 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2068 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2069 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2070 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2071 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2072 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2073 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2074 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2075 break;
2077 case WINED3DTOP_BUMPENVMAP:
2081 case WINED3DTOP_BUMPENVMAPLUMINANCE:
2082 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2084 default:
2085 Handled = FALSE;
2087 if (Handled) {
2088 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2089 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2091 return;
2093 } /* GL_NV_texture_env_combine4 */
2095 Handled = TRUE; /* Again, assume handled */
2096 switch (op) {
2097 case WINED3DTOP_DISABLE: /* Only for alpha */
2098 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2099 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2100 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2101 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2102 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2103 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2104 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2105 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2106 break;
2107 case WINED3DTOP_SELECTARG1:
2108 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2109 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2110 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2111 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2112 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2113 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2114 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2115 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2116 break;
2117 case WINED3DTOP_SELECTARG2:
2118 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2119 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2120 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2121 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2122 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2123 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2124 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2125 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2126 break;
2127 case WINED3DTOP_MODULATE:
2128 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2129 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2130 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2131 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2132 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2133 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2134 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2135 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2136 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2137 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2138 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2139 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2140 break;
2141 case WINED3DTOP_MODULATE2X:
2142 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2143 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2144 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2145 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2146 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2147 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2148 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2149 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2150 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2151 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2152 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2153 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2154 break;
2155 case WINED3DTOP_MODULATE4X:
2156 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2157 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2158 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2159 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2160 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2161 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2162 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2163 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2164 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2165 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2166 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2167 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2168 break;
2169 case WINED3DTOP_ADD:
2170 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2171 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2172 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2173 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2174 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2175 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2176 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2177 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2178 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2179 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2180 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2181 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2182 break;
2183 case WINED3DTOP_ADDSIGNED:
2184 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2185 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
2186 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2187 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2188 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2189 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2190 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2191 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2192 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2193 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2194 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2195 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2196 break;
2197 case WINED3DTOP_ADDSIGNED2X:
2198 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2199 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2200 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2201 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2202 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2203 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2204 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2205 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2206 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2207 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2208 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2209 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2210 break;
2211 case WINED3DTOP_SUBTRACT:
2212 if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
2213 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2214 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
2215 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2216 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2217 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2218 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2219 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2220 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2221 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2222 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2223 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2224 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2225 } else {
2226 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2228 break;
2230 case WINED3DTOP_BLENDDIFFUSEALPHA:
2231 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2232 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2233 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2234 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2235 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2236 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2237 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2238 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2239 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2240 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2241 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
2242 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2243 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2244 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2245 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2246 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2247 break;
2248 case WINED3DTOP_BLENDTEXTUREALPHA:
2249 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2250 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2251 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2252 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2253 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2254 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2255 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2256 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2257 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2258 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2259 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2260 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2261 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2262 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2263 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2264 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2265 break;
2266 case WINED3DTOP_BLENDFACTORALPHA:
2267 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2268 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2269 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2270 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2271 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2272 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2273 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2274 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2275 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2276 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2277 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
2278 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2279 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2280 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2281 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2282 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2283 break;
2284 case WINED3DTOP_BLENDCURRENTALPHA:
2285 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2286 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2287 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2288 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2289 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2290 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2291 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2292 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2293 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2294 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2295 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
2296 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2297 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2298 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2299 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2300 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2301 break;
2302 case WINED3DTOP_DOTPRODUCT3:
2303 if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
2304 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2305 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2306 } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
2307 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2308 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2309 } else {
2310 FIXME("This version of opengl does not support GL_DOT3\n");
2312 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2313 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2314 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2315 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2316 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2317 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2318 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2319 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2320 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2321 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2322 break;
2323 case WINED3DTOP_LERP:
2324 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2325 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2326 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2327 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2328 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2329 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2330 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2331 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2332 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2333 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2334 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2335 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2336 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2337 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2338 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2339 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2340 break;
2341 case WINED3DTOP_ADDSMOOTH:
2342 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2343 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2344 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2345 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2346 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2347 switch (opr1) {
2348 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2349 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2350 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2351 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2353 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2354 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2355 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2356 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2357 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2358 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2359 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2360 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2361 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2362 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2363 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2364 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2365 } else
2366 Handled = FALSE;
2367 break;
2368 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2369 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2370 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2371 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2372 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2373 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2374 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2375 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2376 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2377 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2378 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2379 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2380 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2381 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2382 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2383 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2384 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2385 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2386 } else
2387 Handled = FALSE;
2388 break;
2389 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2390 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2391 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2392 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2393 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2394 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2395 switch (opr1) {
2396 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2397 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2398 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2399 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2401 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2402 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2403 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2404 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2405 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2406 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2407 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2408 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2409 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2410 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2411 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2412 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2413 } else
2414 Handled = FALSE;
2415 break;
2416 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2417 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2418 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2419 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2420 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2421 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2422 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2423 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2424 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2425 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2426 switch (opr1) {
2427 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2428 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2429 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2430 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2432 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2433 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2434 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2435 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2436 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2437 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2438 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2439 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2440 } else
2441 Handled = FALSE;
2442 break;
2443 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2444 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2445 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2446 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2447 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2448 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2449 switch (opr1) {
2450 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2451 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2452 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2453 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2455 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2456 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2457 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2458 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2459 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2460 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2461 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2462 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2463 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2464 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2465 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2466 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2467 } else
2468 Handled = FALSE;
2469 break;
2470 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2471 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2472 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2473 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2474 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2475 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2476 switch (opr1) {
2477 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2478 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2479 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2480 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2482 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2483 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2484 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2485 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2486 switch (opr1) {
2487 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2488 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2489 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2490 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2492 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2493 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2494 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2495 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2496 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2497 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2498 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2499 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2500 } else
2501 Handled = FALSE;
2502 break;
2503 case WINED3DTOP_MULTIPLYADD:
2504 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2505 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2506 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2507 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2508 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2509 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2510 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2511 glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
2512 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
2513 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
2514 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
2515 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2516 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2517 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2518 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2519 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2520 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2521 } else
2522 Handled = FALSE;
2523 break;
2524 case WINED3DTOP_BUMPENVMAPLUMINANCE:
2525 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2526 /* Some apps use BUMPENVMAPLUMINANCE instead of D3DTOP_BUMPENVMAP, although
2527 * they check for the non-luminance cap flag. Well, give them what they asked
2528 * for :-)
2530 WARN("Application uses WINED3DTOP_BUMPENVMAPLUMINANCE\n");
2531 } else {
2532 Handled = FALSE;
2533 break;
2535 /* Fall through */
2536 case WINED3DTOP_BUMPENVMAP:
2537 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2538 TRACE("Using ati bumpmap on stage %d, target %d\n", Stage, Stage + 1);
2539 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI);
2540 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI)");
2541 glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1);
2542 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1)");
2543 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2544 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2545 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2546 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2547 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2548 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2549 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2550 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2551 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2552 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2553 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2554 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2556 Handled = TRUE;
2557 break;
2558 } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2559 /* Technically texture shader support without register combiners is possible, but not expected to occur
2560 * on real world cards, so for now a fixme should be enough
2562 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
2564 default:
2565 Handled = FALSE;
2568 if (Handled) {
2569 BOOL combineOK = TRUE;
2570 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2571 DWORD op2;
2573 if (isAlpha) {
2574 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP];
2575 } else {
2576 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP];
2579 /* Note: If COMBINE4 in effect can't go back to combine! */
2580 switch (op2) {
2581 case WINED3DTOP_ADDSMOOTH:
2582 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2583 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2584 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2585 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2586 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2587 case WINED3DTOP_MULTIPLYADD:
2588 /* Ignore those implemented in both cases */
2589 switch (op) {
2590 case WINED3DTOP_SELECTARG1:
2591 case WINED3DTOP_SELECTARG2:
2592 combineOK = FALSE;
2593 Handled = FALSE;
2594 break;
2595 default:
2596 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
2597 return;
2602 if (combineOK) {
2603 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
2604 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
2606 return;
2610 /* After all the extensions, if still unhandled, report fixme */
2611 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
2612 #undef GLINFO_LOCATION
2615 /* Setup this textures matrix according to the texture flags*/
2616 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype)
2618 float mat[16];
2620 glMatrixMode(GL_TEXTURE);
2621 checkGLcall("glMatrixMode(GL_TEXTURE)");
2623 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2624 glLoadIdentity();
2625 checkGLcall("glLoadIdentity()");
2626 return;
2629 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2630 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2631 return;
2634 memcpy(mat, smat, 16 * sizeof(float));
2636 if (flags & WINED3DTTFF_PROJECTED) {
2637 switch (flags & ~WINED3DTTFF_PROJECTED) {
2638 case WINED3DTTFF_COUNT2:
2639 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2640 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2641 break;
2642 case WINED3DTTFF_COUNT3:
2643 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2644 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2645 break;
2647 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2648 if(!calculatedCoords) {
2649 switch(coordtype) {
2650 case WINED3DDECLTYPE_FLOAT1:
2651 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2652 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2653 * the input value to the transformation will be 0, so the matrix value is irrelevant
2655 mat[12] = mat[4];
2656 mat[13] = mat[5];
2657 mat[14] = mat[6];
2658 mat[15] = mat[7];
2659 break;
2660 case WINED3DDECLTYPE_FLOAT2:
2661 /* See above, just 3rd and 4th coord
2663 mat[12] = mat[8];
2664 mat[13] = mat[9];
2665 mat[14] = mat[10];
2666 mat[15] = mat[11];
2667 break;
2668 case WINED3DDECLTYPE_FLOAT3: /* Opengl defaults match dx defaults */
2669 case WINED3DDECLTYPE_FLOAT4: /* No defaults apply, all app defined */
2671 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2672 * into a bad place. The division elimination below will apply to make sure the
2673 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2675 case WINED3DDECLTYPE_UNUSED: /* No texture coords, 0/0/0/1 defaults are passed */
2676 break;
2677 default:
2678 FIXME("Unexpected fixed function texture coord input\n");
2681 switch (flags & ~WINED3DTTFF_PROJECTED) {
2682 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2683 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2684 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2685 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2686 * the 4th coord evaluates to 1.0 to eliminate that.
2688 * If the fixed function pipeline is used, the 4th value remains unused,
2689 * so there is no danger in doing this. With vertex shaders we have a
2690 * problem. Should an app hit that problem, the code here would have to
2691 * check for pixel shaders, and the shader has to undo the default gl divide.
2693 * A more serious problem occurs if the app passes 4 coordinates in, and the
2694 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2695 * or a replacement shader
2697 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2701 glLoadMatrixf(mat);
2702 checkGLcall("glLoadMatrixf(mat)");
2705 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
2707 /* This small helper function is used to convert a bitmask into the number of masked bits */
2708 unsigned int count_bits(unsigned int mask)
2710 unsigned int count;
2711 for (count = 0; mask; ++count)
2713 mask &= mask - 1;
2715 return count;
2718 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2719 * The later function requires individual color components. */
2720 BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2722 const StaticPixelFormatDesc *desc;
2724 TRACE("fmt: %s\n", debug_d3dformat(fmt));
2725 switch(fmt)
2727 case WINED3DFMT_X8R8G8B8:
2728 case WINED3DFMT_R8G8B8:
2729 case WINED3DFMT_A8R8G8B8:
2730 case WINED3DFMT_A2R10G10B10:
2731 case WINED3DFMT_X1R5G5B5:
2732 case WINED3DFMT_A1R5G5B5:
2733 case WINED3DFMT_R5G6B5:
2734 case WINED3DFMT_X4R4G4B4:
2735 case WINED3DFMT_A4R4G4B4:
2736 case WINED3DFMT_R3G3B2:
2737 case WINED3DFMT_A8P8:
2738 case WINED3DFMT_P8:
2739 break;
2740 default:
2741 ERR("Unsupported format: %s\n", debug_d3dformat(fmt));
2742 return FALSE;
2745 desc = getFormatDescEntry(fmt, NULL, NULL);
2746 if(!desc)
2748 ERR("Unable to look up format: 0x%x\n", fmt);
2749 return FALSE;
2751 *redSize = count_bits(desc->redMask);
2752 *greenSize = count_bits(desc->greenMask);
2753 *blueSize = count_bits(desc->blueMask);
2754 *alphaSize = count_bits(desc->alphaMask);
2755 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2757 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n", *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(fmt));
2758 return TRUE;
2761 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2762 BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize)
2764 const StaticPixelFormatDesc *desc;
2766 TRACE("fmt: %s\n", debug_d3dformat(fmt));
2767 switch(fmt)
2769 case WINED3DFMT_D16_LOCKABLE:
2770 case WINED3DFMT_D16:
2771 case WINED3DFMT_D15S1:
2772 case WINED3DFMT_D24X8:
2773 case WINED3DFMT_D24X4S4:
2774 case WINED3DFMT_D24S8:
2775 case WINED3DFMT_D24FS8:
2776 case WINED3DFMT_D32:
2777 case WINED3DFMT_D32F_LOCKABLE:
2778 break;
2779 default:
2780 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(fmt));
2781 return FALSE;
2784 desc = getFormatDescEntry(fmt, NULL, NULL);
2785 if(!desc)
2787 ERR("Unable to look up format: 0x%x\n", fmt);
2788 return FALSE;
2790 *depthSize = desc->depthSize;
2791 *stencilSize = desc->stencilSize;
2793 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n", *depthSize, *stencilSize, debug_d3dformat(fmt));
2794 return TRUE;
2797 #undef GLINFO_LOCATION
2799 /* DirectDraw stuff */
2800 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2801 switch(depth) {
2802 case 8: return WINED3DFMT_P8;
2803 case 15: return WINED3DFMT_X1R5G5B5;
2804 case 16: return WINED3DFMT_R5G6B5;
2805 case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
2806 case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
2807 default: return WINED3DFMT_UNKNOWN;
2811 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2812 WINED3DMATRIX temp;
2814 /* Now do the multiplication 'by hand'.
2815 I know that all this could be optimised, but this will be done later :-) */
2816 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);
2817 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);
2818 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);
2819 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);
2821 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);
2822 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);
2823 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);
2824 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);
2826 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);
2827 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);
2828 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);
2829 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);
2831 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);
2832 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);
2833 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);
2834 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);
2836 /* And copy the new matrix in the good storage.. */
2837 memcpy(dest, &temp, 16 * sizeof(float));
2840 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2841 DWORD size = 0;
2842 int i;
2843 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2845 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2846 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2847 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2848 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2849 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2850 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2851 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2852 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2853 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2854 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2855 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2856 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2857 default: ERR("Unexpected position mask\n");
2859 for (i = 0; i < numTextures; i++) {
2860 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2863 return size;
2866 /***********************************************************************
2867 * CalculateTexRect
2869 * Calculates the dimensions of the opengl texture used for blits.
2870 * Handled oversized opengl textures and updates the source rectangle
2871 * accordingly
2873 * Params:
2874 * This: Surface to operate on
2875 * Rect: Requested rectangle
2877 * Returns:
2878 * TRUE if the texture part can be loaded,
2879 * FALSE otherwise
2881 *********************************************************************/
2882 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
2884 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
2885 int x1 = Rect->left, x2 = Rect->right;
2886 int y1 = Rect->top, y2 = Rect->bottom;
2887 GLint maxSize = GL_LIMITS(texture_size);
2889 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2890 Rect->left, Rect->top, Rect->right, Rect->bottom);
2892 /* The sizes might be reversed */
2893 if(Rect->left > Rect->right) {
2894 x1 = Rect->right;
2895 x2 = Rect->left;
2897 if(Rect->top > Rect->bottom) {
2898 y1 = Rect->bottom;
2899 y2 = Rect->top;
2902 /* No oversized texture? This is easy */
2903 if(!(This->Flags & SFLAG_OVERSIZE)) {
2904 /* Which rect from the texture do I need? */
2905 if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
2906 glTexCoord[0] = (float) Rect->left;
2907 glTexCoord[2] = (float) Rect->top;
2908 glTexCoord[1] = (float) Rect->right;
2909 glTexCoord[3] = (float) Rect->bottom;
2910 } else {
2911 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2912 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2913 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2914 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2917 return TRUE;
2918 } else {
2919 /* Check if we can succeed at all */
2920 if( (x2 - x1) > maxSize ||
2921 (y2 - y1) > maxSize ) {
2922 TRACE("Requested rectangle is too large for gl\n");
2923 return FALSE;
2926 /* A part of the texture has to be picked. First, check if
2927 * some texture part is loaded already, if yes try to re-use it.
2928 * If the texture is dirty, or the part can't be used,
2929 * re-position the part to load
2931 if(This->Flags & SFLAG_INTEXTURE) {
2932 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2933 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2934 /* Ok, the rectangle is ok, re-use it */
2935 TRACE("Using existing gl Texture\n");
2936 } else {
2937 /* Rectangle is not ok, dirtify the texture to reload it */
2938 TRACE("Dirtifying texture to force reload\n");
2939 This->Flags &= ~SFLAG_INTEXTURE;
2943 /* Now if we are dirty(no else if!) */
2944 if(!(This->Flags & SFLAG_INTEXTURE)) {
2945 /* Set the new rectangle. Use the following strategy:
2946 * 1) Use as big textures as possible.
2947 * 2) Place the texture part in the way that the requested
2948 * part is in the middle of the texture(well, almost)
2949 * 3) If the texture is moved over the edges of the
2950 * surface, replace it nicely
2951 * 4) If the coord is not limiting the texture size,
2952 * use the whole size
2954 if((This->pow2Width) > maxSize) {
2955 This->glRect.left = x1 - maxSize / 2;
2956 if(This->glRect.left < 0) {
2957 This->glRect.left = 0;
2959 This->glRect.right = This->glRect.left + maxSize;
2960 if(This->glRect.right > This->currentDesc.Width) {
2961 This->glRect.right = This->currentDesc.Width;
2962 This->glRect.left = This->glRect.right - maxSize;
2964 } else {
2965 This->glRect.left = 0;
2966 This->glRect.right = This->pow2Width;
2969 if(This->pow2Height > maxSize) {
2970 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2971 if(This->glRect.top < 0) This->glRect.top = 0;
2972 This->glRect.bottom = This->glRect.left + maxSize;
2973 if(This->glRect.bottom > This->currentDesc.Height) {
2974 This->glRect.bottom = This->currentDesc.Height;
2975 This->glRect.top = This->glRect.bottom - maxSize;
2977 } else {
2978 This->glRect.top = 0;
2979 This->glRect.bottom = This->pow2Height;
2981 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2982 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2985 /* Re-calculate the rect to draw */
2986 Rect->left -= This->glRect.left;
2987 Rect->right -= This->glRect.left;
2988 Rect->top -= This->glRect.top;
2989 Rect->bottom -= This->glRect.top;
2991 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2992 * or the pow2Width / pow2Height of the surface.
2994 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
2995 * as regular GL_TEXTURE_2D.
2997 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2998 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2999 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
3000 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
3002 return TRUE;
3004 #undef GLINFO_LOCATION
3006 /* Hash table functions */
3008 hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
3010 hash_table_t *table;
3011 unsigned int initial_size = 8;
3013 table = HeapAlloc(GetProcessHeap(), 0, sizeof(hash_table_t) + (initial_size * sizeof(struct list)));
3014 if (!table)
3016 ERR("Failed to allocate table, returning NULL.\n");
3017 return NULL;
3020 table->hash_function = hash_function;
3021 table->compare_function = compare_function;
3023 table->grow_size = initial_size - (initial_size >> 2);
3024 table->shrink_size = 0;
3026 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
3027 if (!table->buckets)
3029 ERR("Failed to allocate table buckets, returning NULL.\n");
3030 HeapFree(GetProcessHeap(), 0, table);
3031 return NULL;
3033 table->bucket_count = initial_size;
3035 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(hash_table_entry_t));
3036 if (!table->entries)
3038 ERR("Failed to allocate table entries, returning NULL.\n");
3039 HeapFree(GetProcessHeap(), 0, table->buckets);
3040 HeapFree(GetProcessHeap(), 0, table);
3041 return NULL;
3043 table->entry_count = 0;
3045 list_init(&table->free_entries);
3046 table->count = 0;
3048 return table;
3051 void hash_table_destroy(hash_table_t *table)
3053 unsigned int i = 0;
3055 for (i = 0; i < table->entry_count; ++i)
3057 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
3060 HeapFree(GetProcessHeap(), 0, table->entries);
3061 HeapFree(GetProcessHeap(), 0, table->buckets);
3062 HeapFree(GetProcessHeap(), 0, table);
3065 static inline hash_table_entry_t *hash_table_get_by_idx(hash_table_t *table, void *key, unsigned int idx)
3067 hash_table_entry_t *entry;
3069 if (table->buckets[idx].next)
3070 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), hash_table_entry_t, entry)
3071 if (table->compare_function(entry->key, key)) return entry;
3073 return NULL;
3076 static BOOL hash_table_resize(hash_table_t *table, unsigned int new_bucket_count)
3078 unsigned int new_entry_count = 0;
3079 hash_table_entry_t *new_entries;
3080 struct list *new_buckets;
3081 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
3082 unsigned int i;
3084 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
3085 if (!new_buckets)
3087 ERR("Failed to allocate new buckets, returning FALSE.\n");
3088 return FALSE;
3091 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(hash_table_entry_t));
3092 if (!new_entries)
3094 ERR("Failed to allocate new entries, returning FALSE.\n");
3095 HeapFree(GetProcessHeap(), 0, new_buckets);
3096 return FALSE;
3099 for (i = 0; i < table->bucket_count; ++i)
3101 if (table->buckets[i].next)
3103 hash_table_entry_t *entry, *entry2;
3105 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], hash_table_entry_t, entry)
3107 int j;
3108 hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
3109 *new_entry = *entry;
3111 j = new_entry->hash & (new_bucket_count - 1);
3113 if (!new_buckets[j].next) list_init(&new_buckets[j]);
3114 list_add_head(&new_buckets[j], &new_entry->entry);
3119 HeapFree(GetProcessHeap(), 0, table->buckets);
3120 table->buckets = new_buckets;
3122 HeapFree(GetProcessHeap(), 0, table->entries);
3123 table->entries = new_entries;
3125 table->entry_count = new_entry_count;
3126 list_init(&table->free_entries);
3128 table->bucket_count = new_bucket_count;
3129 table->grow_size = grow_size;
3130 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
3132 return TRUE;
3135 void hash_table_put(hash_table_t *table, void *key, void *value)
3137 unsigned int idx;
3138 unsigned int hash;
3139 hash_table_entry_t *entry;
3141 hash = table->hash_function(key);
3142 idx = hash & (table->bucket_count - 1);
3143 entry = hash_table_get_by_idx(table, key, idx);
3145 if (entry)
3147 HeapFree(GetProcessHeap(), 0, key);
3148 entry->value = value;
3150 if (!value)
3152 HeapFree(GetProcessHeap(), 0, entry->key);
3153 entry->key = NULL;
3155 /* Remove the entry */
3156 list_remove(&entry->entry);
3157 list_add_head(&table->free_entries, &entry->entry);
3159 --table->count;
3161 /* Shrink if necessary */
3162 if (table->count < table->shrink_size) {
3163 if (!hash_table_resize(table, table->bucket_count >> 1))
3165 ERR("Failed to shrink the table...\n");
3170 return;
3173 if (!value) return;
3175 /* Grow if necessary */
3176 if (table->count >= table->grow_size)
3178 if (!hash_table_resize(table, table->bucket_count << 1))
3180 ERR("Failed to grow the table, returning.\n");
3181 return;
3184 idx = hash & (table->bucket_count - 1);
3187 /* Find an entry to insert */
3188 if (!list_empty(&table->free_entries))
3190 struct list *elem = list_head(&table->free_entries);
3192 list_remove(elem);
3193 entry = LIST_ENTRY(elem, hash_table_entry_t, entry);
3194 } else {
3195 entry = table->entries + (table->entry_count++);
3198 /* Insert the entry */
3199 entry->key = key;
3200 entry->value = value;
3201 entry->hash = hash;
3202 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
3203 list_add_head(&table->buckets[idx], &entry->entry);
3205 ++table->count;
3208 void hash_table_remove(hash_table_t *table, void *key)
3210 hash_table_put(table, key, NULL);
3213 void *hash_table_get(hash_table_t *table, void *key)
3215 unsigned int idx;
3216 hash_table_entry_t *entry;
3218 idx = table->hash_function(key) & (table->bucket_count - 1);
3219 entry = hash_table_get_by_idx(table, key, idx);
3221 return entry ? entry->value : NULL;
3224 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
3225 void gen_ffp_op(IWineD3DStateBlockImpl *stateblock, struct texture_stage_op op[MAX_TEXTURES]) {
3226 #define ARG1 0x01
3227 #define ARG2 0x02
3228 #define ARG0 0x04
3229 static const unsigned char args[WINED3DTOP_LERP + 1] = {
3230 /* undefined */ 0,
3231 /* D3DTOP_DISABLE */ 0,
3232 /* D3DTOP_SELECTARG1 */ ARG1,
3233 /* D3DTOP_SELECTARG2 */ ARG2,
3234 /* D3DTOP_MODULATE */ ARG1 | ARG2,
3235 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
3236 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
3237 /* D3DTOP_ADD */ ARG1 | ARG2,
3238 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
3239 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
3240 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
3241 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
3242 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
3243 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
3244 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
3245 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
3246 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
3247 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
3248 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
3249 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
3250 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
3251 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
3252 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
3253 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
3254 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
3255 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
3256 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
3258 unsigned int i;
3259 DWORD ttff;
3261 for(i = 0; i < GL_LIMITS(texture_stages); i++) {
3262 IWineD3DBaseTextureImpl *texture;
3263 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
3264 op[i].cop = WINED3DTOP_DISABLE;
3265 op[i].aop = WINED3DTOP_DISABLE;
3266 op[i].carg0 = op[i].carg1 = op[i].carg2 = 0xffffffff;
3267 op[i].aarg0 = op[i].aarg1 = op[i].aarg2 = 0xffffffff;
3268 op[i].color_correction = WINED3DFMT_UNKNOWN;
3269 op[i].dst = 0xffffffff;
3270 i++;
3271 break;
3274 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
3275 op[i].color_correction = texture ? texture->baseTexture.shader_conversion_group : WINED3DFMT_UNKNOWN;
3277 op[i].cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
3278 op[i].aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
3280 op[i].carg1 = (args[op[i].cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : 0xffffffff;
3281 op[i].carg2 = (args[op[i].cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : 0xffffffff;
3282 op[i].carg0 = (args[op[i].cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : 0xffffffff;
3284 if(is_invalid_op(stateblock->wineD3DDevice, i, op[i].cop, op[i].carg1, op[i].carg2, op[i].carg0)) {
3285 op[i].carg0 = 0xffffffff;
3286 op[i].carg2 = 0xffffffff;
3287 op[i].carg1 = WINED3DTA_CURRENT;
3288 op[i].cop = WINED3DTOP_SELECTARG1;
3291 op[i].aarg1 = (args[op[i].aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : 0xffffffff;
3292 op[i].aarg2 = (args[op[i].aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : 0xffffffff;
3293 op[i].aarg0 = (args[op[i].aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : 0xffffffff;
3295 if(is_invalid_op(stateblock->wineD3DDevice, i, op[i].aop, op[i].aarg1, op[i].aarg2, op[i].aarg0)) {
3296 op[i].aarg0 = 0xffffffff;
3297 op[i].aarg2 = 0xffffffff;
3298 op[i].aarg1 = WINED3DTA_CURRENT;
3299 op[i].aop = WINED3DTOP_SELECTARG1;
3300 } else if(i == 0 && stateblock->textures[0] &&
3301 stateblock->renderState[WINED3DRS_COLORKEYENABLE] &&
3302 (stateblock->textureDimensions[0] == GL_TEXTURE_2D ||
3303 stateblock->textureDimensions[0] == GL_TEXTURE_RECTANGLE_ARB)) {
3304 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
3306 if(surf->CKeyFlags & WINEDDSD_CKSRCBLT &&
3307 getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000) {
3309 if(op[0].aop == WINED3DTOP_DISABLE) {
3310 op[0].aarg1 = WINED3DTA_TEXTURE;
3311 op[0].aop = WINED3DTOP_SELECTARG1;
3313 else if(op[0].aop == WINED3DTOP_SELECTARG1 && op[0].aarg1 != WINED3DTA_TEXTURE) {
3314 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
3315 op[0].aarg2 = WINED3DTA_TEXTURE;
3316 op[0].aop = WINED3DTOP_MODULATE;
3318 else op[0].aarg1 = WINED3DTA_TEXTURE;
3320 else if(op[0].aop == WINED3DTOP_SELECTARG2 && op[0].aarg2 != WINED3DTA_TEXTURE) {
3321 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
3322 op[0].aarg1 = WINED3DTA_TEXTURE;
3323 op[0].aop = WINED3DTOP_MODULATE;
3325 else op[0].aarg2 = WINED3DTA_TEXTURE;
3330 if(op[i].carg1 == WINED3DTA_TEXTURE || op[i].carg2 == WINED3DTA_TEXTURE || op[i].carg0 == WINED3DTA_TEXTURE ||
3331 op[i].aarg1 == WINED3DTA_TEXTURE || op[i].aarg2 == WINED3DTA_TEXTURE || op[i].aarg0 == WINED3DTA_TEXTURE) {
3332 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
3333 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
3334 op[i].projected = proj_count3;
3335 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
3336 op[i].projected = proj_count4;
3337 } else {
3338 op[i].projected = proj_none;
3340 } else {
3341 op[i].projected = proj_none;
3344 op[i].dst = stateblock->textureState[i][WINED3DTSS_RESULTARG];
3347 /* Clear unsupported stages */
3348 for(; i < MAX_TEXTURES; i++) {
3349 memset(&op[i], 0xff, sizeof(op[i]));
3352 #undef GLINFO_LOCATION
3354 struct ffp_desc *find_ffp_shader(struct list *shaders, struct texture_stage_op op[MAX_TEXTURES])
3356 struct ffp_desc *entry;
3358 /* TODO: Optimize this. Finding the shader can be optimized by e.g. sorting the list,
3359 * or maybe consider using hashtables
3361 LIST_FOR_EACH_ENTRY(entry, shaders, struct ffp_desc, entry) {
3362 if(memcmp(op, entry->op, sizeof(struct texture_stage_op) * MAX_TEXTURES) == 0) {
3363 TRACE("Found shader entry %p\n", entry);
3364 return entry;
3368 TRACE("Shader not found\n");
3369 return NULL;
3372 void add_ffp_shader(struct list *shaders, struct ffp_desc *desc) {
3373 list_add_head(shaders, &desc->entry);
3376 /* Activates the texture dimension according to the bound D3D texture.
3377 * Does not care for the colorop or correct gl texture unit(when using nvrc)
3378 * Requires the caller to activate the correct unit before
3380 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
3381 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3382 if(stateblock->textures[stage]) {
3383 switch(stateblock->textureDimensions[stage]) {
3384 case GL_TEXTURE_2D:
3385 glDisable(GL_TEXTURE_3D);
3386 checkGLcall("glDisable(GL_TEXTURE_3D)");
3387 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
3388 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3389 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3391 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
3392 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3393 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3395 glEnable(GL_TEXTURE_2D);
3396 checkGLcall("glEnable(GL_TEXTURE_2D)");
3397 break;
3398 case GL_TEXTURE_RECTANGLE_ARB:
3399 glDisable(GL_TEXTURE_2D);
3400 checkGLcall("glDisable(GL_TEXTURE_2D)");
3401 glDisable(GL_TEXTURE_3D);
3402 checkGLcall("glDisable(GL_TEXTURE_3D)");
3403 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
3404 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3405 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3407 glEnable(GL_TEXTURE_RECTANGLE_ARB);
3408 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
3409 break;
3410 case GL_TEXTURE_3D:
3411 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
3412 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3413 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3415 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
3416 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3417 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3419 glDisable(GL_TEXTURE_2D);
3420 checkGLcall("glDisable(GL_TEXTURE_2D)");
3421 glEnable(GL_TEXTURE_3D);
3422 checkGLcall("glEnable(GL_TEXTURE_3D)");
3423 break;
3424 case GL_TEXTURE_CUBE_MAP_ARB:
3425 glDisable(GL_TEXTURE_2D);
3426 checkGLcall("glDisable(GL_TEXTURE_2D)");
3427 glDisable(GL_TEXTURE_3D);
3428 checkGLcall("glDisable(GL_TEXTURE_3D)");
3429 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
3430 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3431 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3433 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
3434 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
3435 break;
3437 } else {
3438 glEnable(GL_TEXTURE_2D);
3439 checkGLcall("glEnable(GL_TEXTURE_2D)");
3440 glDisable(GL_TEXTURE_3D);
3441 checkGLcall("glDisable(GL_TEXTURE_3D)");
3442 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
3443 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3444 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3446 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
3447 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3448 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3450 /* Binding textures is done by samplers. A dummy texture will be bound */
3454 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3455 DWORD sampler = state - STATE_SAMPLER(0);
3456 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
3458 /* No need to enable / disable anything here for unused samplers. The tex_colorop
3459 * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
3460 * will take care of this business
3462 if(mapped_stage == -1 || mapped_stage >= GL_LIMITS(textures)) return;
3463 if(sampler >= stateblock->lowest_disabled_stage) return;
3464 if(use_ps(stateblock->wineD3DDevice)) return;
3465 if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
3467 texture_activate_dimensions(sampler, stateblock, context);
3469 #undef GLINFO_LOCATION