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