wined3d: Update copyright lines.
[wine/wine-gecko.git] / dlls / wined3d / utils.c
blobe26754000a7827e7093fb26bff4ffea7b8227b04
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_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_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_SUBTRACT);
957 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
958 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
959 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
960 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
961 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
962 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
963 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
964 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
965 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
966 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
967 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
968 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
969 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
970 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
971 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
972 D3DTOP_TO_STR(WINED3DTOP_LERP);
973 #undef D3DTOP_TO_STR
974 default:
975 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
976 return "unrecognized";
980 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
981 switch (tstype) {
982 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
983 TSTYPE_TO_STR(WINED3DTS_VIEW);
984 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
985 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
986 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
987 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
988 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
989 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
990 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
991 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
992 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
993 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
994 #undef TSTYPE_TO_STR
995 default:
996 if (tstype > 256 && tstype < 512) {
997 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
998 return ("WINED3DTS_WORLDMATRIX > 0");
1000 FIXME("Unrecognized %u WINED3DTS\n", tstype);
1001 return "unrecognized";
1005 const char* debug_d3dpool(WINED3DPOOL Pool) {
1006 switch (Pool) {
1007 #define POOL_TO_STR(p) case p: return #p;
1008 POOL_TO_STR(WINED3DPOOL_DEFAULT);
1009 POOL_TO_STR(WINED3DPOOL_MANAGED);
1010 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
1011 POOL_TO_STR(WINED3DPOOL_SCRATCH);
1012 #undef POOL_TO_STR
1013 default:
1014 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
1015 return "unrecognized";
1019 const char *debug_fbostatus(GLenum status) {
1020 switch(status) {
1021 #define FBOSTATUS_TO_STR(u) case u: return #u
1022 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
1023 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
1024 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
1025 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
1026 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
1027 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
1028 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
1029 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
1030 #undef FBOSTATUS_TO_STR
1031 default:
1032 FIXME("Unrecognied FBO status 0x%08x\n", status);
1033 return "unrecognized";
1037 const char *debug_glerror(GLenum error) {
1038 switch(error) {
1039 #define GLERROR_TO_STR(u) case u: return #u
1040 GLERROR_TO_STR(GL_NO_ERROR);
1041 GLERROR_TO_STR(GL_INVALID_ENUM);
1042 GLERROR_TO_STR(GL_INVALID_VALUE);
1043 GLERROR_TO_STR(GL_INVALID_OPERATION);
1044 GLERROR_TO_STR(GL_STACK_OVERFLOW);
1045 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
1046 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
1047 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
1048 #undef GLERROR_TO_STR
1049 default:
1050 FIXME("Unrecognied GL error 0x%08x\n", error);
1051 return "unrecognized";
1055 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
1056 switch(basis) {
1057 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
1058 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
1059 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
1060 default: return "unrecognized";
1064 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
1065 switch(degree) {
1066 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
1067 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
1068 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
1069 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
1070 default: return "unrecognized";
1074 /*****************************************************************************
1075 * Useful functions mapping GL <-> D3D values
1077 GLenum StencilOp(DWORD op) {
1078 switch(op) {
1079 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
1080 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
1081 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
1082 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
1083 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
1084 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
1085 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
1086 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
1087 default:
1088 FIXME("Unrecognized stencil op %d\n", op);
1089 return GL_KEEP;
1093 GLenum CompareFunc(DWORD func) {
1094 switch ((WINED3DCMPFUNC)func) {
1095 case WINED3DCMP_NEVER : return GL_NEVER;
1096 case WINED3DCMP_LESS : return GL_LESS;
1097 case WINED3DCMP_EQUAL : return GL_EQUAL;
1098 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
1099 case WINED3DCMP_GREATER : return GL_GREATER;
1100 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
1101 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
1102 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
1103 default:
1104 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
1105 return 0;
1109 static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) {
1110 switch (d3dta) {
1111 case WINED3DTA_DIFFUSE:
1112 return GL_PRIMARY_COLOR_NV;
1114 case WINED3DTA_CURRENT:
1115 if (stage) return GL_SPARE0_NV;
1116 else return GL_PRIMARY_COLOR_NV;
1118 case WINED3DTA_TEXTURE:
1119 if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx;
1120 else return GL_PRIMARY_COLOR_NV;
1122 case WINED3DTA_TFACTOR:
1123 return GL_CONSTANT_COLOR0_NV;
1125 case WINED3DTA_SPECULAR:
1126 return GL_SECONDARY_COLOR_NV;
1128 case WINED3DTA_TEMP:
1129 return GL_SPARE1_NV;
1131 case WINED3DTA_CONSTANT:
1132 /* TODO: Support per stage constants (WINED3DTSS_CONSTANT, NV_register_combiners2) */
1133 FIXME("WINED3DTA_CONSTANT, not properly supported.\n");
1134 return GL_CONSTANT_COLOR1_NV;
1136 default:
1137 FIXME("Unrecognized texture arg %#x\n", d3dta);
1138 return GL_TEXTURE;
1142 static GLenum invert_mapping(GLenum mapping) {
1143 if (mapping == GL_UNSIGNED_INVERT_NV) return GL_SIGNED_IDENTITY_NV;
1144 else if (mapping == GL_SIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV;
1146 FIXME("Unhandled mapping %#x\n", mapping);
1147 return mapping;
1150 static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) {
1151 /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should
1152 * be used. */
1153 if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV;
1154 else *mapping = GL_SIGNED_IDENTITY_NV;
1156 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input
1157 * should be used for all input components. */
1158 if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA;
1159 else *component_usage = GL_RGB;
1161 *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx);
1164 typedef struct {
1165 GLenum input[3];
1166 GLenum mapping[3];
1167 GLenum component_usage[3];
1168 } tex_op_args;
1170 static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1171 if (op == WINED3DTOP_DISABLE) return FALSE;
1172 if (This->stateBlock->textures[stage]) return FALSE;
1174 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1175 && op != WINED3DTOP_SELECTARG2) return TRUE;
1176 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1177 && op != WINED3DTOP_SELECTARG1) return TRUE;
1178 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1179 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1181 return FALSE;
1184 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) {
1185 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface;
1186 tex_op_args tex_op_args = {{0}, {0}, {0}};
1187 GLenum portion = is_alpha ? GL_ALPHA : GL_RGB;
1188 GLenum target = GL_COMBINER0_NV + stage;
1189 GLenum output;
1191 TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1192 stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx);
1194 /* If a texture stage references an invalid texture unit the stage just
1195 * passes through the result from the previous stage */
1196 if (is_invalid_op(This, stage, op, arg1, arg2, arg3)) {
1197 arg1 = WINED3DTA_CURRENT;
1198 op = WINED3DTOP_SELECTARG1;
1201 get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0],
1202 &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx);
1203 get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1],
1204 &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx);
1205 get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2],
1206 &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx);
1209 if(dst == WINED3DTA_TEMP) {
1210 output = GL_SPARE1_NV;
1211 } else {
1212 output = GL_SPARE0_NV;
1215 /* This is called by a state handler which has the gl lock held and a context for the thread */
1216 switch(op)
1218 case WINED3DTOP_DISABLE:
1219 /* Only for alpha */
1220 if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n");
1221 /* Input, prev_alpha*1 */
1222 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1223 GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
1224 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1225 GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
1227 /* Output */
1228 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1229 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1230 break;
1232 case WINED3DTOP_SELECTARG1:
1233 case WINED3DTOP_SELECTARG2:
1234 /* Input, arg*1 */
1235 if (op == WINED3DTOP_SELECTARG1) {
1236 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1237 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1238 } else {
1239 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1240 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1242 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1243 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1245 /* Output */
1246 GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
1247 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1248 break;
1250 case WINED3DTOP_MODULATE:
1251 case WINED3DTOP_MODULATE2X:
1252 case WINED3DTOP_MODULATE4X:
1253 /* Input, arg1*arg2 */
1254 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1255 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1256 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1257 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1259 /* Output */
1260 if (op == WINED3DTOP_MODULATE) {
1261 GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
1262 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1263 } else if (op == WINED3DTOP_MODULATE2X) {
1264 GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
1265 GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1266 } else if (op == WINED3DTOP_MODULATE4X) {
1267 GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
1268 GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1270 break;
1272 case WINED3DTOP_ADD:
1273 case WINED3DTOP_ADDSIGNED:
1274 case WINED3DTOP_ADDSIGNED2X:
1275 /* Input, arg1*1+arg2*1 */
1276 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1277 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1278 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1279 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1280 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1281 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1282 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1283 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1285 /* Output */
1286 if (op == WINED3DTOP_ADD) {
1287 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1288 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1289 } else if (op == WINED3DTOP_ADDSIGNED) {
1290 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1291 output, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
1292 } else if (op == WINED3DTOP_ADDSIGNED2X) {
1293 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1294 output, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
1296 break;
1298 case WINED3DTOP_SUBTRACT:
1299 /* Input, arg1*1+-arg2*1 */
1300 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1301 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1302 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1303 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1304 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1305 tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1]));
1306 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1307 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1309 /* Output */
1310 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1311 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1312 break;
1314 case WINED3DTOP_ADDSMOOTH:
1315 /* Input, arg1*1+(1-arg1)*arg2 */
1316 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1317 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1318 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1319 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1320 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1321 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1322 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1323 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1325 /* Output */
1326 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1327 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1328 break;
1330 case WINED3DTOP_BLENDDIFFUSEALPHA:
1331 case WINED3DTOP_BLENDTEXTUREALPHA:
1332 case WINED3DTOP_BLENDFACTORALPHA:
1333 case WINED3DTOP_BLENDTEXTUREALPHAPM:
1334 case WINED3DTOP_BLENDCURRENTALPHA:
1336 GLenum alpha_src = GL_PRIMARY_COLOR_NV;
1337 if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx);
1338 else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
1339 else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx);
1340 else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
1341 else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx);
1342 else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op));
1344 /* Input, arg1*alpha_src+arg2*(1-alpha_src) */
1345 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1346 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1347 if (op == WINED3DTOP_BLENDTEXTUREALPHAPM)
1349 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1350 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1351 } else {
1352 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1353 alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
1355 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1356 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1357 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1358 alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
1360 /* Output */
1361 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1362 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1363 break;
1366 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1367 /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */
1368 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n");
1369 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1370 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1371 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1372 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1373 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1374 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1375 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1376 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1378 /* Output */
1379 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1380 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1381 break;
1383 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1384 /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */
1385 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n");
1386 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1387 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1388 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1389 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1390 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1391 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1392 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1393 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1395 /* Output */
1396 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1397 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1398 break;
1400 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1401 /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */
1402 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n");
1403 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1404 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA));
1405 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1406 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1407 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1408 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1409 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1410 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1412 /* Output */
1413 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1414 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1415 break;
1417 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1418 /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */
1419 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n");
1420 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1421 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1422 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1423 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1424 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1425 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1426 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1427 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1429 /* Output */
1430 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1431 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1432 break;
1434 case WINED3DTOP_DOTPRODUCT3:
1435 /* Input, arg1 . arg2 */
1436 /* FIXME: DX7 uses a different calculation? */
1437 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1438 tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0]));
1439 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1440 tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1]));
1442 /* Output */
1443 GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
1444 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE));
1445 break;
1447 case WINED3DTOP_MULTIPLYADD:
1448 /* Input, arg1*1+arg2*arg3 */
1449 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1450 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1451 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1452 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1453 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1454 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1455 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1456 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1458 /* Output */
1459 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1460 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1461 break;
1463 case WINED3DTOP_LERP:
1464 /* Input, arg1*arg2+(1-arg1)*arg3 */
1465 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1466 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1467 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1468 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1469 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1470 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1471 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1472 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1474 /* Output */
1475 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1476 output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1477 break;
1479 case WINED3DTOP_BUMPENVMAPLUMINANCE:
1480 case WINED3DTOP_BUMPENVMAP:
1481 if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
1482 /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to
1483 * perform bump mapping and source from the current stage. Pretty much a SELECTARG2.
1484 * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1
1485 * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the next stage
1487 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1488 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1489 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1490 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1491 /* Always pass through to CURRENT, ignore temp arg */
1492 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1493 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1494 break;
1497 default:
1498 FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1499 stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
1502 checkGLcall("set_tex_op_nvrc()\n");
1506 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
1507 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
1508 * input should be used for all input components. The WINED3DTA_COMPLEMENT
1509 * flag specifies the complement of the input should be used. */
1510 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
1511 BOOL complement = arg & WINED3DTA_COMPLEMENT;
1513 /* Calculate the operand */
1514 if (complement) {
1515 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
1516 else *operand = GL_ONE_MINUS_SRC_COLOR;
1517 } else {
1518 if (from_alpha) *operand = GL_SRC_ALPHA;
1519 else *operand = GL_SRC_COLOR;
1522 /* Calculate the source */
1523 switch (arg & WINED3DTA_SELECTMASK) {
1524 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
1525 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
1526 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
1527 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
1528 case WINED3DTA_SPECULAR:
1530 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
1531 * 'Secondary color' and isn't supported until base GL supports it
1532 * There is no concept of temp registers as far as I can tell
1534 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
1535 *source = GL_TEXTURE;
1536 break;
1537 default:
1538 FIXME("Unrecognized texture arg %#x\n", arg);
1539 *source = GL_TEXTURE;
1540 break;
1544 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
1545 #if defined (GL_VERSION_1_3)
1546 # define useext(A) A
1547 # define combine_ext 1
1548 #elif defined (GL_EXT_texture_env_combine)
1549 # define useext(A) A##_EXT
1550 # define combine_ext 1
1551 #elif defined (GL_ARB_texture_env_combine)
1552 # define useext(A) A##_ARB
1553 # define combine_ext 1
1554 #else
1555 # undef combine_ext
1556 #endif
1558 #if !defined(combine_ext)
1559 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1561 FIXME("Requires opengl combine extensions to work\n");
1562 return;
1564 #else
1565 /* Setup the texture operations texture stage states */
1566 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1568 GLenum src1, src2, src3;
1569 GLenum opr1, opr2, opr3;
1570 GLenum comb_target;
1571 GLenum src0_target, src1_target, src2_target;
1572 GLenum opr0_target, opr1_target, opr2_target;
1573 GLenum scal_target;
1574 GLenum opr=0, invopr, src3_target, opr3_target;
1575 BOOL Handled = FALSE;
1576 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
1578 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
1580 /* This is called by a state handler which has the gl lock held and a context for the thread */
1582 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
1583 the form (a1 <operation> a2). However, some of the more complex operations
1584 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
1585 in a third parameter called a0. Therefore these are operations of the form
1586 a0 <operation> a1 <operation> a2, ie the new parameter goes to the front.
1588 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
1589 functions below, expect their syntax to differ slightly to those listed in the
1590 manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
1591 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
1593 if (isAlpha) {
1594 comb_target = useext(GL_COMBINE_ALPHA);
1595 src0_target = useext(GL_SOURCE0_ALPHA);
1596 src1_target = useext(GL_SOURCE1_ALPHA);
1597 src2_target = useext(GL_SOURCE2_ALPHA);
1598 opr0_target = useext(GL_OPERAND0_ALPHA);
1599 opr1_target = useext(GL_OPERAND1_ALPHA);
1600 opr2_target = useext(GL_OPERAND2_ALPHA);
1601 scal_target = GL_ALPHA_SCALE;
1603 else {
1604 comb_target = useext(GL_COMBINE_RGB);
1605 src0_target = useext(GL_SOURCE0_RGB);
1606 src1_target = useext(GL_SOURCE1_RGB);
1607 src2_target = useext(GL_SOURCE2_RGB);
1608 opr0_target = useext(GL_OPERAND0_RGB);
1609 opr1_target = useext(GL_OPERAND1_RGB);
1610 opr2_target = useext(GL_OPERAND2_RGB);
1611 scal_target = useext(GL_RGB_SCALE);
1614 /* If a texture stage references an invalid texture unit the stage just
1615 * passes through the result from the previous stage */
1616 if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) {
1617 arg1 = WINED3DTA_CURRENT;
1618 op = WINED3DTOP_SELECTARG1;
1621 /* From MSDN (WINED3DTSS_ALPHAARG1) :
1622 The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage,
1623 then the default argument is WINED3DTA_DIFFUSE.
1624 FIXME? If texture added/removed, may need to reset back as well? */
1625 if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
1626 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
1627 } else {
1628 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
1630 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
1631 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
1633 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
1635 Handled = TRUE; /* Assume will be handled */
1637 /* Other texture operations require special extensions: */
1638 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1639 if (isAlpha) {
1640 opr = GL_SRC_ALPHA;
1641 invopr = GL_ONE_MINUS_SRC_ALPHA;
1642 src3_target = GL_SOURCE3_ALPHA_NV;
1643 opr3_target = GL_OPERAND3_ALPHA_NV;
1644 } else {
1645 opr = GL_SRC_COLOR;
1646 invopr = GL_ONE_MINUS_SRC_COLOR;
1647 src3_target = GL_SOURCE3_RGB_NV;
1648 opr3_target = GL_OPERAND3_RGB_NV;
1650 switch (op) {
1651 case WINED3DTOP_DISABLE: /* Only for alpha */
1652 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1653 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1654 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1655 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1656 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1657 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1658 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1659 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1660 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1661 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1662 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1663 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1664 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1665 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1666 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1667 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1668 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1669 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1670 break;
1671 case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */
1672 case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
1673 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1674 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1675 if (op == WINED3DTOP_SELECTARG1) {
1676 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1677 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1678 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1679 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1680 } else {
1681 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1682 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1683 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1684 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1686 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1687 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1688 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1689 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1690 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1691 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1692 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1693 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1694 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1695 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1696 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1697 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1698 break;
1700 case WINED3DTOP_MODULATE:
1701 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1702 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1703 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1704 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1705 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1706 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1707 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1708 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1709 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1710 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1711 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1712 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1713 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1714 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1715 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1716 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1717 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1718 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1719 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1720 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1721 break;
1722 case WINED3DTOP_MODULATE2X:
1723 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1724 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1725 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1726 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1727 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1728 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1729 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1730 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1731 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1732 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1733 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1734 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1735 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1736 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1737 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1738 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1739 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1740 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1741 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1742 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1743 break;
1744 case WINED3DTOP_MODULATE4X:
1745 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1746 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1747 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1748 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1749 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1750 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1751 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1752 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1753 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1754 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1755 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1756 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1757 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1758 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1759 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1760 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1761 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1762 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1763 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
1764 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
1765 break;
1767 case WINED3DTOP_ADD:
1768 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1769 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1770 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1771 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1772 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1773 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1774 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1775 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1776 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1777 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1778 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1779 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1780 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1781 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1782 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1783 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1784 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1785 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1786 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1787 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1788 break;
1790 case WINED3DTOP_ADDSIGNED:
1791 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1792 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1793 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1794 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1795 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1796 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1797 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1798 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1799 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1800 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1801 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1802 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1803 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1804 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1805 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1806 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1807 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1808 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1809 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1810 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1811 break;
1813 case WINED3DTOP_ADDSIGNED2X:
1814 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1815 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1816 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1817 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1818 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1819 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1820 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1821 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1822 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1823 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1824 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1825 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1826 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1827 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1828 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1829 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1830 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1831 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1832 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1833 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1834 break;
1836 case WINED3DTOP_ADDSMOOTH:
1837 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1838 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1839 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1840 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1841 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1842 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1843 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1844 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1845 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1846 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1847 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1848 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1849 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1850 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1851 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1852 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1853 switch (opr1) {
1854 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1855 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1856 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1857 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1859 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1860 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1861 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1862 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1863 break;
1865 case WINED3DTOP_BLENDDIFFUSEALPHA:
1866 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1867 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1868 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1869 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1870 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1871 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1872 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
1873 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
1874 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1875 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1876 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1877 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1878 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1879 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1880 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
1881 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
1882 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1883 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1884 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1885 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1886 break;
1887 case WINED3DTOP_BLENDTEXTUREALPHA:
1888 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1889 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1890 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1891 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1892 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1893 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1894 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
1895 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
1896 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1897 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1898 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1899 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1900 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1901 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1902 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1903 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1904 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1905 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1906 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1907 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1908 break;
1909 case WINED3DTOP_BLENDFACTORALPHA:
1910 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1911 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1912 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1913 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1914 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1915 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1916 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
1917 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
1918 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1919 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1920 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1921 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1922 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1923 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1924 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
1925 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
1926 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1927 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1928 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1929 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1930 break;
1931 case WINED3DTOP_BLENDTEXTUREALPHAPM:
1932 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1933 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1934 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1935 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1936 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1937 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1938 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1939 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1940 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1941 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1942 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1943 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1944 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1945 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1946 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1947 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1948 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1949 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1950 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1951 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1952 break;
1953 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1954 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1955 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1956 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
1957 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1958 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1959 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
1960 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1961 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1962 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1963 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1964 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
1965 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1966 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1967 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
1968 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1969 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1970 switch (opr) {
1971 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1972 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1974 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1975 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1976 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1977 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1978 break;
1979 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1980 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1981 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1982 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1983 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1984 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1985 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1986 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1987 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1988 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1989 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1990 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1991 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1992 switch (opr1) {
1993 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1994 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1996 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1997 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1998 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1999 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2000 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2001 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2002 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2003 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2004 break;
2005 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2006 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2007 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2008 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2009 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2010 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2011 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2012 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2013 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2014 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2015 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2016 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2017 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2018 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2019 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2020 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2021 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2022 switch (opr1) {
2023 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2024 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2025 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2026 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2028 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2029 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2030 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2031 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2032 break;
2033 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2034 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2035 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2036 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2037 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2038 switch (opr1) {
2039 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2040 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2041 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2042 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2044 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2045 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2046 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2047 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2048 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2049 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2050 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2051 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2052 switch (opr1) {
2053 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2054 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2056 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2057 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2058 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2059 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2060 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2061 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2062 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2063 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2064 break;
2065 case WINED3DTOP_MULTIPLYADD:
2066 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2067 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2068 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2069 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2070 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2071 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2072 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2073 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2074 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2075 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2076 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2077 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2078 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2079 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2080 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2081 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2082 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2083 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2084 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2085 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2086 break;
2088 case WINED3DTOP_BUMPENVMAP:
2092 case WINED3DTOP_BUMPENVMAPLUMINANCE:
2093 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2095 default:
2096 Handled = FALSE;
2098 if (Handled) {
2099 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2100 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2102 return;
2104 } /* GL_NV_texture_env_combine4 */
2106 Handled = TRUE; /* Again, assume handled */
2107 switch (op) {
2108 case WINED3DTOP_DISABLE: /* Only for alpha */
2109 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2110 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2111 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2112 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2113 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2114 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2115 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2116 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2117 break;
2118 case WINED3DTOP_SELECTARG1:
2119 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2120 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2121 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2122 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2123 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2124 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2125 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2126 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2127 break;
2128 case WINED3DTOP_SELECTARG2:
2129 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2130 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2131 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2132 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2133 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2134 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2135 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2136 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2137 break;
2138 case WINED3DTOP_MODULATE:
2139 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2140 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2141 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2142 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2143 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2144 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2145 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2146 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2147 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2148 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2149 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2150 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2151 break;
2152 case WINED3DTOP_MODULATE2X:
2153 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2154 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2155 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2156 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2157 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2158 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2159 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2160 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2161 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2162 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2163 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2164 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2165 break;
2166 case WINED3DTOP_MODULATE4X:
2167 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2168 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2169 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2170 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2171 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2172 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2173 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2174 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2175 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2176 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2177 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2178 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2179 break;
2180 case WINED3DTOP_ADD:
2181 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2182 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2183 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2184 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2185 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2186 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2187 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2188 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2189 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2190 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2191 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2192 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2193 break;
2194 case WINED3DTOP_ADDSIGNED:
2195 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2196 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
2197 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2198 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2199 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2200 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2201 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2202 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2203 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2204 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2205 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2206 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2207 break;
2208 case WINED3DTOP_ADDSIGNED2X:
2209 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2210 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2211 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2212 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2213 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2214 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2215 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2216 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2217 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2218 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2219 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2220 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2221 break;
2222 case WINED3DTOP_SUBTRACT:
2223 if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
2224 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2225 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
2226 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2227 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2228 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2229 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2230 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2231 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2232 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2233 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2234 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2235 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2236 } else {
2237 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2239 break;
2241 case WINED3DTOP_BLENDDIFFUSEALPHA:
2242 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2243 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2244 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2245 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2246 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2247 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2248 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2249 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2250 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2251 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2252 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
2253 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2254 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2255 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2256 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2257 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2258 break;
2259 case WINED3DTOP_BLENDTEXTUREALPHA:
2260 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2261 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2262 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2263 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2264 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2265 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2266 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2267 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2268 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2269 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2270 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2271 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2272 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2273 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2274 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2275 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2276 break;
2277 case WINED3DTOP_BLENDFACTORALPHA:
2278 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2279 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2280 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2281 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2282 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2283 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2284 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2285 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2286 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2287 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2288 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
2289 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2290 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2291 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2292 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2293 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2294 break;
2295 case WINED3DTOP_BLENDCURRENTALPHA:
2296 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2297 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2298 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2299 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2300 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2301 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2302 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2303 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2304 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2305 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2306 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
2307 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2308 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2309 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2310 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2311 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2312 break;
2313 case WINED3DTOP_DOTPRODUCT3:
2314 if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
2315 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2316 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2317 } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
2318 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2319 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2320 } else {
2321 FIXME("This version of opengl does not support GL_DOT3\n");
2323 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2324 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2325 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2326 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2327 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2328 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2329 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2330 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2331 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2332 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2333 break;
2334 case WINED3DTOP_LERP:
2335 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2336 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2337 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2338 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2339 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2340 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2341 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2342 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2343 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2344 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2345 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2346 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2347 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2348 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2349 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2350 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2351 break;
2352 case WINED3DTOP_ADDSMOOTH:
2353 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2354 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2355 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2356 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2357 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2358 switch (opr1) {
2359 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2360 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2361 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2362 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2364 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2365 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2366 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2367 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2368 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2369 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2370 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2371 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2372 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2373 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2374 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2375 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2376 } else
2377 Handled = FALSE;
2378 break;
2379 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2380 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2381 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2382 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2383 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2384 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2385 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2386 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2387 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2388 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2389 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2390 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2391 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2392 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2393 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2394 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2395 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2396 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2397 } else
2398 Handled = FALSE;
2399 break;
2400 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2401 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2402 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2403 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2404 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2405 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2406 switch (opr1) {
2407 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2408 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2409 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2410 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2412 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2413 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2414 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2415 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2416 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2417 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2418 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2419 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2420 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2421 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2422 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2423 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2424 } else
2425 Handled = FALSE;
2426 break;
2427 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2428 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2429 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2430 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2431 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2432 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2433 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2434 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2435 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2436 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2437 switch (opr1) {
2438 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2439 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2440 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2441 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2443 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2444 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2445 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2446 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2447 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2448 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2449 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2450 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2451 } else
2452 Handled = FALSE;
2453 break;
2454 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2455 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2456 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2457 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2458 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2459 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2460 switch (opr1) {
2461 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2462 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2463 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2464 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2466 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2467 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2468 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2469 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2470 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2471 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2472 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2473 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2474 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2475 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2476 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2477 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2478 } else
2479 Handled = FALSE;
2480 break;
2481 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2482 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2483 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2484 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2485 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2486 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2487 switch (opr1) {
2488 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2489 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2490 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2491 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2493 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2494 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2495 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2496 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2497 switch (opr1) {
2498 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2499 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2500 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2501 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2503 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2504 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2505 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2506 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2507 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2508 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2509 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2510 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2511 } else
2512 Handled = FALSE;
2513 break;
2514 case WINED3DTOP_MULTIPLYADD:
2515 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2516 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2517 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2518 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2519 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2520 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2521 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2522 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2523 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2524 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2525 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2526 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2527 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2528 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2529 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2530 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2531 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2532 } else
2533 Handled = FALSE;
2534 break;
2535 case WINED3DTOP_BUMPENVMAPLUMINANCE:
2536 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2537 /* Some apps use BUMPENVMAPLUMINANCE instead of D3DTOP_BUMPENVMAP, although
2538 * they check for the non-luminance cap flag. Well, give them what they asked
2539 * for :-)
2541 WARN("Application uses WINED3DTOP_BUMPENVMAPLUMINANCE\n");
2542 } else {
2543 Handled = FALSE;
2544 break;
2546 /* Fall through */
2547 case WINED3DTOP_BUMPENVMAP:
2548 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2549 TRACE("Using ati bumpmap on stage %d, target %d\n", Stage, Stage + 1);
2550 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI);
2551 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI)");
2552 glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1);
2553 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1)");
2554 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2555 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2556 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2557 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2558 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2559 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2560 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2561 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2562 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2563 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2564 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2565 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2567 Handled = TRUE;
2568 break;
2569 } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2570 /* Technically texture shader support without register combiners is possible, but not expected to occur
2571 * on real world cards, so for now a fixme should be enough
2573 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
2575 default:
2576 Handled = FALSE;
2579 if (Handled) {
2580 BOOL combineOK = TRUE;
2581 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2582 DWORD op2;
2584 if (isAlpha) {
2585 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP];
2586 } else {
2587 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP];
2590 /* Note: If COMBINE4 in effect can't go back to combine! */
2591 switch (op2) {
2592 case WINED3DTOP_ADDSMOOTH:
2593 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2594 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2595 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2596 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2597 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2598 case WINED3DTOP_MULTIPLYADD:
2599 /* Ignore those implemented in both cases */
2600 switch (op) {
2601 case WINED3DTOP_SELECTARG1:
2602 case WINED3DTOP_SELECTARG2:
2603 combineOK = FALSE;
2604 Handled = FALSE;
2605 break;
2606 default:
2607 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
2608 return;
2613 if (combineOK) {
2614 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
2615 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
2617 return;
2621 /* After all the extensions, if still unhandled, report fixme */
2622 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
2623 #undef GLINFO_LOCATION
2625 #endif
2627 /* Setup this textures matrix according to the texture flags*/
2628 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype)
2630 float mat[16];
2632 glMatrixMode(GL_TEXTURE);
2633 checkGLcall("glMatrixMode(GL_TEXTURE)");
2635 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2636 glLoadIdentity();
2637 checkGLcall("glLoadIdentity()");
2638 return;
2641 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2642 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2643 return;
2646 memcpy(mat, smat, 16 * sizeof(float));
2648 if (flags & WINED3DTTFF_PROJECTED) {
2649 switch (flags & ~WINED3DTTFF_PROJECTED) {
2650 case WINED3DTTFF_COUNT2:
2651 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2652 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2653 break;
2654 case WINED3DTTFF_COUNT3:
2655 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2656 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2657 break;
2659 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2660 if(!calculatedCoords) {
2661 switch(coordtype) {
2662 case WINED3DDECLTYPE_FLOAT1:
2663 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2664 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2665 * the input value to the transformation will be 0, so the matrix value is irrelevant
2667 mat[12] = mat[4];
2668 mat[13] = mat[5];
2669 mat[14] = mat[6];
2670 mat[15] = mat[7];
2671 break;
2672 case WINED3DDECLTYPE_FLOAT2:
2673 /* See above, just 3rd and 4th coord
2675 mat[12] = mat[8];
2676 mat[13] = mat[9];
2677 mat[14] = mat[10];
2678 mat[15] = mat[11];
2679 break;
2680 case WINED3DDECLTYPE_FLOAT3: /* Opengl defaults match dx defaults */
2681 case WINED3DDECLTYPE_FLOAT4: /* No defaults apply, all app defined */
2683 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
2684 * into a bad place. The division elimination below will apply to make sure the
2685 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2687 case WINED3DDECLTYPE_UNUSED: /* No texture coords, 0/0/0/1 defaults are passed */
2688 break;
2689 default:
2690 FIXME("Unexpected fixed function texture coord input\n");
2693 switch (flags & ~WINED3DTTFF_PROJECTED) {
2694 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2695 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2696 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2697 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2698 * the 4th coord evaluates to 1.0 to eliminate that.
2700 * If the fixed function pipeline is used, the 4th value remains unused,
2701 * so there is no danger in doing this. With vertex shaders we have a
2702 * problem. Should an app hit that problem, the code here would have to
2703 * check for pixel shaders, and the shader has to undo the default gl divide.
2705 * A more serious problem occurs if the app passes 4 coordinates in, and the
2706 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2707 * or a replacement shader
2709 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2713 glLoadMatrixf(mat);
2714 checkGLcall("glLoadMatrixf(mat)");
2717 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
2719 /* This small helper function is used to convert a bitmask into the number of masked bits */
2720 unsigned int count_bits(unsigned int mask)
2722 unsigned int count;
2723 for (count = 0; mask; ++count)
2725 mask &= mask - 1;
2727 return count;
2730 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2731 * The later function requires individual color components. */
2732 BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2734 const StaticPixelFormatDesc *desc;
2736 TRACE("fmt: %s\n", debug_d3dformat(fmt));
2737 switch(fmt)
2739 case WINED3DFMT_X8R8G8B8:
2740 case WINED3DFMT_R8G8B8:
2741 case WINED3DFMT_A8R8G8B8:
2742 case WINED3DFMT_A2R10G10B10:
2743 case WINED3DFMT_X1R5G5B5:
2744 case WINED3DFMT_A1R5G5B5:
2745 case WINED3DFMT_R5G6B5:
2746 case WINED3DFMT_X4R4G4B4:
2747 case WINED3DFMT_A4R4G4B4:
2748 case WINED3DFMT_R3G3B2:
2749 case WINED3DFMT_A8P8:
2750 case WINED3DFMT_P8:
2751 break;
2752 default:
2753 ERR("Unsupported format: %s\n", debug_d3dformat(fmt));
2754 return FALSE;
2757 desc = getFormatDescEntry(fmt, NULL, NULL);
2758 if(!desc)
2760 ERR("Unable to look up format: 0x%x\n", fmt);
2761 return FALSE;
2763 *redSize = count_bits(desc->redMask);
2764 *greenSize = count_bits(desc->greenMask);
2765 *blueSize = count_bits(desc->blueMask);
2766 *alphaSize = count_bits(desc->alphaMask);
2767 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2769 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n", *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(fmt));
2770 return TRUE;
2773 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2774 BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize)
2776 const StaticPixelFormatDesc *desc;
2778 TRACE("fmt: %s\n", debug_d3dformat(fmt));
2779 switch(fmt)
2781 case WINED3DFMT_D16_LOCKABLE:
2782 case WINED3DFMT_D16:
2783 case WINED3DFMT_D15S1:
2784 case WINED3DFMT_D24X8:
2785 case WINED3DFMT_D24X4S4:
2786 case WINED3DFMT_D24S8:
2787 case WINED3DFMT_D24FS8:
2788 case WINED3DFMT_D32:
2789 case WINED3DFMT_D32F_LOCKABLE:
2790 break;
2791 default:
2792 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(fmt));
2793 return FALSE;
2796 desc = getFormatDescEntry(fmt, NULL, NULL);
2797 if(!desc)
2799 ERR("Unable to look up format: 0x%x\n", fmt);
2800 return FALSE;
2802 *depthSize = desc->depthSize;
2803 *stencilSize = desc->stencilSize;
2805 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n", *depthSize, *stencilSize, debug_d3dformat(fmt));
2806 return TRUE;
2809 #undef GLINFO_LOCATION
2811 /* DirectDraw stuff */
2812 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2813 switch(depth) {
2814 case 8: return WINED3DFMT_P8;
2815 case 15: return WINED3DFMT_X1R5G5B5;
2816 case 16: return WINED3DFMT_R5G6B5;
2817 case 24: return WINED3DFMT_X8R8G8B8; /* Robots needs 24bit to be X8R8G8B8 */
2818 case 32: return WINED3DFMT_X8R8G8B8; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return X8R8G8B8 */
2819 default: return WINED3DFMT_UNKNOWN;
2823 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2824 WINED3DMATRIX temp;
2826 /* Now do the multiplication 'by hand'.
2827 I know that all this could be optimised, but this will be done later :-) */
2828 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);
2829 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);
2830 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);
2831 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);
2833 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);
2834 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);
2835 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);
2836 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);
2838 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);
2839 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);
2840 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);
2841 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);
2843 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);
2844 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);
2845 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);
2846 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);
2848 /* And copy the new matrix in the good storage.. */
2849 memcpy(dest, &temp, 16 * sizeof(float));
2852 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2853 DWORD size = 0;
2854 int i;
2855 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2857 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2858 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2859 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2860 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2861 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2862 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2863 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2864 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2865 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2866 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2867 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2868 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2869 default: ERR("Unexpected position mask\n");
2871 for (i = 0; i < numTextures; i++) {
2872 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2875 return size;
2878 /***********************************************************************
2879 * CalculateTexRect
2881 * Calculates the dimensions of the opengl texture used for blits.
2882 * Handled oversized opengl textures and updates the source rectangle
2883 * accordingly
2885 * Params:
2886 * This: Surface to operate on
2887 * Rect: Requested rectangle
2889 * Returns:
2890 * TRUE if the texture part can be loaded,
2891 * FALSE otherwise
2893 *********************************************************************/
2894 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
2896 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
2897 int x1 = Rect->left, x2 = Rect->right;
2898 int y1 = Rect->top, y2 = Rect->bottom;
2899 GLint maxSize = GL_LIMITS(texture_size);
2901 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2902 Rect->left, Rect->top, Rect->right, Rect->bottom);
2904 /* The sizes might be reversed */
2905 if(Rect->left > Rect->right) {
2906 x1 = Rect->right;
2907 x2 = Rect->left;
2909 if(Rect->top > Rect->bottom) {
2910 y1 = Rect->bottom;
2911 y2 = Rect->top;
2914 /* No oversized texture? This is easy */
2915 if(!(This->Flags & SFLAG_OVERSIZE)) {
2916 /* Which rect from the texture do I need? */
2917 if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
2918 glTexCoord[0] = (float) Rect->left;
2919 glTexCoord[2] = (float) Rect->top;
2920 glTexCoord[1] = (float) Rect->right;
2921 glTexCoord[3] = (float) Rect->bottom;
2922 } else {
2923 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2924 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2925 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2926 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2929 return TRUE;
2930 } else {
2931 /* Check if we can succeed at all */
2932 if( (x2 - x1) > maxSize ||
2933 (y2 - y1) > maxSize ) {
2934 TRACE("Requested rectangle is too large for gl\n");
2935 return FALSE;
2938 /* A part of the texture has to be picked. First, check if
2939 * some texture part is loaded already, if yes try to re-use it.
2940 * If the texture is dirty, or the part can't be used,
2941 * re-position the part to load
2943 if(This->Flags & SFLAG_INTEXTURE) {
2944 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2945 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2946 /* Ok, the rectangle is ok, re-use it */
2947 TRACE("Using existing gl Texture\n");
2948 } else {
2949 /* Rectangle is not ok, dirtify the texture to reload it */
2950 TRACE("Dirtifying texture to force reload\n");
2951 This->Flags &= ~SFLAG_INTEXTURE;
2955 /* Now if we are dirty(no else if!) */
2956 if(!(This->Flags & SFLAG_INTEXTURE)) {
2957 /* Set the new rectangle. Use the following strategy:
2958 * 1) Use as big textures as possible.
2959 * 2) Place the texture part in the way that the requested
2960 * part is in the middle of the texture(well, almost)
2961 * 3) If the texture is moved over the edges of the
2962 * surface, replace it nicely
2963 * 4) If the coord is not limiting the texture size,
2964 * use the whole size
2966 if((This->pow2Width) > maxSize) {
2967 This->glRect.left = x1 - maxSize / 2;
2968 if(This->glRect.left < 0) {
2969 This->glRect.left = 0;
2971 This->glRect.right = This->glRect.left + maxSize;
2972 if(This->glRect.right > This->currentDesc.Width) {
2973 This->glRect.right = This->currentDesc.Width;
2974 This->glRect.left = This->glRect.right - maxSize;
2976 } else {
2977 This->glRect.left = 0;
2978 This->glRect.right = This->pow2Width;
2981 if(This->pow2Height > maxSize) {
2982 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2983 if(This->glRect.top < 0) This->glRect.top = 0;
2984 This->glRect.bottom = This->glRect.left + maxSize;
2985 if(This->glRect.bottom > This->currentDesc.Height) {
2986 This->glRect.bottom = This->currentDesc.Height;
2987 This->glRect.top = This->glRect.bottom - maxSize;
2989 } else {
2990 This->glRect.top = 0;
2991 This->glRect.bottom = This->pow2Height;
2993 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2994 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2997 /* Re-calculate the rect to draw */
2998 Rect->left -= This->glRect.left;
2999 Rect->right -= This->glRect.left;
3000 Rect->top -= This->glRect.top;
3001 Rect->bottom -= This->glRect.top;
3003 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
3004 * or the pow2Width / pow2Height of the surface.
3006 * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
3007 * as regular GL_TEXTURE_2D.
3009 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
3010 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
3011 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
3012 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
3014 return TRUE;
3016 #undef GLINFO_LOCATION
3018 /* Hash table functions */
3020 hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
3022 hash_table_t *table;
3023 unsigned int initial_size = 8;
3025 table = HeapAlloc(GetProcessHeap(), 0, sizeof(hash_table_t) + (initial_size * sizeof(struct list)));
3026 if (!table)
3028 ERR("Failed to allocate table, returning NULL.\n");
3029 return NULL;
3032 table->hash_function = hash_function;
3033 table->compare_function = compare_function;
3035 table->grow_size = initial_size - (initial_size >> 2);
3036 table->shrink_size = 0;
3038 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
3039 if (!table->buckets)
3041 ERR("Failed to allocate table buckets, returning NULL.\n");
3042 HeapFree(GetProcessHeap(), 0, table);
3043 return NULL;
3045 table->bucket_count = initial_size;
3047 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(hash_table_entry_t));
3048 if (!table->entries)
3050 ERR("Failed to allocate table entries, returning NULL.\n");
3051 HeapFree(GetProcessHeap(), 0, table->buckets);
3052 HeapFree(GetProcessHeap(), 0, table);
3053 return NULL;
3055 table->entry_count = 0;
3057 list_init(&table->free_entries);
3058 table->count = 0;
3060 return table;
3063 void hash_table_destroy(hash_table_t *table)
3065 unsigned int i = 0;
3067 for (i = 0; i < table->entry_count; ++i)
3069 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
3072 HeapFree(GetProcessHeap(), 0, table->entries);
3073 HeapFree(GetProcessHeap(), 0, table->buckets);
3074 HeapFree(GetProcessHeap(), 0, table);
3077 static inline hash_table_entry_t *hash_table_get_by_idx(hash_table_t *table, void *key, unsigned int idx)
3079 hash_table_entry_t *entry;
3081 if (table->buckets[idx].next)
3082 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), hash_table_entry_t, entry)
3083 if (table->compare_function(entry->key, key)) return entry;
3085 return NULL;
3088 static BOOL hash_table_resize(hash_table_t *table, unsigned int new_bucket_count)
3090 unsigned int new_entry_count = 0;
3091 hash_table_entry_t *new_entries;
3092 struct list *new_buckets;
3093 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
3094 unsigned int i;
3096 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
3097 if (!new_buckets)
3099 ERR("Failed to allocate new buckets, returning FALSE.\n");
3100 return FALSE;
3103 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(hash_table_entry_t));
3104 if (!new_entries)
3106 ERR("Failed to allocate new entries, returning FALSE.\n");
3107 HeapFree(GetProcessHeap(), 0, new_buckets);
3108 return FALSE;
3111 for (i = 0; i < table->bucket_count; ++i)
3113 if (table->buckets[i].next)
3115 hash_table_entry_t *entry, *entry2;
3117 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], hash_table_entry_t, entry)
3119 int j;
3120 hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
3121 *new_entry = *entry;
3123 j = new_entry->hash & (new_bucket_count - 1);
3125 if (!new_buckets[j].next) list_init(&new_buckets[j]);
3126 list_add_head(&new_buckets[j], &new_entry->entry);
3131 HeapFree(GetProcessHeap(), 0, table->buckets);
3132 table->buckets = new_buckets;
3134 HeapFree(GetProcessHeap(), 0, table->entries);
3135 table->entries = new_entries;
3137 table->entry_count = new_entry_count;
3138 list_init(&table->free_entries);
3140 table->bucket_count = new_bucket_count;
3141 table->grow_size = grow_size;
3142 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
3144 return TRUE;
3147 void hash_table_put(hash_table_t *table, void *key, void *value)
3149 unsigned int idx;
3150 unsigned int hash;
3151 hash_table_entry_t *entry;
3153 hash = table->hash_function(key);
3154 idx = hash & (table->bucket_count - 1);
3155 entry = hash_table_get_by_idx(table, key, idx);
3157 if (entry)
3159 HeapFree(GetProcessHeap(), 0, key);
3160 entry->value = value;
3162 if (!value)
3164 HeapFree(GetProcessHeap(), 0, entry->key);
3165 entry->key = NULL;
3167 /* Remove the entry */
3168 list_remove(&entry->entry);
3169 list_add_head(&table->free_entries, &entry->entry);
3171 --table->count;
3173 /* Shrink if necessary */
3174 if (table->count < table->shrink_size) {
3175 if (!hash_table_resize(table, table->bucket_count >> 1))
3177 ERR("Failed to shrink the table...\n");
3182 return;
3185 if (!value) return;
3187 /* Grow if necessary */
3188 if (table->count >= table->grow_size)
3190 if (!hash_table_resize(table, table->bucket_count << 1))
3192 ERR("Failed to grow the table, returning.\n");
3193 return;
3196 idx = hash & (table->bucket_count - 1);
3199 /* Find an entry to insert */
3200 if (!list_empty(&table->free_entries))
3202 struct list *elem = list_head(&table->free_entries);
3204 list_remove(elem);
3205 entry = LIST_ENTRY(elem, hash_table_entry_t, entry);
3206 } else {
3207 entry = table->entries + (table->entry_count++);
3210 /* Insert the entry */
3211 entry->key = key;
3212 entry->value = value;
3213 entry->hash = hash;
3214 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
3215 list_add_head(&table->buckets[idx], &entry->entry);
3217 ++table->count;
3220 void hash_table_remove(hash_table_t *table, void *key)
3222 hash_table_put(table, key, NULL);
3225 void *hash_table_get(hash_table_t *table, void *key)
3227 unsigned int idx;
3228 hash_table_entry_t *entry;
3230 idx = table->hash_function(key) & (table->bucket_count - 1);
3231 entry = hash_table_get_by_idx(table, key, idx);
3233 return entry ? entry->value : NULL;
3236 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
3237 void gen_ffp_op(IWineD3DStateBlockImpl *stateblock, struct texture_stage_op op[MAX_TEXTURES]) {
3238 #define ARG1 0x01
3239 #define ARG2 0x02
3240 #define ARG0 0x04
3241 static const unsigned char args[WINED3DTOP_LERP + 1] = {
3242 /* undefined */ 0,
3243 /* D3DTOP_DISABLE */ 0,
3244 /* D3DTOP_SELECTARG1 */ ARG1,
3245 /* D3DTOP_SELECTARG2 */ ARG2,
3246 /* D3DTOP_MODULATE */ ARG1 | ARG2,
3247 /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
3248 /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
3249 /* D3DTOP_ADD */ ARG1 | ARG2,
3250 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
3251 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
3252 /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
3253 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
3254 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
3255 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
3256 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
3257 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
3258 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
3259 /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
3260 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
3261 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
3262 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
3263 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
3264 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
3265 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
3266 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
3267 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
3268 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
3270 unsigned int i;
3271 DWORD ttff;
3273 for(i = 0; i < GL_LIMITS(texture_stages); i++) {
3274 IWineD3DBaseTextureImpl *texture;
3275 if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
3276 op[i].cop = WINED3DTOP_DISABLE;
3277 op[i].aop = WINED3DTOP_DISABLE;
3278 op[i].carg0 = op[i].carg1 = op[i].carg2 = 0xffffffff;
3279 op[i].aarg0 = op[i].aarg1 = op[i].aarg2 = 0xffffffff;
3280 op[i].color_correction = WINED3DFMT_UNKNOWN;
3281 op[i].dst = 0xffffffff;
3282 i++;
3283 break;
3286 texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
3287 op[i].color_correction = texture ? texture->baseTexture.shader_conversion_group : WINED3DFMT_UNKNOWN;
3289 op[i].cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
3290 op[i].aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
3292 op[i].carg1 = (args[op[i].cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : 0xffffffff;
3293 op[i].carg2 = (args[op[i].cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : 0xffffffff;
3294 op[i].carg0 = (args[op[i].cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : 0xffffffff;
3296 if(is_invalid_op(stateblock->wineD3DDevice, i, op[i].cop, op[i].carg1, op[i].carg2, op[i].carg0)) {
3297 op[i].carg0 = 0xffffffff;
3298 op[i].carg2 = 0xffffffff;
3299 op[i].carg1 = WINED3DTA_CURRENT;
3300 op[i].cop = WINED3DTOP_SELECTARG1;
3303 op[i].aarg1 = (args[op[i].aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : 0xffffffff;
3304 op[i].aarg2 = (args[op[i].aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : 0xffffffff;
3305 op[i].aarg0 = (args[op[i].aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : 0xffffffff;
3307 if(is_invalid_op(stateblock->wineD3DDevice, i, op[i].aop, op[i].aarg1, op[i].aarg2, op[i].aarg0)) {
3308 op[i].aarg0 = 0xffffffff;
3309 op[i].aarg2 = 0xffffffff;
3310 op[i].aarg1 = WINED3DTA_CURRENT;
3311 op[i].aop = WINED3DTOP_SELECTARG1;
3312 } else if(i == 0 && stateblock->textures[0] &&
3313 stateblock->renderState[WINED3DRS_COLORKEYENABLE] &&
3314 (stateblock->textureDimensions[0] == GL_TEXTURE_2D ||
3315 stateblock->textureDimensions[0] == GL_TEXTURE_RECTANGLE_ARB)) {
3316 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
3318 if(surf->CKeyFlags & WINEDDSD_CKSRCBLT &&
3319 getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000) {
3321 if(op[0].aop == WINED3DTOP_DISABLE) {
3322 op[0].aarg1 = WINED3DTA_TEXTURE;
3323 op[0].aop = WINED3DTOP_SELECTARG1;
3325 else if(op[0].aop == WINED3DTOP_SELECTARG1 && op[0].aarg1 != WINED3DTA_TEXTURE) {
3326 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
3327 op[0].aarg2 = WINED3DTA_TEXTURE;
3328 op[0].aop = WINED3DTOP_MODULATE;
3330 else op[0].aarg1 = WINED3DTA_TEXTURE;
3332 else if(op[0].aop == WINED3DTOP_SELECTARG2 && op[0].aarg2 != WINED3DTA_TEXTURE) {
3333 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
3334 op[0].aarg1 = WINED3DTA_TEXTURE;
3335 op[0].aop = WINED3DTOP_MODULATE;
3337 else op[0].aarg2 = WINED3DTA_TEXTURE;
3342 if(op[i].carg1 == WINED3DTA_TEXTURE || op[i].carg2 == WINED3DTA_TEXTURE || op[i].carg0 == WINED3DTA_TEXTURE ||
3343 op[i].aarg1 == WINED3DTA_TEXTURE || op[i].aarg2 == WINED3DTA_TEXTURE || op[i].aarg0 == WINED3DTA_TEXTURE) {
3344 ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
3345 if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
3346 op[i].projected = proj_count3;
3347 } else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
3348 op[i].projected = proj_count4;
3349 } else {
3350 op[i].projected = proj_none;
3352 } else {
3353 op[i].projected = proj_none;
3356 op[i].dst = stateblock->textureState[i][WINED3DTSS_RESULTARG];
3359 /* Clear unsupported stages */
3360 for(; i < MAX_TEXTURES; i++) {
3361 memset(&op[i], 0xff, sizeof(op[i]));
3364 #undef GLINFO_LOCATION
3366 struct ffp_desc *find_ffp_shader(struct list *shaders, struct texture_stage_op op[MAX_TEXTURES])
3368 struct ffp_desc *entry;
3370 /* TODO: Optimize this. Finding the shader can be optimized by e.g. sorting the list,
3371 * or maybe consider using hashtables
3373 LIST_FOR_EACH_ENTRY(entry, shaders, struct ffp_desc, entry) {
3374 if(memcmp(op, entry->op, sizeof(struct texture_stage_op) * MAX_TEXTURES) == 0) {
3375 TRACE("Found shader entry %p\n", entry);
3376 return entry;
3380 TRACE("Shader not found\n");
3381 return NULL;
3384 void add_ffp_shader(struct list *shaders, struct ffp_desc *desc) {
3385 list_add_head(shaders, &desc->entry);