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