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