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