d3dx8: Add WINAPI to the prototypes of D3DXMatrixTransformation.
[wine/multimedia.git] / dlls / wined3d / utils.c
blobe108fca307891c4b31ccb1609236db5952fd0095
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 static const StaticPixelFormatDesc formats[] = {
34 /*{WINED3DFORMAT ,alphamask ,redmask ,greenmask ,bluemask ,bpp ,depth ,stencil, isFourcc*/
35 {WINED3DFMT_UNKNOWN ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
36 /* FourCC formats, kept here to have WINED3DFMT_R8G8B8(=20) at position 20 */
37 {WINED3DFMT_UYVY ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
38 {WINED3DFMT_YUY2 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
39 {WINED3DFMT_DXT1 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
40 {WINED3DFMT_DXT2 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
41 {WINED3DFMT_DXT3 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
42 {WINED3DFMT_DXT4 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
43 {WINED3DFMT_DXT5 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
44 {WINED3DFMT_MULTI2_ARGB8,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
45 {WINED3DFMT_G8R8_G8B8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
46 {WINED3DFMT_R8G8_B8G8 ,0x0 ,0x0 ,0x0 ,0x0 ,1/*?*/ ,0 ,0 ,TRUE },
47 /* IEEE formats */
48 {WINED3DFMT_R32F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
49 {WINED3DFMT_G32R32F ,0x0 ,0x0 ,0x0 ,0x0 ,8 ,0 ,0 ,FALSE },
50 {WINED3DFMT_A32B32G32R32F,0x0 ,0x0 ,0x0 ,0x0 ,16 ,0 ,0 ,FALSE },
51 /* Hmm? */
52 {WINED3DFMT_CxV8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
53 /* Float */
54 {WINED3DFMT_R16F ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
55 {WINED3DFMT_G16R16F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
56 {WINED3DFMT_A16B16G16R16F,0x0 ,0x0 ,0x0 ,0x0 ,8 ,0 ,0 ,FALSE },
57 /* Palettized formats */
58 {WINED3DFMT_A8P8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
59 {WINED3DFMT_P8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
60 /* Standard ARGB formats. Keep WINED3DFMT_R8G8B8(=20) at position 20 */
61 {WINED3DFMT_R8G8B8 ,0x0 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,3 ,0 ,0 ,FALSE },
62 {WINED3DFMT_A8R8G8B8 ,0xff000000 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,0 ,0 ,FALSE },
63 {WINED3DFMT_X8R8G8B8 ,0x0 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,0 ,0 ,FALSE },
64 {WINED3DFMT_R5G6B5 ,0x0 ,0x0000F800 ,0x000007e0 ,0x0000001f ,2 ,0 ,0 ,FALSE },
65 {WINED3DFMT_X1R5G5B5 ,0x0 ,0x00007c00 ,0x000003e0 ,0x0000001f ,2 ,0 ,0 ,FALSE },
66 {WINED3DFMT_A1R5G5B5 ,0x00008000 ,0x00007c00 ,0x000003e0 ,0x0000001f ,2 ,0 ,0 ,FALSE },
67 {WINED3DFMT_A4R4G4B4 ,0x0000f000 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,0 ,0 ,FALSE },
68 {WINED3DFMT_R3G3B2 ,0x0 ,0x000000e0 ,0x0000001c ,0x00000003 ,1 ,0 ,0 ,FALSE },
69 {WINED3DFMT_A8 ,0x000000ff ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
70 {WINED3DFMT_A8R3G3B2 ,0x0000ff00 ,0x000000e0 ,0x0000001c ,0x00000003 ,2 ,0 ,0 ,FALSE },
71 {WINED3DFMT_X4R4G4B4 ,0x0 ,0x00000f00 ,0x000000f0 ,0x0000000f ,2 ,0 ,0 ,FALSE },
72 {WINED3DFMT_A2B10G10R10 ,0xb0000000 ,0x000003ff ,0x000ffc00 ,0x3ff00000 ,4 ,0 ,0 ,FALSE },
73 {WINED3DFMT_A8B8G8R8 ,0xff000000 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,0 ,0 ,FALSE },
74 {WINED3DFMT_X8B8G8R8 ,0x0 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,0 ,0 ,FALSE },
75 {WINED3DFMT_G16R16 ,0x0 ,0x0000ffff ,0xffff0000 ,0x0 ,4 ,0 ,0 ,FALSE },
76 {WINED3DFMT_A2R10G10B10 ,0xb0000000 ,0x3ff00000 ,0x000ffc00 ,0x000003ff ,4 ,0 ,0 ,FALSE },
77 {WINED3DFMT_A16B16G16R16,0x0 ,0x0000ffff ,0xffff0000 ,0x0 ,8 ,0 ,0 ,FALSE },
78 /* Luminance */
79 {WINED3DFMT_L8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
80 {WINED3DFMT_A8L8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
81 {WINED3DFMT_A4L4 ,0x000000f0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,FALSE },
82 /* Bump mapping stuff */
83 {WINED3DFMT_V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
84 {WINED3DFMT_L6V5U5 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
85 {WINED3DFMT_X8L8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
86 {WINED3DFMT_Q8W8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
87 {WINED3DFMT_V16U16 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
88 {WINED3DFMT_W11V11U10 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
89 {WINED3DFMT_A2W10V10U10 ,0xb0000000 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
90 /* Depth stencil formats */
91 {WINED3DFMT_D16_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,2 ,16 ,0 ,FALSE },
92 {WINED3DFMT_D32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,32 ,0 ,FALSE },
93 {WINED3DFMT_D15S1 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,15 ,1 ,FALSE },
94 {WINED3DFMT_D24S8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,8 ,FALSE },
95 {WINED3DFMT_D24X8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,0 ,FALSE },
96 {WINED3DFMT_D24X4S4 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,4 ,FALSE },
97 {WINED3DFMT_D16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,16 ,0 ,FALSE },
98 {WINED3DFMT_L16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,16 ,0 ,FALSE },
99 {WINED3DFMT_D32F_LOCKABLE,0x0 ,0x0 ,0x0 ,0x0 ,4 ,32 ,0 ,FALSE },
100 {WINED3DFMT_D24FS8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,24 ,8 ,FALSE },
101 /* Is this a vertex buffer? */
102 {WINED3DFMT_VERTEXDATA ,0x0 ,0x0 ,0x0 ,0x0 ,0 ,0 ,0 ,FALSE },
103 {WINED3DFMT_INDEX16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
104 {WINED3DFMT_INDEX32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
105 {WINED3DFMT_Q16W16V16U16,0x0 ,0x0 ,0x0 ,0x0 ,8 ,0 ,0 ,FALSE },
108 typedef struct {
109 WINED3DFORMAT fmt;
110 GLint glInternal, glGammaInternal, glFormat, glType;
111 } GlPixelFormatDescTemplate;
113 /*****************************************************************************
114 * OpenGL format template. Contains unexciting formats which do not need
115 * extension checks. The order in this table is independent of the order in
116 * the table StaticPixelFormatDesc above. Not all formats have to be in this
117 * table.
119 static const GlPixelFormatDescTemplate gl_formats_template[] = {
120 /*{ internal ,srgbInternal ,format ,type }*/
121 {WINED3DFMT_UNKNOWN ,0 ,0 ,0 ,0 },
122 /* FourCC formats */
123 {WINED3DFMT_UYVY ,0 ,0 ,0 ,0 },
124 {WINED3DFMT_YUY2 ,0 ,0 ,0 ,0 },
125 {WINED3DFMT_DXT1 ,GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
126 {WINED3DFMT_DXT2 ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
127 {WINED3DFMT_DXT3 ,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
128 {WINED3DFMT_DXT4 ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
129 {WINED3DFMT_DXT5 ,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT ,GL_RGBA ,GL_UNSIGNED_BYTE },
130 {WINED3DFMT_MULTI2_ARGB8 ,0 ,0 ,0 ,0 },
131 {WINED3DFMT_G8R8_G8B8 ,0 ,0 ,0 ,0 },
132 {WINED3DFMT_R8G8_B8G8 ,0 ,0 ,0 ,0 },
133 /* IEEE formats */
134 {WINED3DFMT_R32F ,GL_RGB32F_ARB ,GL_RGB32F_ARB ,GL_RED ,GL_FLOAT },
135 {WINED3DFMT_G32R32F ,0 ,0 ,0 ,0 },
136 {WINED3DFMT_A32B32G32R32F ,GL_RGBA32F_ARB ,GL_RGBA32F_ARB ,GL_RGBA ,GL_FLOAT },
137 /* Hmm? */
138 {WINED3DFMT_CxV8U8 ,0 ,0 ,0 ,0 },
139 /* Float */
140 {WINED3DFMT_R16F ,GL_RGB16F_ARB ,GL_RGB16F_ARB ,GL_RED ,GL_HALF_FLOAT_ARB },
141 {WINED3DFMT_G16R16F ,0 ,0 ,0 ,0 },
142 {WINED3DFMT_A16B16G16R16F ,GL_RGBA16F_ARB ,GL_RGBA16F_ARB ,GL_RGBA ,GL_HALF_FLOAT_ARB },
143 /* Palettized formats */
144 {WINED3DFMT_A8P8, 0 ,0 ,0 ,0 },
145 {WINED3DFMT_P8, GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX ,GL_UNSIGNED_BYTE },
146 /* Standard ARGB formats */
147 {WINED3DFMT_R8G8B8 ,GL_RGB8 ,GL_RGB8 ,GL_BGR ,GL_UNSIGNED_BYTE },
148 {WINED3DFMT_A8R8G8B8 ,GL_RGBA8 ,GL_SRGB8_ALPHA8_EXT ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
149 {WINED3DFMT_X8R8G8B8 ,GL_RGB8 ,GL_SRGB8_EXT ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
150 {WINED3DFMT_R5G6B5 ,GL_RGB5 ,GL_RGB5 ,GL_RGB ,GL_UNSIGNED_SHORT_5_6_5 },
151 {WINED3DFMT_X1R5G5B5 ,GL_RGB5 ,GL_RGB5_A1 ,GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV },
152 {WINED3DFMT_A1R5G5B5 ,GL_RGB5_A1 ,GL_RGB5_A1 ,GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV },
153 {WINED3DFMT_A4R4G4B4 ,GL_RGBA4 ,GL_SRGB8_ALPHA8_EXT ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
154 {WINED3DFMT_R3G3B2 ,GL_R3_G3_B2 ,GL_R3_G3_B2 ,GL_RGB ,GL_UNSIGNED_BYTE_3_3_2 },
155 {WINED3DFMT_A8 ,GL_ALPHA8 ,GL_ALPHA8 ,GL_ALPHA ,GL_UNSIGNED_BYTE },
156 {WINED3DFMT_A8R3G3B2 ,0 ,0 ,0 ,0 },
157 {WINED3DFMT_X4R4G4B4 ,GL_RGB4 ,GL_RGB4 ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
158 {WINED3DFMT_A2B10G10R10 ,GL_RGBA ,GL_RGBA ,GL_RGBA ,GL_UNSIGNED_INT_2_10_10_10_REV },
159 {WINED3DFMT_A8B8G8R8 ,GL_RGBA8 ,GL_RGBA8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
160 {WINED3DFMT_X8B8G8R8 ,GL_RGB8 ,GL_RGB8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
161 {WINED3DFMT_G16R16 ,0 ,0 ,0 ,0 },
162 {WINED3DFMT_A2R10G10B10 ,GL_RGBA ,GL_RGBA ,GL_BGRA ,GL_UNSIGNED_INT_2_10_10_10_REV },
163 {WINED3DFMT_A16B16G16R16 ,GL_RGBA16_EXT ,GL_RGBA16_EXT ,GL_RGBA ,GL_UNSIGNED_SHORT },
164 /* Luminance */
165 {WINED3DFMT_L8 ,GL_LUMINANCE8 ,GL_SLUMINANCE8_EXT ,GL_LUMINANCE ,GL_UNSIGNED_BYTE },
166 {WINED3DFMT_A8L8 ,GL_LUMINANCE8_ALPHA8 ,GL_SLUMINANCE8_ALPHA8_EXT ,GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE },
167 {WINED3DFMT_A4L4 ,GL_LUMINANCE4_ALPHA4 ,GL_LUMINANCE4_ALPHA4 ,GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE },
168 /* Bump mapping stuff */
169 {WINED3DFMT_V8U8 ,GL_DSDT8_NV ,GL_DSDT8_NV ,GL_DSDT_NV ,GL_BYTE },
170 {WINED3DFMT_L6V5U5 ,GL_DSDT8_MAG8_NV ,GL_DSDT8_MAG8_NV ,GL_DSDT_MAG_NV ,GL_BYTE },
171 {WINED3DFMT_X8L8V8U8 ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT_MAG_VIB_NV ,GL_UNSIGNED_INT_8_8_S8_S8_REV_NV},
172 {WINED3DFMT_Q8W8V8U8 ,GL_SIGNED_RGBA8_NV ,GL_SIGNED_RGBA8_NV ,GL_RGBA ,GL_BYTE },
173 {WINED3DFMT_V16U16 ,GL_SIGNED_HILO16_NV ,GL_SIGNED_HILO16_NV ,GL_HILO_NV ,GL_SHORT },
174 {WINED3DFMT_W11V11U10 ,0 ,0 ,0 ,0 },
175 {WINED3DFMT_A2W10V10U10 ,0 ,0 ,0 ,0 },
176 /* Depth stencil formats */
177 {WINED3DFMT_D16_LOCKABLE ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT },
178 {WINED3DFMT_D32 ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
179 {WINED3DFMT_D15S1 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT },
180 {WINED3DFMT_D24S8 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
181 {WINED3DFMT_D24X8 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
182 {WINED3DFMT_D24X4S4 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_INT },
183 {WINED3DFMT_D16 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_UNSIGNED_SHORT },
184 {WINED3DFMT_L16 ,GL_LUMINANCE16_EXT ,GL_LUMINANCE16_EXT ,GL_LUMINANCE ,GL_UNSIGNED_SHORT },
185 {WINED3DFMT_D32F_LOCKABLE ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT32_ARB ,GL_DEPTH_COMPONENT ,GL_FLOAT },
186 {WINED3DFMT_D24FS8 ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT24_ARB ,GL_DEPTH_COMPONENT ,GL_FLOAT },
187 /* Is this a vertex buffer? */
188 {WINED3DFMT_VERTEXDATA ,0 ,0 ,0 ,0 },
189 {WINED3DFMT_INDEX16 ,0 ,0 ,0 ,0 },
190 {WINED3DFMT_INDEX32 ,0 ,0 ,0 ,0 },
191 {WINED3DFMT_Q16W16V16U16 ,GL_COLOR_INDEX ,GL_COLOR_INDEX ,GL_COLOR_INDEX ,GL_UNSIGNED_SHORT }
194 static inline int getFmtIdx(WINED3DFORMAT fmt) {
195 /* First check if the format is at the position of its value.
196 * This will catch the argb formats before the loop is entered
198 if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
199 return fmt;
200 } else {
201 unsigned int i;
202 for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
203 if(formats[i].format == fmt) {
204 return i;
208 return -1;
211 #define GLINFO_LOCATION (*gl_info)
212 BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
214 unsigned int src;
215 int dst;
217 gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
218 sizeof(formats) / sizeof(formats[0]) * sizeof(gl_info->gl_formats[0]));
219 if(!gl_info->gl_formats) return FALSE;
221 /* If a format depends on some extensions, remove them from the table above and initialize them
222 * after this loop
224 for(src = 0; src < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); src++) {
225 dst = getFmtIdx(gl_formats_template[src].fmt);
226 gl_info->gl_formats[dst].glInternal = gl_formats_template[src].glInternal;
227 gl_info->gl_formats[dst].glGammaInternal = gl_formats_template[src].glGammaInternal;
228 gl_info->gl_formats[dst].glFormat = gl_formats_template[src].glFormat;
229 gl_info->gl_formats[dst].glType = gl_formats_template[src].glType;
230 gl_info->gl_formats[dst].conversion_group= WINED3DFMT_UNKNOWN;
233 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
234 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
235 * their extensions are not available.
237 * In theory, V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
238 * returns 0.0 when sampling from it, DirectX 1.0. This is disabled until we find
239 * an application that needs this because it causes performance problems due to
240 * shader recompiling in some games.
242 if(!GL_SUPPORT(ATI_ENVMAP_BUMPMAP) && !GL_SUPPORT(NV_TEXTURE_SHADER2)) {
243 /* signed -> unsigned fixup */
244 dst = getFmtIdx(WINED3DFMT_V8U8);
245 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
246 dst = getFmtIdx(WINED3DFMT_V16U16);
247 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
248 } else if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
249 /* signed -> unsigned fixup */
250 dst = getFmtIdx(WINED3DFMT_V16U16);
251 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V16U16;
252 } else {
253 /* Blue = 1.0 fixup, disabled for now */
254 #if 0
255 dst = getFmtIdx(WINED3DFMT_V8U8);
256 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
257 dst = getFmtIdx(WINED3DFMT_V16U16);
258 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
259 #endif
262 if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
263 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
264 * with each other
266 dst = getFmtIdx(WINED3DFMT_L6V5U5);
267 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_L6V5U5;
268 dst = getFmtIdx(WINED3DFMT_X8L8V8U8);
269 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_X8L8V8U8;
270 dst = getFmtIdx(WINED3DFMT_Q8W8V8U8);
271 gl_info->gl_formats[dst].conversion_group = WINED3DFMT_Q8W8V8U8;
272 } else {
273 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
274 * are converted at surface loading time, but they do not need any modification in
275 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
276 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
280 return TRUE;
282 #undef GLINFO_LOCATION
284 #define GLINFO_LOCATION This->adapter->gl_info
286 const StaticPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, WineD3D_GL_Info *gl_info, const GlPixelFormatDesc **glDesc)
288 int idx = getFmtIdx(fmt);
290 if(idx == -1) {
291 FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
292 /* Get the caller a valid pointer */
293 idx = getFmtIdx(WINED3DFMT_UNKNOWN);
295 if(glDesc) {
296 if(!gl_info) {
297 ERR("OpenGL pixel format information was requested, but no gl info structure passed\n");
298 return NULL;
300 *glDesc = &gl_info->gl_formats[idx];
302 return &formats[idx];
305 /*****************************************************************************
306 * Trace formatting of useful values
308 const char* debug_d3dformat(WINED3DFORMAT fmt) {
309 switch (fmt) {
310 #define FMT_TO_STR(fmt) case fmt: return #fmt
311 FMT_TO_STR(WINED3DFMT_UNKNOWN);
312 FMT_TO_STR(WINED3DFMT_R8G8B8);
313 FMT_TO_STR(WINED3DFMT_A8R8G8B8);
314 FMT_TO_STR(WINED3DFMT_X8R8G8B8);
315 FMT_TO_STR(WINED3DFMT_R5G6B5);
316 FMT_TO_STR(WINED3DFMT_X1R5G5B5);
317 FMT_TO_STR(WINED3DFMT_A1R5G5B5);
318 FMT_TO_STR(WINED3DFMT_A4R4G4B4);
319 FMT_TO_STR(WINED3DFMT_R3G3B2);
320 FMT_TO_STR(WINED3DFMT_A8);
321 FMT_TO_STR(WINED3DFMT_A8R3G3B2);
322 FMT_TO_STR(WINED3DFMT_X4R4G4B4);
323 FMT_TO_STR(WINED3DFMT_A2B10G10R10);
324 FMT_TO_STR(WINED3DFMT_A8B8G8R8);
325 FMT_TO_STR(WINED3DFMT_X8B8G8R8);
326 FMT_TO_STR(WINED3DFMT_G16R16);
327 FMT_TO_STR(WINED3DFMT_A2R10G10B10);
328 FMT_TO_STR(WINED3DFMT_A16B16G16R16);
329 FMT_TO_STR(WINED3DFMT_A8P8);
330 FMT_TO_STR(WINED3DFMT_P8);
331 FMT_TO_STR(WINED3DFMT_L8);
332 FMT_TO_STR(WINED3DFMT_A8L8);
333 FMT_TO_STR(WINED3DFMT_A4L4);
334 FMT_TO_STR(WINED3DFMT_V8U8);
335 FMT_TO_STR(WINED3DFMT_L6V5U5);
336 FMT_TO_STR(WINED3DFMT_X8L8V8U8);
337 FMT_TO_STR(WINED3DFMT_Q8W8V8U8);
338 FMT_TO_STR(WINED3DFMT_V16U16);
339 FMT_TO_STR(WINED3DFMT_W11V11U10);
340 FMT_TO_STR(WINED3DFMT_A2W10V10U10);
341 FMT_TO_STR(WINED3DFMT_UYVY);
342 FMT_TO_STR(WINED3DFMT_YUY2);
343 FMT_TO_STR(WINED3DFMT_DXT1);
344 FMT_TO_STR(WINED3DFMT_DXT2);
345 FMT_TO_STR(WINED3DFMT_DXT3);
346 FMT_TO_STR(WINED3DFMT_DXT4);
347 FMT_TO_STR(WINED3DFMT_DXT5);
348 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
349 FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
350 FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
351 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
352 FMT_TO_STR(WINED3DFMT_D32);
353 FMT_TO_STR(WINED3DFMT_D15S1);
354 FMT_TO_STR(WINED3DFMT_D24S8);
355 FMT_TO_STR(WINED3DFMT_D24X8);
356 FMT_TO_STR(WINED3DFMT_D24X4S4);
357 FMT_TO_STR(WINED3DFMT_D16);
358 FMT_TO_STR(WINED3DFMT_L16);
359 FMT_TO_STR(WINED3DFMT_D32F_LOCKABLE);
360 FMT_TO_STR(WINED3DFMT_D24FS8);
361 FMT_TO_STR(WINED3DFMT_VERTEXDATA);
362 FMT_TO_STR(WINED3DFMT_INDEX16);
363 FMT_TO_STR(WINED3DFMT_INDEX32);
364 FMT_TO_STR(WINED3DFMT_Q16W16V16U16);
365 FMT_TO_STR(WINED3DFMT_R16F);
366 FMT_TO_STR(WINED3DFMT_G16R16F);
367 FMT_TO_STR(WINED3DFMT_A16B16G16R16F);
368 FMT_TO_STR(WINED3DFMT_R32F);
369 FMT_TO_STR(WINED3DFMT_G32R32F);
370 FMT_TO_STR(WINED3DFMT_A32B32G32R32F);
371 FMT_TO_STR(WINED3DFMT_CxV8U8);
372 #undef FMT_TO_STR
373 default:
375 char fourcc[5];
376 fourcc[0] = (char)(fmt);
377 fourcc[1] = (char)(fmt >> 8);
378 fourcc[2] = (char)(fmt >> 16);
379 fourcc[3] = (char)(fmt >> 24);
380 fourcc[4] = 0;
381 if( isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]) )
382 FIXME("Unrecognized %u (as fourcc: %s) WINED3DFORMAT!\n", fmt, fourcc);
383 else
384 FIXME("Unrecognized %u WINED3DFORMAT!\n", fmt);
386 return "unrecognized";
390 const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
391 switch (devtype) {
392 #define DEVTYPE_TO_STR(dev) case dev: return #dev
393 DEVTYPE_TO_STR(WINED3DDEVTYPE_HAL);
394 DEVTYPE_TO_STR(WINED3DDEVTYPE_REF);
395 DEVTYPE_TO_STR(WINED3DDEVTYPE_SW);
396 #undef DEVTYPE_TO_STR
397 default:
398 FIXME("Unrecognized %u WINED3DDEVTYPE!\n", devtype);
399 return "unrecognized";
403 const char* debug_d3dusage(DWORD usage) {
404 switch (usage & WINED3DUSAGE_MASK) {
405 #define WINED3DUSAGE_TO_STR(u) case u: return #u
406 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
407 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
408 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
409 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
410 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
411 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
412 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
413 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
414 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
415 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
416 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
417 #undef WINED3DUSAGE_TO_STR
418 case 0: return "none";
419 default:
420 FIXME("Unrecognized %u Usage!\n", usage);
421 return "unrecognized";
425 const char* debug_d3dusagequery(DWORD usagequery) {
426 switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
427 #define WINED3DUSAGEQUERY_TO_STR(u) case u: return #u
428 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
429 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
430 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
431 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
432 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
433 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
434 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
435 #undef WINED3DUSAGEQUERY_TO_STR
436 case 0: return "none";
437 default:
438 FIXME("Unrecognized %u Usage Query!\n", usagequery);
439 return "unrecognized";
443 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
444 switch (method) {
445 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
446 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
447 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
448 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
449 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
450 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
451 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
452 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
453 #undef WINED3DDECLMETHOD_TO_STR
454 default:
455 FIXME("Unrecognized %u declaration method!\n", method);
456 return "unrecognized";
460 const char* debug_d3ddecltype(WINED3DDECLTYPE type) {
461 switch (type) {
462 #define WINED3DDECLTYPE_TO_STR(u) case u: return #u
463 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT1);
464 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT2);
465 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT3);
466 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT4);
467 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_D3DCOLOR);
468 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4);
469 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2);
470 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4);
471 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UBYTE4N);
472 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT2N);
473 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_SHORT4N);
474 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT2N);
475 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_USHORT4N);
476 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UDEC3);
477 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_DEC3N);
478 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_2);
479 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_FLOAT16_4);
480 WINED3DDECLTYPE_TO_STR(WINED3DDECLTYPE_UNUSED);
481 #undef WINED3DDECLTYPE_TO_STR
482 default:
483 FIXME("Unrecognized %u declaration type!\n", type);
484 return "unrecognized";
488 const char* debug_d3ddeclusage(BYTE usage) {
489 switch (usage) {
490 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
491 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
492 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
493 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
494 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
495 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
496 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
497 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
498 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
499 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
500 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
501 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
502 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
503 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
504 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
505 #undef WINED3DDECLUSAGE_TO_STR
506 default:
507 FIXME("Unrecognized %u declaration usage!\n", usage);
508 return "unrecognized";
512 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
513 switch (res) {
514 #define RES_TO_STR(res) case res: return #res;
515 RES_TO_STR(WINED3DRTYPE_SURFACE);
516 RES_TO_STR(WINED3DRTYPE_VOLUME);
517 RES_TO_STR(WINED3DRTYPE_TEXTURE);
518 RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
519 RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
520 RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER);
521 RES_TO_STR(WINED3DRTYPE_INDEXBUFFER);
522 #undef RES_TO_STR
523 default:
524 FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res);
525 return "unrecognized";
529 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
530 switch (PrimitiveType) {
531 #define PRIM_TO_STR(prim) case prim: return #prim;
532 PRIM_TO_STR(WINED3DPT_POINTLIST);
533 PRIM_TO_STR(WINED3DPT_LINELIST);
534 PRIM_TO_STR(WINED3DPT_LINESTRIP);
535 PRIM_TO_STR(WINED3DPT_TRIANGLELIST);
536 PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP);
537 PRIM_TO_STR(WINED3DPT_TRIANGLEFAN);
538 #undef PRIM_TO_STR
539 default:
540 FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType);
541 return "unrecognized";
545 const char* debug_d3drenderstate(DWORD state) {
546 switch (state) {
547 #define D3DSTATE_TO_STR(u) case u: return #u
548 D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
549 D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
550 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
551 D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
552 D3DSTATE_TO_STR(WINED3DRS_WRAPU );
553 D3DSTATE_TO_STR(WINED3DRS_WRAPV );
554 D3DSTATE_TO_STR(WINED3DRS_ZENABLE );
555 D3DSTATE_TO_STR(WINED3DRS_FILLMODE );
556 D3DSTATE_TO_STR(WINED3DRS_SHADEMODE );
557 D3DSTATE_TO_STR(WINED3DRS_LINEPATTERN );
558 D3DSTATE_TO_STR(WINED3DRS_MONOENABLE );
559 D3DSTATE_TO_STR(WINED3DRS_ROP2 );
560 D3DSTATE_TO_STR(WINED3DRS_PLANEMASK );
561 D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
562 D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
563 D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
564 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
565 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
566 D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
567 D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
568 D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
569 D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
570 D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
571 D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
572 D3DSTATE_TO_STR(WINED3DRS_ALPHAFUNC );
573 D3DSTATE_TO_STR(WINED3DRS_DITHERENABLE );
574 D3DSTATE_TO_STR(WINED3DRS_ALPHABLENDENABLE );
575 D3DSTATE_TO_STR(WINED3DRS_FOGENABLE );
576 D3DSTATE_TO_STR(WINED3DRS_SPECULARENABLE );
577 D3DSTATE_TO_STR(WINED3DRS_ZVISIBLE );
578 D3DSTATE_TO_STR(WINED3DRS_SUBPIXEL );
579 D3DSTATE_TO_STR(WINED3DRS_SUBPIXELX );
580 D3DSTATE_TO_STR(WINED3DRS_STIPPLEDALPHA );
581 D3DSTATE_TO_STR(WINED3DRS_FOGCOLOR );
582 D3DSTATE_TO_STR(WINED3DRS_FOGTABLEMODE );
583 D3DSTATE_TO_STR(WINED3DRS_FOGSTART );
584 D3DSTATE_TO_STR(WINED3DRS_FOGEND );
585 D3DSTATE_TO_STR(WINED3DRS_FOGDENSITY );
586 D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
587 D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
588 D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
589 D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
590 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
591 D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
592 D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
593 D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
594 D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
595 D3DSTATE_TO_STR(WINED3DRS_ANISOTROPY );
596 D3DSTATE_TO_STR(WINED3DRS_FLUSHBATCH );
597 D3DSTATE_TO_STR(WINED3DRS_TRANSLUCENTSORTINDEPENDENT);
598 D3DSTATE_TO_STR(WINED3DRS_STENCILENABLE );
599 D3DSTATE_TO_STR(WINED3DRS_STENCILFAIL );
600 D3DSTATE_TO_STR(WINED3DRS_STENCILZFAIL );
601 D3DSTATE_TO_STR(WINED3DRS_STENCILPASS );
602 D3DSTATE_TO_STR(WINED3DRS_STENCILFUNC );
603 D3DSTATE_TO_STR(WINED3DRS_STENCILREF );
604 D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
605 D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
606 D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
607 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
608 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
609 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
610 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
611 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
612 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
613 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
614 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
615 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
616 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
617 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
618 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
619 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
620 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
621 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
622 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
623 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
624 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
625 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
626 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
627 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
628 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
629 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
630 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
631 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
632 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
633 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
634 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
635 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
636 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
637 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
638 D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
639 D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
640 D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
641 D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
642 D3DSTATE_TO_STR(WINED3DRS_WRAP3 );
643 D3DSTATE_TO_STR(WINED3DRS_WRAP4 );
644 D3DSTATE_TO_STR(WINED3DRS_WRAP5 );
645 D3DSTATE_TO_STR(WINED3DRS_WRAP6 );
646 D3DSTATE_TO_STR(WINED3DRS_WRAP7 );
647 D3DSTATE_TO_STR(WINED3DRS_CLIPPING );
648 D3DSTATE_TO_STR(WINED3DRS_LIGHTING );
649 D3DSTATE_TO_STR(WINED3DRS_EXTENTS );
650 D3DSTATE_TO_STR(WINED3DRS_AMBIENT );
651 D3DSTATE_TO_STR(WINED3DRS_FOGVERTEXMODE );
652 D3DSTATE_TO_STR(WINED3DRS_COLORVERTEX );
653 D3DSTATE_TO_STR(WINED3DRS_LOCALVIEWER );
654 D3DSTATE_TO_STR(WINED3DRS_NORMALIZENORMALS );
655 D3DSTATE_TO_STR(WINED3DRS_COLORKEYBLENDENABLE );
656 D3DSTATE_TO_STR(WINED3DRS_DIFFUSEMATERIALSOURCE );
657 D3DSTATE_TO_STR(WINED3DRS_SPECULARMATERIALSOURCE );
658 D3DSTATE_TO_STR(WINED3DRS_AMBIENTMATERIALSOURCE );
659 D3DSTATE_TO_STR(WINED3DRS_EMISSIVEMATERIALSOURCE );
660 D3DSTATE_TO_STR(WINED3DRS_VERTEXBLEND );
661 D3DSTATE_TO_STR(WINED3DRS_CLIPPLANEENABLE );
662 D3DSTATE_TO_STR(WINED3DRS_SOFTWAREVERTEXPROCESSING );
663 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE );
664 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MIN );
665 D3DSTATE_TO_STR(WINED3DRS_POINTSPRITEENABLE );
666 D3DSTATE_TO_STR(WINED3DRS_POINTSCALEENABLE );
667 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_A );
668 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_B );
669 D3DSTATE_TO_STR(WINED3DRS_POINTSCALE_C );
670 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEANTIALIAS );
671 D3DSTATE_TO_STR(WINED3DRS_MULTISAMPLEMASK );
672 D3DSTATE_TO_STR(WINED3DRS_PATCHEDGESTYLE );
673 D3DSTATE_TO_STR(WINED3DRS_PATCHSEGMENTS );
674 D3DSTATE_TO_STR(WINED3DRS_DEBUGMONITORTOKEN );
675 D3DSTATE_TO_STR(WINED3DRS_POINTSIZE_MAX );
676 D3DSTATE_TO_STR(WINED3DRS_INDEXEDVERTEXBLENDENABLE );
677 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE );
678 D3DSTATE_TO_STR(WINED3DRS_TWEENFACTOR );
679 D3DSTATE_TO_STR(WINED3DRS_BLENDOP );
680 D3DSTATE_TO_STR(WINED3DRS_POSITIONDEGREE );
681 D3DSTATE_TO_STR(WINED3DRS_NORMALDEGREE );
682 D3DSTATE_TO_STR(WINED3DRS_SCISSORTESTENABLE );
683 D3DSTATE_TO_STR(WINED3DRS_SLOPESCALEDEPTHBIAS );
684 D3DSTATE_TO_STR(WINED3DRS_ANTIALIASEDLINEENABLE );
685 D3DSTATE_TO_STR(WINED3DRS_MINTESSELLATIONLEVEL );
686 D3DSTATE_TO_STR(WINED3DRS_MAXTESSELLATIONLEVEL );
687 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_X );
688 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Y );
689 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_Z );
690 D3DSTATE_TO_STR(WINED3DRS_ADAPTIVETESS_W );
691 D3DSTATE_TO_STR(WINED3DRS_ENABLEADAPTIVETESSELLATION);
692 D3DSTATE_TO_STR(WINED3DRS_TWOSIDEDSTENCILMODE );
693 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFAIL );
694 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILZFAIL );
695 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILPASS );
696 D3DSTATE_TO_STR(WINED3DRS_CCW_STENCILFUNC );
697 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE1 );
698 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE2 );
699 D3DSTATE_TO_STR(WINED3DRS_COLORWRITEENABLE3 );
700 D3DSTATE_TO_STR(WINED3DRS_BLENDFACTOR );
701 D3DSTATE_TO_STR(WINED3DRS_SRGBWRITEENABLE );
702 D3DSTATE_TO_STR(WINED3DRS_DEPTHBIAS );
703 D3DSTATE_TO_STR(WINED3DRS_WRAP8 );
704 D3DSTATE_TO_STR(WINED3DRS_WRAP9 );
705 D3DSTATE_TO_STR(WINED3DRS_WRAP10 );
706 D3DSTATE_TO_STR(WINED3DRS_WRAP11 );
707 D3DSTATE_TO_STR(WINED3DRS_WRAP12 );
708 D3DSTATE_TO_STR(WINED3DRS_WRAP13 );
709 D3DSTATE_TO_STR(WINED3DRS_WRAP14 );
710 D3DSTATE_TO_STR(WINED3DRS_WRAP15 );
711 D3DSTATE_TO_STR(WINED3DRS_SEPARATEALPHABLENDENABLE );
712 D3DSTATE_TO_STR(WINED3DRS_SRCBLENDALPHA );
713 D3DSTATE_TO_STR(WINED3DRS_DESTBLENDALPHA );
714 D3DSTATE_TO_STR(WINED3DRS_BLENDOPALPHA );
715 #undef D3DSTATE_TO_STR
716 default:
717 FIXME("Unrecognized %u render state!\n", state);
718 return "unrecognized";
722 const char* debug_d3dsamplerstate(DWORD state) {
723 switch (state) {
724 #define D3DSTATE_TO_STR(u) case u: return #u
725 D3DSTATE_TO_STR(WINED3DSAMP_BORDERCOLOR );
726 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSU );
727 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSV );
728 D3DSTATE_TO_STR(WINED3DSAMP_ADDRESSW );
729 D3DSTATE_TO_STR(WINED3DSAMP_MAGFILTER );
730 D3DSTATE_TO_STR(WINED3DSAMP_MINFILTER );
731 D3DSTATE_TO_STR(WINED3DSAMP_MIPFILTER );
732 D3DSTATE_TO_STR(WINED3DSAMP_MIPMAPLODBIAS);
733 D3DSTATE_TO_STR(WINED3DSAMP_MAXMIPLEVEL );
734 D3DSTATE_TO_STR(WINED3DSAMP_MAXANISOTROPY);
735 D3DSTATE_TO_STR(WINED3DSAMP_SRGBTEXTURE );
736 D3DSTATE_TO_STR(WINED3DSAMP_ELEMENTINDEX );
737 D3DSTATE_TO_STR(WINED3DSAMP_DMAPOFFSET );
738 #undef D3DSTATE_TO_STR
739 default:
740 FIXME("Unrecognized %u sampler state!\n", state);
741 return "unrecognized";
745 const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) {
746 switch (filter_type) {
747 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
748 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_NONE);
749 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_POINT);
750 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_LINEAR);
751 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_ANISOTROPIC);
752 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_FLATCUBIC);
753 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANCUBIC);
754 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_PYRAMIDALQUAD);
755 D3DTEXTUREFILTERTYPE_TO_STR(WINED3DTEXF_GAUSSIANQUAD);
756 #undef D3DTEXTUREFILTERTYPE_TO_STR
757 default:
758 FIXME("Unrecognied texture filter type 0x%08x\n", filter_type);
759 return "unrecognized";
763 const char* debug_d3dtexturestate(DWORD state) {
764 switch (state) {
765 #define D3DSTATE_TO_STR(u) case u: return #u
766 D3DSTATE_TO_STR(WINED3DTSS_COLOROP );
767 D3DSTATE_TO_STR(WINED3DTSS_COLORARG1 );
768 D3DSTATE_TO_STR(WINED3DTSS_COLORARG2 );
769 D3DSTATE_TO_STR(WINED3DTSS_ALPHAOP );
770 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG1 );
771 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG2 );
772 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT00 );
773 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT01 );
774 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT10 );
775 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVMAT11 );
776 D3DSTATE_TO_STR(WINED3DTSS_TEXCOORDINDEX );
777 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE );
778 D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET );
779 D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
780 D3DSTATE_TO_STR(WINED3DTSS_ADDRESSW );
781 D3DSTATE_TO_STR(WINED3DTSS_COLORARG0 );
782 D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0 );
783 D3DSTATE_TO_STR(WINED3DTSS_RESULTARG );
784 D3DSTATE_TO_STR(WINED3DTSS_CONSTANT );
785 #undef D3DSTATE_TO_STR
786 case 12:
787 /* Note WINED3DTSS are not consecutive, so skip these */
788 return "unused";
789 default:
790 FIXME("Unrecognized %u texture state!\n", state);
791 return "unrecognized";
795 static const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
796 switch (d3dtop) {
797 #define D3DTOP_TO_STR(u) case u: return #u
798 D3DTOP_TO_STR(WINED3DTOP_DISABLE);
799 D3DTOP_TO_STR(WINED3DTOP_SELECTARG1);
800 D3DTOP_TO_STR(WINED3DTOP_SELECTARG2);
801 D3DTOP_TO_STR(WINED3DTOP_MODULATE);
802 D3DTOP_TO_STR(WINED3DTOP_MODULATE2X);
803 D3DTOP_TO_STR(WINED3DTOP_MODULATE4X);
804 D3DTOP_TO_STR(WINED3DTOP_ADD);
805 D3DTOP_TO_STR(WINED3DTOP_ADDSIGNED);
806 D3DTOP_TO_STR(WINED3DTOP_SUBTRACT);
807 D3DTOP_TO_STR(WINED3DTOP_ADDSMOOTH);
808 D3DTOP_TO_STR(WINED3DTOP_BLENDDIFFUSEALPHA);
809 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHA);
810 D3DTOP_TO_STR(WINED3DTOP_BLENDFACTORALPHA);
811 D3DTOP_TO_STR(WINED3DTOP_BLENDTEXTUREALPHAPM);
812 D3DTOP_TO_STR(WINED3DTOP_BLENDCURRENTALPHA);
813 D3DTOP_TO_STR(WINED3DTOP_PREMODULATE);
814 D3DTOP_TO_STR(WINED3DTOP_MODULATEALPHA_ADDCOLOR);
815 D3DTOP_TO_STR(WINED3DTOP_MODULATECOLOR_ADDALPHA);
816 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVALPHA_ADDCOLOR);
817 D3DTOP_TO_STR(WINED3DTOP_MODULATEINVCOLOR_ADDALPHA);
818 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAP);
819 D3DTOP_TO_STR(WINED3DTOP_BUMPENVMAPLUMINANCE);
820 D3DTOP_TO_STR(WINED3DTOP_DOTPRODUCT3);
821 D3DTOP_TO_STR(WINED3DTOP_MULTIPLYADD);
822 D3DTOP_TO_STR(WINED3DTOP_LERP);
823 #undef D3DTOP_TO_STR
824 default:
825 FIXME("Unrecognized %u WINED3DTOP\n", d3dtop);
826 return "unrecognized";
830 const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
831 switch (tstype) {
832 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
833 TSTYPE_TO_STR(WINED3DTS_VIEW);
834 TSTYPE_TO_STR(WINED3DTS_PROJECTION);
835 TSTYPE_TO_STR(WINED3DTS_TEXTURE0);
836 TSTYPE_TO_STR(WINED3DTS_TEXTURE1);
837 TSTYPE_TO_STR(WINED3DTS_TEXTURE2);
838 TSTYPE_TO_STR(WINED3DTS_TEXTURE3);
839 TSTYPE_TO_STR(WINED3DTS_TEXTURE4);
840 TSTYPE_TO_STR(WINED3DTS_TEXTURE5);
841 TSTYPE_TO_STR(WINED3DTS_TEXTURE6);
842 TSTYPE_TO_STR(WINED3DTS_TEXTURE7);
843 TSTYPE_TO_STR(WINED3DTS_WORLDMATRIX(0));
844 #undef TSTYPE_TO_STR
845 default:
846 if (tstype > 256 && tstype < 512) {
847 FIXME("WINED3DTS_WORLDMATRIX(%u). 1..255 not currently supported\n", tstype);
848 return ("WINED3DTS_WORLDMATRIX > 0");
850 FIXME("Unrecognized %u WINED3DTS\n", tstype);
851 return "unrecognized";
855 const char* debug_d3dpool(WINED3DPOOL Pool) {
856 switch (Pool) {
857 #define POOL_TO_STR(p) case p: return #p;
858 POOL_TO_STR(WINED3DPOOL_DEFAULT);
859 POOL_TO_STR(WINED3DPOOL_MANAGED);
860 POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
861 POOL_TO_STR(WINED3DPOOL_SCRATCH);
862 #undef POOL_TO_STR
863 default:
864 FIXME("Unrecognized %u WINED3DPOOL!\n", Pool);
865 return "unrecognized";
869 const char *debug_fbostatus(GLenum status) {
870 switch(status) {
871 #define FBOSTATUS_TO_STR(u) case u: return #u
872 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
873 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
874 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
875 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
876 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
877 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
878 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
879 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
880 #undef FBOSTATUS_TO_STR
881 default:
882 FIXME("Unrecognied FBO status 0x%08x\n", status);
883 return "unrecognized";
887 const char *debug_glerror(GLenum error) {
888 switch(error) {
889 #define GLERROR_TO_STR(u) case u: return #u
890 GLERROR_TO_STR(GL_NO_ERROR);
891 GLERROR_TO_STR(GL_INVALID_ENUM);
892 GLERROR_TO_STR(GL_INVALID_VALUE);
893 GLERROR_TO_STR(GL_INVALID_OPERATION);
894 GLERROR_TO_STR(GL_STACK_OVERFLOW);
895 GLERROR_TO_STR(GL_STACK_UNDERFLOW);
896 GLERROR_TO_STR(GL_OUT_OF_MEMORY);
897 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
898 #undef GLERROR_TO_STR
899 default:
900 FIXME("Unrecognied GL error 0x%08x\n", error);
901 return "unrecognized";
905 const char *debug_d3dbasis(WINED3DBASISTYPE basis) {
906 switch(basis) {
907 case WINED3DBASIS_BEZIER: return "WINED3DBASIS_BEZIER";
908 case WINED3DBASIS_BSPLINE: return "WINED3DBASIS_BSPLINE";
909 case WINED3DBASIS_INTERPOLATE: return "WINED3DBASIS_INTERPOLATE";
910 default: return "unrecognized";
914 const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
915 switch(degree) {
916 case WINED3DDEGREE_LINEAR: return "WINED3DDEGREE_LINEAR";
917 case WINED3DDEGREE_QUADRATIC: return "WINED3DDEGREE_QUADRATIC";
918 case WINED3DDEGREE_CUBIC: return "WINED3DDEGREE_CUBIC";
919 case WINED3DDEGREE_QUINTIC: return "WINED3DDEGREE_QUINTIC";
920 default: return "unrecognized";
924 /*****************************************************************************
925 * Useful functions mapping GL <-> D3D values
927 GLenum StencilOp(DWORD op) {
928 switch(op) {
929 case WINED3DSTENCILOP_KEEP : return GL_KEEP;
930 case WINED3DSTENCILOP_ZERO : return GL_ZERO;
931 case WINED3DSTENCILOP_REPLACE : return GL_REPLACE;
932 case WINED3DSTENCILOP_INCRSAT : return GL_INCR;
933 case WINED3DSTENCILOP_DECRSAT : return GL_DECR;
934 case WINED3DSTENCILOP_INVERT : return GL_INVERT;
935 case WINED3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
936 case WINED3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
937 default:
938 FIXME("Unrecognized stencil op %d\n", op);
939 return GL_KEEP;
943 GLenum CompareFunc(DWORD func) {
944 switch ((WINED3DCMPFUNC)func) {
945 case WINED3DCMP_NEVER : return GL_NEVER;
946 case WINED3DCMP_LESS : return GL_LESS;
947 case WINED3DCMP_EQUAL : return GL_EQUAL;
948 case WINED3DCMP_LESSEQUAL : return GL_LEQUAL;
949 case WINED3DCMP_GREATER : return GL_GREATER;
950 case WINED3DCMP_NOTEQUAL : return GL_NOTEQUAL;
951 case WINED3DCMP_GREATEREQUAL : return GL_GEQUAL;
952 case WINED3DCMP_ALWAYS : return GL_ALWAYS;
953 default:
954 FIXME("Unrecognized WINED3DCMPFUNC value %d\n", func);
955 return 0;
959 static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) {
960 switch (d3dta) {
961 case WINED3DTA_DIFFUSE:
962 return GL_PRIMARY_COLOR_NV;
964 case WINED3DTA_CURRENT:
965 if (stage) return GL_SPARE0_NV;
966 else return GL_PRIMARY_COLOR_NV;
968 case WINED3DTA_TEXTURE:
969 if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx;
970 else return GL_PRIMARY_COLOR_NV;
972 case WINED3DTA_TFACTOR:
973 return GL_CONSTANT_COLOR0_NV;
975 case WINED3DTA_SPECULAR:
976 return GL_SECONDARY_COLOR_NV;
978 case WINED3DTA_TEMP:
979 /* TODO: Support WINED3DTSS_RESULTARG */
980 FIXME("WINED3DTA_TEMP, not properly supported.\n");
981 return GL_SPARE1_NV;
983 case WINED3DTA_CONSTANT:
984 /* TODO: Support per stage constants (WINED3DTSS_CONSTANT, NV_register_combiners2) */
985 FIXME("WINED3DTA_CONSTANT, not properly supported.\n");
986 return GL_CONSTANT_COLOR1_NV;
988 default:
989 FIXME("Unrecognized texture arg %#x\n", d3dta);
990 return GL_TEXTURE;
994 static GLenum invert_mapping(GLenum mapping) {
995 if (mapping == GL_UNSIGNED_INVERT_NV) return GL_SIGNED_IDENTITY_NV;
996 else if (mapping == GL_SIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV;
998 FIXME("Unhandled mapping %#x\n", mapping);
999 return mapping;
1002 static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) {
1003 /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should
1004 * be used. */
1005 if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV;
1006 else *mapping = GL_SIGNED_IDENTITY_NV;
1008 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input
1009 * should be used for all input components. */
1010 if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA;
1011 else *component_usage = GL_RGB;
1013 *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx);
1016 typedef struct {
1017 GLenum input[3];
1018 GLenum mapping[3];
1019 GLenum component_usage[3];
1020 } tex_op_args;
1022 static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
1023 if (op == WINED3DTOP_DISABLE) return FALSE;
1024 if (This->stateBlock->textures[stage]) return FALSE;
1026 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1027 && op != WINED3DTOP_SELECTARG2) return TRUE;
1028 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1029 && op != WINED3DTOP_SELECTARG1) return TRUE;
1030 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
1031 && (op == WINED3DTOP_MULTIPLYADD || op == WINED3DTOP_LERP)) return TRUE;
1033 return FALSE;
1036 void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx) {
1037 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface;
1038 tex_op_args tex_op_args = {{0}, {0}, {0}};
1039 GLenum portion = is_alpha ? GL_ALPHA : GL_RGB;
1040 GLenum target = GL_COMBINER0_NV + stage;
1042 TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1043 stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx);
1045 /* If a texture stage references an invalid texture unit the stage just
1046 * passes through the result from the previous stage */
1047 if (is_invalid_op(This, stage, op, arg1, arg2, arg3)) {
1048 arg1 = WINED3DTA_CURRENT;
1049 op = WINED3DTOP_SELECTARG1;
1052 get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0],
1053 &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx);
1054 get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1],
1055 &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx);
1056 get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2],
1057 &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx);
1060 /* This is called by a state handler which has the gl lock held and a context for the thread */
1061 switch(op)
1063 case WINED3DTOP_DISABLE:
1064 /* Only for alpha */
1065 if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n");
1066 /* Input, prev_alpha*1 */
1067 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1068 GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
1069 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1070 GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
1072 /* Output */
1073 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1074 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1075 break;
1077 case WINED3DTOP_SELECTARG1:
1078 case WINED3DTOP_SELECTARG2:
1079 /* Input, arg*1 */
1080 if (op == WINED3DTOP_SELECTARG1) {
1081 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1082 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1083 } else {
1084 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1085 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1087 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1088 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1090 /* Output */
1091 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1092 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1093 break;
1095 case WINED3DTOP_MODULATE:
1096 case WINED3DTOP_MODULATE2X:
1097 case WINED3DTOP_MODULATE4X:
1098 /* Input, arg1*arg2 */
1099 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1100 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1101 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1102 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1104 /* Output */
1105 if (op == WINED3DTOP_MODULATE) {
1106 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1107 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1108 } else if (op == WINED3DTOP_MODULATE2X) {
1109 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1110 GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1111 } else if (op == WINED3DTOP_MODULATE4X) {
1112 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1113 GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1115 break;
1117 case WINED3DTOP_ADD:
1118 case WINED3DTOP_ADDSIGNED:
1119 case WINED3DTOP_ADDSIGNED2X:
1120 /* Input, arg1*1+arg2*1 */
1121 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1122 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1123 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1124 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1125 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1126 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1127 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1128 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1130 /* Output */
1131 if (op == WINED3DTOP_ADD) {
1132 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1133 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1134 } else if (op == WINED3DTOP_ADDSIGNED) {
1135 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1136 GL_SPARE0_NV, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
1137 } else if (op == WINED3DTOP_ADDSIGNED2X) {
1138 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1139 GL_SPARE0_NV, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
1141 break;
1143 case WINED3DTOP_SUBTRACT:
1144 /* Input, arg1*1+-arg2*1 */
1145 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1146 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1147 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1148 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1149 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1150 tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1]));
1151 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1152 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1154 /* Output */
1155 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1156 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1157 break;
1159 case WINED3DTOP_ADDSMOOTH:
1160 /* Input, arg1*1+(1-arg1)*arg2 */
1161 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1162 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1163 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1164 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1165 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1166 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1167 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1168 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1170 /* Output */
1171 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1172 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1173 break;
1175 case WINED3DTOP_BLENDDIFFUSEALPHA:
1176 case WINED3DTOP_BLENDTEXTUREALPHA:
1177 case WINED3DTOP_BLENDFACTORALPHA:
1178 case WINED3DTOP_BLENDTEXTUREALPHAPM:
1179 case WINED3DTOP_BLENDCURRENTALPHA:
1181 GLenum alpha_src = GL_PRIMARY_COLOR_NV;
1182 if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx);
1183 else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
1184 else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx);
1185 else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
1186 else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx);
1187 else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op));
1189 /* Input, arg1*alpha_src+arg2*(1-alpha_src) */
1190 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1191 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1192 if (op == WINED3DTOP_BLENDTEXTUREALPHAPM)
1194 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1195 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1196 } else {
1197 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1198 alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
1200 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1201 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1202 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1203 alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
1205 /* Output */
1206 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1207 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1208 break;
1211 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1212 /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */
1213 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n");
1214 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1215 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1216 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1217 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1218 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1219 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1220 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1221 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1223 /* Output */
1224 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1225 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1226 break;
1228 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1229 /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */
1230 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n");
1231 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1232 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1233 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1234 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1235 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1236 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1237 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1238 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1240 /* Output */
1241 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1242 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1243 break;
1245 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1246 /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */
1247 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n");
1248 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1249 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA));
1250 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1251 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1252 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1253 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1254 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1255 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1257 /* Output */
1258 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1259 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1260 break;
1262 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1263 /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */
1264 if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n");
1265 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1266 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1267 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1268 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1269 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1270 tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
1271 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1272 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1274 /* Output */
1275 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1276 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1277 break;
1279 case WINED3DTOP_DOTPRODUCT3:
1280 /* Input, arg1 . arg2 */
1281 /* FIXME: DX7 uses a different calculation? */
1282 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1283 tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0]));
1284 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1285 tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1]));
1287 /* Output */
1288 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1289 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE));
1290 break;
1292 case WINED3DTOP_MULTIPLYADD:
1293 /* Input, arg1*1+arg2*arg3 */
1294 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1295 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1296 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1297 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1298 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1299 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1300 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1301 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1303 /* Output */
1304 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1305 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1306 break;
1308 case WINED3DTOP_LERP:
1309 /* Input, arg1*arg2+(1-arg1)*arg3 */
1310 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
1311 tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
1312 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
1313 tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
1314 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
1315 tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
1316 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
1317 tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
1319 /* Output */
1320 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
1321 GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1322 break;
1324 case WINED3DTOP_BUMPENVMAPLUMINANCE:
1325 case WINED3DTOP_BUMPENVMAP:
1326 if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
1327 /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to
1328 * perform bump mapping and source from the current stage. Pretty much a SELECTARG2.
1329 * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1
1330 * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the next stage
1332 GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_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_B_NV,
1335 GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
1336 GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
1337 GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
1338 break;
1341 default:
1342 FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
1343 stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
1346 checkGLcall("set_tex_op_nvrc()\n");
1350 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
1351 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
1352 * input should be used for all input components. The WINED3DTA_COMPLEMENT
1353 * flag specifies the complement of the input should be used. */
1354 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
1355 BOOL complement = arg & WINED3DTA_COMPLEMENT;
1357 /* Calculate the operand */
1358 if (complement) {
1359 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
1360 else *operand = GL_ONE_MINUS_SRC_COLOR;
1361 } else {
1362 if (from_alpha) *operand = GL_SRC_ALPHA;
1363 else *operand = GL_SRC_COLOR;
1366 /* Calculate the source */
1367 switch (arg & WINED3DTA_SELECTMASK) {
1368 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
1369 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
1370 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
1371 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
1372 case WINED3DTA_SPECULAR:
1374 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
1375 * 'Secondary color' and isn't supported until base GL supports it
1376 * There is no concept of temp registers as far as I can tell
1378 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
1379 *source = GL_TEXTURE;
1380 break;
1381 default:
1382 FIXME("Unrecognized texture arg %#x\n", arg);
1383 *source = GL_TEXTURE;
1384 break;
1388 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
1389 #if defined (GL_VERSION_1_3)
1390 # define useext(A) A
1391 # define combine_ext 1
1392 #elif defined (GL_EXT_texture_env_combine)
1393 # define useext(A) A##_EXT
1394 # define combine_ext 1
1395 #elif defined (GL_ARB_texture_env_combine)
1396 # define useext(A) A##_ARB
1397 # define combine_ext 1
1398 #else
1399 # undef combine_ext
1400 #endif
1402 #if !defined(combine_ext)
1403 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1405 FIXME("Requires opengl combine extensions to work\n");
1406 return;
1408 #else
1409 /* Setup the texture operations texture stage states */
1410 void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1412 GLenum src1, src2, src3;
1413 GLenum opr1, opr2, opr3;
1414 GLenum comb_target;
1415 GLenum src0_target, src1_target, src2_target;
1416 GLenum opr0_target, opr1_target, opr2_target;
1417 GLenum scal_target;
1418 GLenum opr=0, invopr, src3_target, opr3_target;
1419 BOOL Handled = FALSE;
1420 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
1422 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
1424 /* This is called by a state handler which has the gl lock held and a context for the thread */
1426 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
1427 the form (a1 <operation> a2). However, some of the more complex operations
1428 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
1429 in a third parameter called a0. Therefore these are operations of the form
1430 a0 <operation> a1 <operation> a2, ie the new parameter goes to the front.
1432 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
1433 functions below, expect their syntax to differ slightly to those listed in the
1434 manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
1435 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
1437 if (isAlpha) {
1438 comb_target = useext(GL_COMBINE_ALPHA);
1439 src0_target = useext(GL_SOURCE0_ALPHA);
1440 src1_target = useext(GL_SOURCE1_ALPHA);
1441 src2_target = useext(GL_SOURCE2_ALPHA);
1442 opr0_target = useext(GL_OPERAND0_ALPHA);
1443 opr1_target = useext(GL_OPERAND1_ALPHA);
1444 opr2_target = useext(GL_OPERAND2_ALPHA);
1445 scal_target = GL_ALPHA_SCALE;
1447 else {
1448 comb_target = useext(GL_COMBINE_RGB);
1449 src0_target = useext(GL_SOURCE0_RGB);
1450 src1_target = useext(GL_SOURCE1_RGB);
1451 src2_target = useext(GL_SOURCE2_RGB);
1452 opr0_target = useext(GL_OPERAND0_RGB);
1453 opr1_target = useext(GL_OPERAND1_RGB);
1454 opr2_target = useext(GL_OPERAND2_RGB);
1455 scal_target = useext(GL_RGB_SCALE);
1458 /* If a texture stage references an invalid texture unit the stage just
1459 * passes through the result from the previous stage */
1460 if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) {
1461 arg1 = WINED3DTA_CURRENT;
1462 op = WINED3DTOP_SELECTARG1;
1465 /* From MSDN (WINED3DTSS_ALPHAARG1) :
1466 The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage,
1467 then the default argument is WINED3DTA_DIFFUSE.
1468 FIXME? If texture added/removed, may need to reset back as well? */
1469 if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
1470 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
1471 } else {
1472 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
1474 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
1475 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
1477 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
1479 Handled = TRUE; /* Assume will be handled */
1481 /* Other texture operations require special extensions: */
1482 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1483 if (isAlpha) {
1484 opr = GL_SRC_ALPHA;
1485 invopr = GL_ONE_MINUS_SRC_ALPHA;
1486 src3_target = GL_SOURCE3_ALPHA_NV;
1487 opr3_target = GL_OPERAND3_ALPHA_NV;
1488 } else {
1489 opr = GL_SRC_COLOR;
1490 invopr = GL_ONE_MINUS_SRC_COLOR;
1491 src3_target = GL_SOURCE3_RGB_NV;
1492 opr3_target = GL_OPERAND3_RGB_NV;
1494 switch (op) {
1495 case WINED3DTOP_DISABLE: /* Only for alpha */
1496 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1497 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1498 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1499 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1500 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1501 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1502 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1503 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1504 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1505 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1506 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1507 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1508 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1509 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1510 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1511 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1512 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1513 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1514 break;
1515 case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */
1516 case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
1517 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1518 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1519 if (op == WINED3DTOP_SELECTARG1) {
1520 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1521 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1522 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1523 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1524 } else {
1525 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1526 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1527 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1528 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1530 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1531 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1532 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1533 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1534 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1535 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1536 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1537 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1538 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1539 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1540 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1541 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1542 break;
1544 case WINED3DTOP_MODULATE:
1545 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1546 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1547 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1548 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1549 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1550 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1551 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1552 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1553 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1554 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1555 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1556 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1557 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1558 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1559 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1560 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1561 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1562 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1563 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1564 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1565 break;
1566 case WINED3DTOP_MODULATE2X:
1567 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1568 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1569 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1570 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1571 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1572 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1573 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1574 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1575 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1576 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1577 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1578 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1579 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1580 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1581 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1582 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1583 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1584 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1585 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1586 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1587 break;
1588 case WINED3DTOP_MODULATE4X:
1589 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1590 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1591 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1592 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1593 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1594 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1595 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1596 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1597 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1598 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1599 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1600 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1601 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1602 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1603 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1604 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1605 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1606 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1607 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
1608 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
1609 break;
1611 case WINED3DTOP_ADD:
1612 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1613 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1614 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1615 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1616 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1617 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1618 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1619 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1620 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1621 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1622 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1623 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1624 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1625 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1626 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1627 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1628 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1629 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1630 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1631 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1632 break;
1634 case WINED3DTOP_ADDSIGNED:
1635 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1636 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1637 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1638 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1639 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1640 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1641 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1642 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1643 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1644 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1645 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1646 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1647 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1648 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1649 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1650 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1651 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1652 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1653 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1654 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1655 break;
1657 case WINED3DTOP_ADDSIGNED2X:
1658 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
1659 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
1660 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1661 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1662 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1663 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1664 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1665 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1666 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1667 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1668 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1669 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1670 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1671 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1672 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1673 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1674 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1675 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1676 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
1677 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
1678 break;
1680 case WINED3DTOP_ADDSMOOTH:
1681 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1682 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1683 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1684 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1685 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1686 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1687 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1688 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1689 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1690 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1691 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1692 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1693 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1694 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1695 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1696 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1697 switch (opr1) {
1698 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1699 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1700 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1701 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1703 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1704 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1705 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1706 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1707 break;
1709 case WINED3DTOP_BLENDDIFFUSEALPHA:
1710 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1711 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1712 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1713 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1714 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1715 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1716 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
1717 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
1718 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1719 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1720 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1721 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1722 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1723 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1724 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
1725 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
1726 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1727 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1728 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1729 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1730 break;
1731 case WINED3DTOP_BLENDTEXTUREALPHA:
1732 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1733 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1734 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1735 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1736 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1737 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1738 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
1739 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
1740 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1741 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1742 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1743 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1744 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1745 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1746 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1747 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1748 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1749 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1750 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1751 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1752 break;
1753 case WINED3DTOP_BLENDFACTORALPHA:
1754 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1755 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1756 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1757 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1758 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1759 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1760 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
1761 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
1762 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1763 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1764 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1765 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1766 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1767 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1768 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
1769 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
1770 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1771 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1772 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1773 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1774 break;
1775 case WINED3DTOP_BLENDTEXTUREALPHAPM:
1776 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1777 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1778 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1779 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1780 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1781 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1782 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1783 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1784 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1785 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1786 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1787 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1788 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1789 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1790 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1791 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1792 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1793 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1794 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1795 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1796 break;
1797 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
1798 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1799 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
1800 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
1801 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1802 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1803 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
1804 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1805 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1806 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1807 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1808 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
1809 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1810 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1811 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
1812 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1813 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1814 switch (opr) {
1815 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1816 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1818 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1819 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1820 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1821 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1822 break;
1823 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
1824 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1825 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1826 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1827 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1828 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1829 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1830 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1831 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1832 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1833 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1834 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1835 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1836 switch (opr1) {
1837 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1838 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1840 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1841 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1842 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1843 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1844 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1845 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1846 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1847 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1848 break;
1849 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
1850 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1851 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1852 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1853 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1854 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1855 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1856 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1857 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1858 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1859 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1860 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1861 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1862 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1863 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1864 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1865 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1866 switch (opr1) {
1867 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1868 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1869 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1870 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1872 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1873 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1874 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1875 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1876 break;
1877 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
1878 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1879 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1880 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1881 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1882 switch (opr1) {
1883 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1884 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1885 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1886 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1888 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
1889 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
1890 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1891 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1892 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1893 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1894 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1895 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1896 switch (opr1) {
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, opr2_target, opr);
1901 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1902 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1903 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1904 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1905 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1906 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1907 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1908 break;
1909 case WINED3DTOP_MULTIPLYADD:
1910 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1911 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1912 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
1913 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1914 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
1915 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1916 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1917 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1918 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1919 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1920 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1921 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1922 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1923 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1924 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
1925 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
1926 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
1927 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
1928 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1929 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1930 break;
1932 case WINED3DTOP_BUMPENVMAP:
1936 case WINED3DTOP_BUMPENVMAPLUMINANCE:
1937 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
1939 default:
1940 Handled = FALSE;
1942 if (Handled) {
1943 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
1944 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
1946 return;
1948 } /* GL_NV_texture_env_combine4 */
1950 Handled = TRUE; /* Again, assume handled */
1951 switch (op) {
1952 case WINED3DTOP_DISABLE: /* Only for alpha */
1953 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1954 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1955 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1956 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
1957 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1958 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
1959 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1960 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1961 break;
1962 case WINED3DTOP_SELECTARG1:
1963 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1964 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1965 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1966 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1967 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1968 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1969 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1970 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1971 break;
1972 case WINED3DTOP_SELECTARG2:
1973 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
1974 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1975 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
1976 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1977 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
1978 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
1979 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1980 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1981 break;
1982 case WINED3DTOP_MODULATE:
1983 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1984 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1985 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1986 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1987 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1988 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1989 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1990 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1991 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1992 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1993 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1994 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1995 break;
1996 case WINED3DTOP_MODULATE2X:
1997 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
1998 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
1999 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2000 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2001 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2002 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2003 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2004 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2005 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2006 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2007 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2008 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2009 break;
2010 case WINED3DTOP_MODULATE4X:
2011 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2012 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2013 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2014 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2015 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2016 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2017 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2018 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2019 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2020 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2021 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2022 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2023 break;
2024 case WINED3DTOP_ADD:
2025 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2026 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2027 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2028 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2029 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2030 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2031 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2032 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2033 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2034 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2035 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2036 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2037 break;
2038 case WINED3DTOP_ADDSIGNED:
2039 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2040 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
2041 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2042 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2043 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2044 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2045 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2046 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2047 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2048 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2049 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2050 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2051 break;
2052 case WINED3DTOP_ADDSIGNED2X:
2053 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2054 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2055 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2056 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2057 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2058 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2059 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2060 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2061 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2062 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2063 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2064 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2065 break;
2066 case WINED3DTOP_SUBTRACT:
2067 if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
2068 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2069 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
2070 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2071 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2072 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2073 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2074 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2075 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2076 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2077 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2078 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2079 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2080 } else {
2081 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2083 break;
2085 case WINED3DTOP_BLENDDIFFUSEALPHA:
2086 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2087 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2088 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2089 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2090 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2091 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2092 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2093 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2094 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2095 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2096 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
2097 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2098 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2099 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2100 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2101 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2102 break;
2103 case WINED3DTOP_BLENDTEXTUREALPHA:
2104 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2105 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2106 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2107 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2108 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2109 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2110 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2111 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2112 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2113 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2114 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2115 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2116 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2117 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2118 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2119 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2120 break;
2121 case WINED3DTOP_BLENDFACTORALPHA:
2122 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2123 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2124 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2125 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2126 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2127 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2128 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2129 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2130 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2131 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2132 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
2133 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2134 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2135 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2136 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2137 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2138 break;
2139 case WINED3DTOP_BLENDCURRENTALPHA:
2140 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2141 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2142 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2143 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2144 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2145 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2146 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2147 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2148 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2149 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2150 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
2151 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2152 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2153 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2154 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2155 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2156 break;
2157 case WINED3DTOP_DOTPRODUCT3:
2158 if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
2159 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2160 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2161 } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
2162 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2163 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2164 } else {
2165 FIXME("This version of opengl does not support GL_DOT3\n");
2167 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2168 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2169 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2170 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2171 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2172 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2173 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2174 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2175 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2176 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2177 break;
2178 case WINED3DTOP_LERP:
2179 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2180 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2181 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2182 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2183 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2184 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2185 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2186 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2187 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2188 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2189 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2190 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2191 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2192 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2193 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2194 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2195 break;
2196 case WINED3DTOP_ADDSMOOTH:
2197 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2198 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2199 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2200 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2201 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2202 switch (opr1) {
2203 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2204 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2205 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2206 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2208 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2209 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2210 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2211 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2212 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2213 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2214 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2215 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2216 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2217 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2218 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2219 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2220 } else
2221 Handled = FALSE;
2222 break;
2223 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2224 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2225 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2226 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2227 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2228 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2229 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2230 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2231 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2232 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2233 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2234 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2235 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2236 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2237 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2238 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2239 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2240 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2241 } else
2242 Handled = FALSE;
2243 break;
2244 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2245 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2246 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2247 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2248 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2249 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2250 switch (opr1) {
2251 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2252 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2253 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2254 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2256 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2257 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2258 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2259 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2260 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2261 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2262 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2263 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2264 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2265 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2266 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2267 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2268 } else
2269 Handled = FALSE;
2270 break;
2271 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2272 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2273 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2274 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2275 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2276 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2277 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2278 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2279 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2280 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2281 switch (opr1) {
2282 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2283 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2284 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2285 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2287 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2288 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2289 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2290 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2291 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2292 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2293 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2294 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2295 } else
2296 Handled = FALSE;
2297 break;
2298 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2299 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2300 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2301 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2302 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2303 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2304 switch (opr1) {
2305 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2306 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2307 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2308 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2310 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2311 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2312 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2313 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2314 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2315 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2316 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2317 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2318 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2319 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2320 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2321 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2322 } else
2323 Handled = FALSE;
2324 break;
2325 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2326 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2327 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2328 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2329 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2330 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2331 switch (opr1) {
2332 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2333 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2334 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2335 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2337 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2338 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2339 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2340 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2341 switch (opr1) {
2342 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2343 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2344 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2345 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2347 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2348 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2349 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2350 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2351 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2352 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2353 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2354 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2355 } else
2356 Handled = FALSE;
2357 break;
2358 case WINED3DTOP_MULTIPLYADD:
2359 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2360 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2361 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2362 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2363 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2364 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2365 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2366 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2367 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2368 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2369 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2370 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2371 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2372 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2373 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2374 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2375 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2376 } else
2377 Handled = FALSE;
2378 break;
2379 case WINED3DTOP_BUMPENVMAPLUMINANCE:
2380 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2381 /* Some apps use BUMPENVMAPLUMINANCE instead of D3DTOP_BUMPENVMAP, although
2382 * they check for the non-luminance cap flag. Well, give them what they asked
2383 * for :-)
2385 WARN("Application uses WINED3DTOP_BUMPENVMAPLUMINANCE\n");
2386 } else {
2387 Handled = FALSE;
2388 break;
2390 /* Fall through */
2391 case WINED3DTOP_BUMPENVMAP:
2392 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2393 TRACE("Using ati bumpmap on stage %d, target %d\n", Stage, Stage + 1);
2394 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI);
2395 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI)");
2396 glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1);
2397 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1)");
2398 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2399 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2400 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2401 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2402 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2403 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2404 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2405 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2406 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2407 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2408 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2409 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2411 Handled = TRUE;
2412 break;
2413 } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2414 /* Technically texture shader support without register combiners is possible, but not expected to occur
2415 * on real world cards, so for now a fixme should be enough
2417 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
2419 default:
2420 Handled = FALSE;
2423 if (Handled) {
2424 BOOL combineOK = TRUE;
2425 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2426 DWORD op2;
2428 if (isAlpha) {
2429 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP];
2430 } else {
2431 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP];
2434 /* Note: If COMBINE4 in effect can't go back to combine! */
2435 switch (op2) {
2436 case WINED3DTOP_ADDSMOOTH:
2437 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2438 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2439 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2440 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2441 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2442 case WINED3DTOP_MULTIPLYADD:
2443 /* Ignore those implemented in both cases */
2444 switch (op) {
2445 case WINED3DTOP_SELECTARG1:
2446 case WINED3DTOP_SELECTARG2:
2447 combineOK = FALSE;
2448 Handled = FALSE;
2449 break;
2450 default:
2451 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
2452 return;
2457 if (combineOK) {
2458 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
2459 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
2461 return;
2465 /* After all the extensions, if still unhandled, report fixme */
2466 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
2467 #undef GLINFO_LOCATION
2469 #endif
2471 /* Setup this textures matrix according to the texture flags*/
2472 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype)
2474 float mat[16];
2476 glMatrixMode(GL_TEXTURE);
2477 checkGLcall("glMatrixMode(GL_TEXTURE)");
2479 if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
2480 glLoadIdentity();
2481 checkGLcall("glLoadIdentity()");
2482 return;
2485 if (flags == (WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED)) {
2486 ERR("Invalid texture transform flags: WINED3DTTFF_COUNT1|WINED3DTTFF_PROJECTED\n");
2487 return;
2490 memcpy(mat, smat, 16 * sizeof(float));
2492 if (flags & WINED3DTTFF_PROJECTED) {
2493 switch (flags & ~WINED3DTTFF_PROJECTED) {
2494 case WINED3DTTFF_COUNT2:
2495 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
2496 mat[1] = mat[5] = mat[9] = mat[13] = 0;
2497 break;
2498 case WINED3DTTFF_COUNT3:
2499 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
2500 mat[2] = mat[6] = mat[10] = mat[14] = 0;
2501 break;
2503 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
2504 if(!calculatedCoords) {
2505 switch(coordtype) {
2506 case WINED3DDECLTYPE_FLOAT1:
2507 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
2508 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
2509 * the input value to the transformation will be 0, so the matrix value is irrelevant
2511 mat[12] = mat[4];
2512 mat[13] = mat[5];
2513 mat[14] = mat[6];
2514 mat[15] = mat[7];
2515 break;
2516 case WINED3DDECLTYPE_FLOAT2:
2517 /* See above, just 3rd and 4th coord
2519 mat[12] = mat[8];
2520 mat[13] = mat[9];
2521 mat[14] = mat[10];
2522 mat[15] = mat[11];
2523 break;
2524 case WINED3DDECLTYPE_FLOAT3: /* Opengl defaults match dx defaults */
2525 case WINED3DDECLTYPE_FLOAT4: /* No defaults apply, all app defined */
2527 /* This is to prevent swaping the matrix lines and put the default 4th coord = 1.0
2528 * into a bad place. The division elimination below will apply to make sure the
2529 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
2531 case WINED3DDECLTYPE_UNUSED: /* No texture coords, 0/0/0/1 defaults are passed */
2532 break;
2533 default:
2534 FIXME("Unexpected fixed function texture coord input\n");
2537 switch (flags & ~WINED3DTTFF_PROJECTED) {
2538 /* case WINED3DTTFF_COUNT1: Won't ever get here */
2539 case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
2540 /* OpenGL divides the first 3 vertex coord by the 4th by default,
2541 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
2542 * the 4th coord evaluates to 1.0 to eliminate that.
2544 * If the fixed function pipeline is used, the 4th value remains unused,
2545 * so there is no danger in doing this. With vertex shaders we have a
2546 * problem. Should an app hit that problem, the code here would have to
2547 * check for pixel shaders, and the shader has to undo the default gl divide.
2549 * A more serious problem occurs if the app passes 4 coordinates in, and the
2550 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
2551 * or a replacement shader
2553 default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
2557 glLoadMatrixf(mat);
2558 checkGLcall("glLoadMatrixf(mat)");
2561 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
2563 /* This small helper function is used to convert a bitmask into the number of masked bits */
2564 unsigned int count_bits(unsigned int mask)
2566 unsigned int count;
2567 for (count = 0; mask; ++count)
2569 mask &= mask - 1;
2571 return count;
2574 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
2575 * The later function requires individual color components. */
2576 BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
2578 const StaticPixelFormatDesc *desc;
2580 TRACE("fmt: %s\n", debug_d3dformat(fmt));
2581 switch(fmt)
2583 case WINED3DFMT_X8R8G8B8:
2584 case WINED3DFMT_R8G8B8:
2585 case WINED3DFMT_A8R8G8B8:
2586 case WINED3DFMT_A2R10G10B10:
2587 case WINED3DFMT_X1R5G5B5:
2588 case WINED3DFMT_A1R5G5B5:
2589 case WINED3DFMT_R5G6B5:
2590 case WINED3DFMT_X4R4G4B4:
2591 case WINED3DFMT_A4R4G4B4:
2592 case WINED3DFMT_R3G3B2:
2593 case WINED3DFMT_A8P8:
2594 case WINED3DFMT_P8:
2595 break;
2596 default:
2597 ERR("Unsupported format: %s\n", debug_d3dformat(fmt));
2598 return FALSE;
2601 desc = getFormatDescEntry(fmt, NULL, NULL);
2602 if(!desc)
2604 ERR("Unable to look up format: 0x%x\n", fmt);
2605 return FALSE;
2607 *redSize = count_bits(desc->redMask);
2608 *greenSize = count_bits(desc->greenMask);
2609 *blueSize = count_bits(desc->blueMask);
2610 *alphaSize = count_bits(desc->alphaMask);
2611 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
2613 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for fmt=%s\n", *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(fmt));
2614 return TRUE;
2617 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
2618 BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize)
2620 const StaticPixelFormatDesc *desc;
2622 TRACE("fmt: %s\n", debug_d3dformat(fmt));
2623 switch(fmt)
2625 case WINED3DFMT_D16_LOCKABLE:
2626 case WINED3DFMT_D16:
2627 case WINED3DFMT_D15S1:
2628 case WINED3DFMT_D24X8:
2629 case WINED3DFMT_D24X4S4:
2630 case WINED3DFMT_D24S8:
2631 case WINED3DFMT_D24FS8:
2632 case WINED3DFMT_D32:
2633 break;
2634 default:
2635 FIXME("Unsupported stencil format: %s\n", debug_d3dformat(fmt));
2636 return FALSE;
2639 desc = getFormatDescEntry(fmt, NULL, NULL);
2640 if(!desc)
2642 ERR("Unable to look up format: 0x%x\n", fmt);
2643 return FALSE;
2645 *depthSize = desc->depthSize;
2646 *stencilSize = desc->stencilSize;
2648 TRACE("Returning depthSize: %d and stencilSize: %d for fmt=%s\n", *depthSize, *stencilSize, debug_d3dformat(fmt));
2649 return TRUE;
2652 #undef GLINFO_LOCATION
2654 /* DirectDraw stuff */
2655 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
2656 switch(depth) {
2657 case 8: return WINED3DFMT_P8;
2658 case 15: return WINED3DFMT_X1R5G5B5;
2659 case 16: return WINED3DFMT_R5G6B5;
2660 case 24: return WINED3DFMT_R8G8B8;
2661 case 32: return WINED3DFMT_X8R8G8B8;
2662 default: return WINED3DFMT_UNKNOWN;
2666 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2) {
2667 WINED3DMATRIX temp;
2669 /* Now do the multiplication 'by hand'.
2670 I know that all this could be optimised, but this will be done later :-) */
2671 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);
2672 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);
2673 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);
2674 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);
2676 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);
2677 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);
2678 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);
2679 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);
2681 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);
2682 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);
2683 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);
2684 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);
2686 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);
2687 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);
2688 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);
2689 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);
2691 /* And copy the new matrix in the good storage.. */
2692 memcpy(dest, &temp, 16 * sizeof(float));
2695 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
2696 DWORD size = 0;
2697 int i;
2698 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
2700 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
2701 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
2702 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
2703 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
2704 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
2705 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
2706 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
2707 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
2708 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
2709 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
2710 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
2711 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
2712 default: ERR("Unexpected position mask\n");
2714 for (i = 0; i < numTextures; i++) {
2715 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
2718 return size;
2721 /***********************************************************************
2722 * CalculateTexRect
2724 * Calculates the dimensions of the opengl texture used for blits.
2725 * Handled oversized opengl textures and updates the source rectangle
2726 * accordingly
2728 * Params:
2729 * This: Surface to operate on
2730 * Rect: Requested rectangle
2732 * Returns:
2733 * TRUE if the texture part can be loaded,
2734 * FALSE otherwise
2736 *********************************************************************/
2737 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
2739 BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) {
2740 int x1 = Rect->left, x2 = Rect->right;
2741 int y1 = Rect->top, y2 = Rect->bottom;
2742 GLint maxSize = GL_LIMITS(texture_size);
2744 TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
2745 Rect->left, Rect->top, Rect->right, Rect->bottom);
2747 /* The sizes might be reversed */
2748 if(Rect->left > Rect->right) {
2749 x1 = Rect->right;
2750 x2 = Rect->left;
2752 if(Rect->top > Rect->bottom) {
2753 y1 = Rect->bottom;
2754 y2 = Rect->top;
2757 /* No oversized texture? This is easy */
2758 if(!(This->Flags & SFLAG_OVERSIZE)) {
2759 /* Which rect from the texture do I need? */
2760 glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
2761 glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
2762 glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
2763 glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
2765 return TRUE;
2766 } else {
2767 /* Check if we can succeed at all */
2768 if( (x2 - x1) > maxSize ||
2769 (y2 - y1) > maxSize ) {
2770 TRACE("Requested rectangle is too large for gl\n");
2771 return FALSE;
2774 /* A part of the texture has to be picked. First, check if
2775 * some texture part is loaded already, if yes try to re-use it.
2776 * If the texture is dirty, or the part can't be used,
2777 * re-position the part to load
2779 if(This->Flags & SFLAG_INTEXTURE) {
2780 if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
2781 This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
2782 /* Ok, the rectangle is ok, re-use it */
2783 TRACE("Using existing gl Texture\n");
2784 } else {
2785 /* Rectangle is not ok, dirtify the texture to reload it */
2786 TRACE("Dirtifying texture to force reload\n");
2787 This->Flags &= ~SFLAG_INTEXTURE;
2791 /* Now if we are dirty(no else if!) */
2792 if(!(This->Flags & SFLAG_INTEXTURE)) {
2793 /* Set the new rectangle. Use the following strategy:
2794 * 1) Use as big textures as possible.
2795 * 2) Place the texture part in the way that the requested
2796 * part is in the middle of the texture(well, almost)
2797 * 3) If the texture is moved over the edges of the
2798 * surface, replace it nicely
2799 * 4) If the coord is not limiting the texture size,
2800 * use the whole size
2802 if((This->pow2Width) > maxSize) {
2803 This->glRect.left = x1 - maxSize / 2;
2804 if(This->glRect.left < 0) {
2805 This->glRect.left = 0;
2807 This->glRect.right = This->glRect.left + maxSize;
2808 if(This->glRect.right > This->currentDesc.Width) {
2809 This->glRect.right = This->currentDesc.Width;
2810 This->glRect.left = This->glRect.right - maxSize;
2812 } else {
2813 This->glRect.left = 0;
2814 This->glRect.right = This->pow2Width;
2817 if(This->pow2Height > maxSize) {
2818 This->glRect.top = x1 - GL_LIMITS(texture_size) / 2;
2819 if(This->glRect.top < 0) This->glRect.top = 0;
2820 This->glRect.bottom = This->glRect.left + maxSize;
2821 if(This->glRect.bottom > This->currentDesc.Height) {
2822 This->glRect.bottom = This->currentDesc.Height;
2823 This->glRect.top = This->glRect.bottom - maxSize;
2825 } else {
2826 This->glRect.top = 0;
2827 This->glRect.bottom = This->pow2Height;
2829 TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
2830 This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
2833 /* Re-calculate the rect to draw */
2834 Rect->left -= This->glRect.left;
2835 Rect->right -= This->glRect.left;
2836 Rect->top -= This->glRect.top;
2837 Rect->bottom -= This->glRect.top;
2839 /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
2840 * or the pow2Width / pow2Height of the surface
2842 glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
2843 glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
2844 glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
2845 glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
2847 return TRUE;
2849 #undef GLINFO_LOCATION
2851 /* Hash table functions */
2853 hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
2855 hash_table_t *table;
2856 unsigned int initial_size = 8;
2858 table = HeapAlloc(GetProcessHeap(), 0, sizeof(hash_table_t) + (initial_size * sizeof(struct list)));
2859 if (!table)
2861 ERR("Failed to allocate table, returning NULL.\n");
2862 return NULL;
2865 table->hash_function = hash_function;
2866 table->compare_function = compare_function;
2868 table->grow_size = initial_size - (initial_size >> 2);
2869 table->shrink_size = 0;
2871 table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
2872 if (!table->buckets)
2874 ERR("Failed to allocate table buckets, returning NULL.\n");
2875 HeapFree(GetProcessHeap(), 0, table);
2876 return NULL;
2878 table->bucket_count = initial_size;
2880 table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(hash_table_entry_t));
2881 if (!table->entries)
2883 ERR("Failed to allocate table entries, returning NULL.\n");
2884 HeapFree(GetProcessHeap(), 0, table->buckets);
2885 HeapFree(GetProcessHeap(), 0, table);
2886 return NULL;
2888 table->entry_count = 0;
2890 list_init(&table->free_entries);
2891 table->count = 0;
2893 return table;
2896 void hash_table_destroy(hash_table_t *table)
2898 unsigned int i = 0;
2900 for (i = 0; i < table->entry_count; ++i)
2902 HeapFree(GetProcessHeap(), 0, table->entries[i].key);
2905 HeapFree(GetProcessHeap(), 0, table->entries);
2906 HeapFree(GetProcessHeap(), 0, table->buckets);
2907 HeapFree(GetProcessHeap(), 0, table);
2910 static inline hash_table_entry_t *hash_table_get_by_idx(hash_table_t *table, void *key, unsigned int idx)
2912 hash_table_entry_t *entry;
2914 if (table->buckets[idx].next)
2915 LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), hash_table_entry_t, entry)
2916 if (table->compare_function(entry->key, key)) return entry;
2918 return NULL;
2921 static BOOL hash_table_resize(hash_table_t *table, unsigned int new_bucket_count)
2923 unsigned int new_entry_count = 0;
2924 hash_table_entry_t *new_entries;
2925 struct list *new_buckets;
2926 unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
2927 unsigned int i;
2929 new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
2930 if (!new_buckets)
2932 ERR("Failed to allocate new buckets, returning FALSE.\n");
2933 return FALSE;
2936 new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(hash_table_entry_t));
2937 if (!new_entries)
2939 ERR("Failed to allocate new entries, returning FALSE.\n");
2940 HeapFree(GetProcessHeap(), 0, new_buckets);
2941 return FALSE;
2944 for (i = 0; i < table->bucket_count; ++i)
2946 if (table->buckets[i].next)
2948 hash_table_entry_t *entry, *entry2;
2950 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], hash_table_entry_t, entry)
2952 int j;
2953 hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
2954 *new_entry = *entry;
2956 j = new_entry->hash & (new_bucket_count - 1);
2958 if (!new_buckets[j].next) list_init(&new_buckets[j]);
2959 list_add_head(&new_buckets[j], &new_entry->entry);
2964 HeapFree(GetProcessHeap(), 0, table->buckets);
2965 table->buckets = new_buckets;
2967 HeapFree(GetProcessHeap(), 0, table->entries);
2968 table->entries = new_entries;
2970 table->entry_count = new_entry_count;
2971 list_init(&table->free_entries);
2973 table->bucket_count = new_bucket_count;
2974 table->grow_size = grow_size;
2975 table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
2977 return TRUE;
2980 void hash_table_put(hash_table_t *table, void *key, void *value)
2982 unsigned int idx;
2983 unsigned int hash;
2984 hash_table_entry_t *entry;
2986 hash = table->hash_function(key);
2987 idx = hash & (table->bucket_count - 1);
2988 entry = hash_table_get_by_idx(table, key, idx);
2990 if (entry)
2992 HeapFree(GetProcessHeap(), 0, key);
2993 entry->value = value;
2995 if (!value)
2997 HeapFree(GetProcessHeap(), 0, entry->key);
2998 entry->key = NULL;
3000 /* Remove the entry */
3001 list_remove(&entry->entry);
3002 list_add_head(&table->free_entries, &entry->entry);
3004 --table->count;
3006 /* Shrink if necessary */
3007 if (table->count < table->shrink_size) {
3008 if (!hash_table_resize(table, table->bucket_count >> 1))
3010 ERR("Failed to shrink the table...\n");
3015 return;
3018 if (!value) return;
3020 /* Grow if necessary */
3021 if (table->count >= table->grow_size)
3023 if (!hash_table_resize(table, table->bucket_count << 1))
3025 ERR("Failed to grow the table, returning.\n");
3026 return;
3029 idx = hash & (table->bucket_count - 1);
3032 /* Find an entry to insert */
3033 if (!list_empty(&table->free_entries))
3035 struct list *elem = list_head(&table->free_entries);
3037 list_remove(elem);
3038 entry = LIST_ENTRY(elem, hash_table_entry_t, entry);
3039 } else {
3040 entry = table->entries + (table->entry_count++);
3043 /* Insert the entry */
3044 entry->key = key;
3045 entry->value = value;
3046 entry->hash = hash;
3047 if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
3048 list_add_head(&table->buckets[idx], &entry->entry);
3050 ++table->count;
3053 void hash_table_remove(hash_table_t *table, void *key)
3055 hash_table_put(table, key, NULL);
3058 void *hash_table_get(hash_table_t *table, void *key)
3060 unsigned int idx;
3061 hash_table_entry_t *entry;
3063 idx = table->hash_function(key) & (table->bucket_count - 1);
3064 entry = hash_table_get_by_idx(table, key, idx);
3066 return entry ? entry->value : NULL;