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