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