Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenutils.c
Go to the documentation of this file.
00001 /* 00002 * Utility functions for the WineD3D Library 00003 * 00004 * Copyright 2002-2004 Jason Edmeades 00005 * Copyright 2003-2004 Raphael Junqueira 00006 * Copyright 2004 Christian Costa 00007 * Copyright 2005 Oliver Stieber 00008 * Copyright 2006-2008 Henri Verbeet 00009 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers 00010 * Copyright 2009-2010 Henri Verbeet for CodeWeavers 00011 * 00012 * This library is free software; you can redistribute it and/or 00013 * modify it under the terms of the GNU Lesser General Public 00014 * License as published by the Free Software Foundation; either 00015 * version 2.1 of the License, or (at your option) any later version. 00016 * 00017 * This library is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00020 * Lesser General Public License for more details. 00021 * 00022 * You should have received a copy of the GNU Lesser General Public 00023 * License along with this library; if not, write to the Free Software 00024 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00025 */ 00026 00027 #include "config.h" 00028 #include "wined3d_private.h" 00029 00030 WINE_DEFAULT_DEBUG_CHANNEL(d3d); 00031 00032 struct StaticPixelFormatDesc 00033 { 00034 enum wined3d_format_id id; 00035 DWORD alphaMask, redMask, greenMask, blueMask; 00036 UINT bpp; 00037 BYTE depthSize, stencilSize; 00038 }; 00039 00040 /***************************************************************************** 00041 * Pixel format array 00042 * 00043 * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F, 00044 * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the 00045 * high masks do not fit into the 32 bit values needed for ddraw. It is only 00046 * used for ddraw mostly, and to figure out if the format has alpha at all, so 00047 * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit 00048 * formats are not usable in 2D rendering because ddraw doesn't support them. 00049 */ 00050 static const struct StaticPixelFormatDesc formats[] = 00051 { 00052 /* format id alphamask redmask greenmask bluemask bpp depth stencil */ 00053 {WINED3DFMT_UNKNOWN, 0x0, 0x0, 0x0, 0x0, 0, 0, 0}, 00054 /* FourCC formats */ 00055 {WINED3DFMT_UYVY, 0x0, 0x0, 0x0, 0x0, 2, 0, 0}, 00056 {WINED3DFMT_YUY2, 0x0, 0x0, 0x0, 0x0, 2, 0, 0}, 00057 {WINED3DFMT_YV12, 0x0, 0x0, 0x0, 0x0, 1, 0, 0}, 00058 {WINED3DFMT_DXT1, 0x0, 0x0, 0x0, 0x0, 1, 0, 0}, 00059 {WINED3DFMT_DXT2, 0x0, 0x0, 0x0, 0x0, 1, 0, 0}, 00060 {WINED3DFMT_DXT3, 0x0, 0x0, 0x0, 0x0, 1, 0, 0}, 00061 {WINED3DFMT_DXT4, 0x0, 0x0, 0x0, 0x0, 1, 0, 0}, 00062 {WINED3DFMT_DXT5, 0x0, 0x0, 0x0, 0x0, 1, 0, 0}, 00063 {WINED3DFMT_MULTI2_ARGB8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0}, 00064 {WINED3DFMT_G8R8_G8B8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0}, 00065 {WINED3DFMT_R8G8_B8G8, 0x0, 0x0, 0x0, 0x0, 1/*?*/, 0, 0}, 00066 /* IEEE formats */ 00067 {WINED3DFMT_R32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0}, 00068 {WINED3DFMT_R32G32_FLOAT, 0x0, 0x0, 0x0, 0x0, 8, 0, 0}, 00069 {WINED3DFMT_R32G32B32_FLOAT, 0x0, 0x0, 0x0, 0x0, 12, 0, 0}, 00070 {WINED3DFMT_R32G32B32A32_FLOAT, 0x1, 0x0, 0x0, 0x0, 16, 0, 0}, 00071 /* Hmm? */ 00072 {WINED3DFMT_R8G8_SNORM_Cx, 0x0, 0x0, 0x0, 0x0, 2, 0, 0}, 00073 /* Float */ 00074 {WINED3DFMT_R16_FLOAT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0}, 00075 {WINED3DFMT_R16G16_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0}, 00076 {WINED3DFMT_R16G16_SINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0}, 00077 {WINED3DFMT_R16G16B16A16_FLOAT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0}, 00078 {WINED3DFMT_R16G16B16A16_SINT, 0x1, 0x0, 0x0, 0x0, 8, 0, 0}, 00079 /* Palettized formats */ 00080 {WINED3DFMT_P8_UINT_A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0}, 00081 {WINED3DFMT_P8_UINT, 0x0, 0x0, 0x0, 0x0, 1, 0, 0}, 00082 /* Standard ARGB formats. */ 00083 {WINED3DFMT_B8G8R8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 3, 0, 0}, 00084 {WINED3DFMT_B8G8R8A8_UNORM, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0}, 00085 {WINED3DFMT_B8G8R8X8_UNORM, 0x0, 0x00ff0000, 0x0000ff00, 0x000000ff, 4, 0, 0}, 00086 {WINED3DFMT_B5G6R5_UNORM, 0x0, 0x0000f800, 0x000007e0, 0x0000001f, 2, 0, 0}, 00087 {WINED3DFMT_B5G5R5X1_UNORM, 0x0, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0}, 00088 {WINED3DFMT_B5G5R5A1_UNORM, 0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2, 0, 0}, 00089 {WINED3DFMT_B4G4R4A4_UNORM, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0}, 00090 {WINED3DFMT_B2G3R3_UNORM, 0x0, 0x000000e0, 0x0000001c, 0x00000003, 1, 0, 0}, 00091 {WINED3DFMT_A8_UNORM, 0x000000ff, 0x0, 0x0, 0x0, 1, 0, 0}, 00092 {WINED3DFMT_B2G3R3A8_UNORM, 0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2, 0, 0}, 00093 {WINED3DFMT_B4G4R4X4_UNORM, 0x0, 0x00000f00, 0x000000f0, 0x0000000f, 2, 0, 0}, 00094 {WINED3DFMT_R10G10B10A2_UNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0}, 00095 {WINED3DFMT_R10G10B10A2_UINT, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0}, 00096 {WINED3DFMT_R10G10B10A2_SNORM, 0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4, 0, 0}, 00097 {WINED3DFMT_R8G8B8A8_UNORM, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0}, 00098 {WINED3DFMT_R8G8B8A8_UINT, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0}, 00099 {WINED3DFMT_R8G8B8X8_UNORM, 0x0, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0}, 00100 {WINED3DFMT_R16G16_UNORM, 0x0, 0x0000ffff, 0xffff0000, 0x0, 4, 0, 0}, 00101 {WINED3DFMT_B10G10R10A2_UNORM, 0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4, 0, 0}, 00102 {WINED3DFMT_R16G16B16A16_UNORM, 0x1, 0x0000ffff, 0xffff0000, 0x0, 8, 0, 0}, 00103 /* Luminance */ 00104 {WINED3DFMT_L8_UNORM, 0x0, 0x0, 0x0, 0x0, 1, 0, 0}, 00105 {WINED3DFMT_L8A8_UNORM, 0x0000ff00, 0x0, 0x0, 0x0, 2, 0, 0}, 00106 {WINED3DFMT_L4A4_UNORM, 0x000000f0, 0x0, 0x0, 0x0, 1, 0, 0}, 00107 {WINED3DFMT_L16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0}, 00108 /* Bump mapping stuff */ 00109 {WINED3DFMT_R8G8_SNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0}, 00110 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 0, 0}, 00111 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0}, 00112 {WINED3DFMT_R8G8B8A8_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0}, 00113 {WINED3DFMT_R16G16_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0}, 00114 {WINED3DFMT_R10G11B11_SNORM, 0x0, 0x0, 0x0, 0x0, 4, 0, 0}, 00115 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 0xb0000000, 0x0, 0x0, 0x0, 4, 0, 0}, 00116 /* Depth stencil formats */ 00117 {WINED3DFMT_D16_LOCKABLE, 0x0, 0x0, 0x0, 0x0, 2, 16, 0}, 00118 {WINED3DFMT_D32_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 32, 0}, 00119 {WINED3DFMT_S1_UINT_D15_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 15, 1}, 00120 {WINED3DFMT_D24_UNORM_S8_UINT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8}, 00121 {WINED3DFMT_X8D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 0}, 00122 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0x0, 0x0, 0x0, 0x0, 4, 24, 4}, 00123 {WINED3DFMT_D16_UNORM, 0x0, 0x0, 0x0, 0x0, 2, 16, 0}, 00124 {WINED3DFMT_D32_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 32, 0}, 00125 {WINED3DFMT_S8_UINT_D24_FLOAT, 0x0, 0x0, 0x0, 0x0, 4, 24, 8}, 00126 {WINED3DFMT_VERTEXDATA, 0x0, 0x0, 0x0, 0x0, 0, 0, 0}, 00127 {WINED3DFMT_R16_UINT, 0x0, 0x0, 0x0, 0x0, 2, 0, 0}, 00128 {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0}, 00129 {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0}, 00130 /* Vendor-specific formats */ 00131 {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0}, 00132 {WINED3DFMT_NVDB, 0x0, 0x0, 0x0, 0x0, 0, 0, 0}, 00133 {WINED3DFMT_INTZ, 0x0, 0x0, 0x0, 0x0, 4, 24, 8}, 00134 {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0}, 00135 {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0}, 00136 {WINED3DFMT_NULL, 0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4, 0, 0}, 00137 /* Unsure about them, could not find a Windows driver that supports them */ 00138 {WINED3DFMT_R16, 0x0, 0x0000ffff, 0x0, 0x0, 2, 0, 0}, 00139 {WINED3DFMT_AL16, 0xffff0000, 0x0, 0x0, 0x0, 4, 0, 0}, 00140 }; 00141 00142 struct wined3d_format_base_flags 00143 { 00144 enum wined3d_format_id id; 00145 DWORD flags; 00146 }; 00147 00148 /* The ATI2N format behaves like an uncompressed format in LockRect(), but 00149 * still needs to use the correct block based calculation for e.g. the 00150 * resource size. */ 00151 static const struct wined3d_format_base_flags format_base_flags[] = 00152 { 00153 {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC}, 00154 {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC}, 00155 {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC}, 00156 {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC}, 00157 {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC}, 00158 {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC}, 00159 {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC}, 00160 {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC}, 00161 {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC}, 00162 {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC}, 00163 {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC}, 00164 {WINED3DFMT_INTZ, WINED3DFMT_FLAG_FOURCC}, 00165 {WINED3DFMT_NULL, WINED3DFMT_FLAG_FOURCC}, 00166 {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC}, 00167 {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC}, 00168 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC}, 00169 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC}, 00170 {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC}, 00171 {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC}, 00172 {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC}, 00173 {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC}, 00174 {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC}, 00175 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC}, 00176 {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC}, 00177 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH}, 00178 {WINED3DFMT_NVDB, WINED3DFMT_FLAG_FOURCC}, 00179 {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC}, 00180 {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC}, 00181 {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT}, 00182 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT}, 00183 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT}, 00184 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT}, 00185 {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT}, 00186 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT}, 00187 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT}, 00188 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT}, 00189 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT}, 00190 }; 00191 00192 struct wined3d_format_block_info 00193 { 00194 enum wined3d_format_id id; 00195 UINT block_width; 00196 UINT block_height; 00197 UINT block_byte_count; 00198 }; 00199 00200 static const struct wined3d_format_block_info format_block_info[] = 00201 { 00202 {WINED3DFMT_DXT1, 4, 4, 8}, 00203 {WINED3DFMT_DXT2, 4, 4, 16}, 00204 {WINED3DFMT_DXT3, 4, 4, 16}, 00205 {WINED3DFMT_DXT4, 4, 4, 16}, 00206 {WINED3DFMT_DXT5, 4, 4, 16}, 00207 {WINED3DFMT_ATI2N, 4, 4, 16}, 00208 {WINED3DFMT_YUY2, 2, 1, 4}, 00209 {WINED3DFMT_UYVY, 2, 1, 4}, 00210 }; 00211 00212 struct wined3d_format_vertex_info 00213 { 00214 enum wined3d_format_id id; 00215 enum wined3d_ffp_emit_idx emit_idx; 00216 GLint component_count; 00217 GLenum gl_vtx_type; 00218 GLint gl_vtx_format; 00219 GLboolean gl_normalized; 00220 unsigned int component_size; 00221 }; 00222 00223 static const struct wined3d_format_vertex_info format_vertex_info[] = 00224 { 00225 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)}, 00226 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)}, 00227 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)}, 00228 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)}, 00229 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)}, 00230 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)}, 00231 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)}, 00232 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)}, 00233 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)}, 00234 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)}, 00235 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)}, 00236 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)}, 00237 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)}, 00238 {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)}, 00239 {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)}, 00240 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)}, 00241 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)} 00242 }; 00243 00244 struct wined3d_format_texture_info 00245 { 00246 enum wined3d_format_id id; 00247 GLint gl_internal; 00248 GLint gl_srgb_internal; 00249 GLint gl_rt_internal; 00250 GLint gl_format; 00251 GLint gl_type; 00252 unsigned int conv_byte_count; 00253 unsigned int flags; 00254 enum wined3d_gl_extension extension; 00255 void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height); 00256 }; 00257 00258 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) 00259 { 00260 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not 00261 * format+type combination to load it. Thus convert it to A8L8, then load it 00262 * with A4L4 internal, but A8L8 format+type 00263 */ 00264 unsigned int x, y; 00265 const unsigned char *Source; 00266 unsigned char *Dest; 00267 UINT outpitch = pitch * 2; 00268 00269 for(y = 0; y < height; y++) { 00270 Source = src + y * pitch; 00271 Dest = dst + y * outpitch; 00272 for (x = 0; x < width; x++ ) { 00273 unsigned char color = (*Source++); 00274 /* A */ Dest[1] = (color & 0xf0) << 0; 00275 /* L */ Dest[0] = (color & 0x0f) << 4; 00276 Dest += 2; 00277 } 00278 } 00279 } 00280 00281 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) 00282 { 00283 unsigned int x, y; 00284 const WORD *Source; 00285 00286 for(y = 0; y < height; y++) 00287 { 00288 unsigned short *Dest_s = (unsigned short *) (dst + y * pitch); 00289 Source = (const WORD *)(src + y * pitch); 00290 for (x = 0; x < width; x++ ) 00291 { 00292 short color = (*Source++); 00293 unsigned char l = ((color >> 10) & 0xfc); 00294 short v = ((color >> 5) & 0x3e); 00295 short u = ((color ) & 0x1f); 00296 short v_conv = v + 16; 00297 short u_conv = u + 16; 00298 00299 *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f); 00300 Dest_s += 1; 00301 } 00302 } 00303 } 00304 00305 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) 00306 { 00307 unsigned int x, y; 00308 const WORD *Source; 00309 unsigned char *Dest; 00310 UINT outpitch = (pitch * 3)/2; 00311 00312 /* This makes the gl surface bigger(24 bit instead of 16), but it works with 00313 * fixed function and shaders without further conversion once the surface is 00314 * loaded 00315 */ 00316 for(y = 0; y < height; y++) { 00317 Source = (const WORD *)(src + y * pitch); 00318 Dest = dst + y * outpitch; 00319 for (x = 0; x < width; x++ ) { 00320 short color = (*Source++); 00321 unsigned char l = ((color >> 10) & 0xfc); 00322 char v = ((color >> 5) & 0x3e); 00323 char u = ((color ) & 0x1f); 00324 00325 /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign 00326 * and doubles the positive range. Thus shift left only once, gl does the 2nd 00327 * shift. GL reads a signed value and converts it into an unsigned value. 00328 */ 00329 /* M */ Dest[2] = l << 1; 00330 00331 /* Those are read as signed, but kept signed. Just left-shift 3 times to scale 00332 * from 5 bit values to 8 bit values. 00333 */ 00334 /* V */ Dest[1] = v << 3; 00335 /* U */ Dest[0] = u << 3; 00336 Dest += 3; 00337 } 00338 } 00339 } 00340 00341 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) 00342 { 00343 unsigned int x, y; 00344 const short *Source; 00345 unsigned char *Dest; 00346 UINT outpitch = (pitch * 3)/2; 00347 00348 for(y = 0; y < height; y++) 00349 { 00350 Source = (const short *)(src + y * pitch); 00351 Dest = dst + y * outpitch; 00352 for (x = 0; x < width; x++ ) 00353 { 00354 const short color = (*Source++); 00355 /* B */ Dest[0] = 0xff; 00356 /* G */ Dest[1] = (color >> 8) + 128; /* V */ 00357 /* R */ Dest[2] = (color & 0xff) + 128; /* U */ 00358 Dest += 3; 00359 } 00360 } 00361 } 00362 00363 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) 00364 { 00365 unsigned int x, y; 00366 const DWORD *Source; 00367 unsigned char *Dest; 00368 00369 /* Doesn't work correctly with the fixed function pipeline, but can work in 00370 * shaders if the shader is adjusted. (There's no use for this format in gl's 00371 * standard fixed function pipeline anyway). 00372 */ 00373 for(y = 0; y < height; y++) 00374 { 00375 Source = (const DWORD *)(src + y * pitch); 00376 Dest = dst + y * pitch; 00377 for (x = 0; x < width; x++ ) 00378 { 00379 LONG color = (*Source++); 00380 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */ 00381 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ 00382 /* R */ Dest[2] = (color & 0xff) + 128; /* U */ 00383 Dest += 4; 00384 } 00385 } 00386 } 00387 00388 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) 00389 { 00390 unsigned int x, y; 00391 const DWORD *Source; 00392 unsigned char *Dest; 00393 00394 /* This implementation works with the fixed function pipeline and shaders 00395 * without further modification after converting the surface. 00396 */ 00397 for(y = 0; y < height; y++) 00398 { 00399 Source = (const DWORD *)(src + y * pitch); 00400 Dest = dst + y * pitch; 00401 for (x = 0; x < width; x++ ) 00402 { 00403 LONG color = (*Source++); 00404 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */ 00405 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */ 00406 /* U */ Dest[0] = (color & 0xff); /* U */ 00407 /* I */ Dest[3] = 255; /* X */ 00408 Dest += 4; 00409 } 00410 } 00411 } 00412 00413 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) 00414 { 00415 unsigned int x, y; 00416 const DWORD *Source; 00417 unsigned char *Dest; 00418 00419 for(y = 0; y < height; y++) 00420 { 00421 Source = (const DWORD *)(src + y * pitch); 00422 Dest = dst + y * pitch; 00423 for (x = 0; x < width; x++ ) 00424 { 00425 LONG color = (*Source++); 00426 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */ 00427 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ 00428 /* R */ Dest[2] = (color & 0xff) + 128; /* U */ 00429 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */ 00430 Dest += 4; 00431 } 00432 } 00433 } 00434 00435 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) 00436 { 00437 unsigned int x, y; 00438 const DWORD *Source; 00439 unsigned short *Dest; 00440 UINT outpitch = (pitch * 3)/2; 00441 00442 for(y = 0; y < height; y++) 00443 { 00444 Source = (const DWORD *)(src + y * pitch); 00445 Dest = (unsigned short *) (dst + y * outpitch); 00446 for (x = 0; x < width; x++ ) 00447 { 00448 const DWORD color = (*Source++); 00449 /* B */ Dest[0] = 0xffff; 00450 /* G */ Dest[1] = (color >> 16) + 32768; /* V */ 00451 /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */ 00452 Dest += 3; 00453 } 00454 } 00455 } 00456 00457 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) 00458 { 00459 unsigned int x, y; 00460 const WORD *Source; 00461 WORD *Dest; 00462 UINT outpitch = (pitch * 3)/2; 00463 00464 for(y = 0; y < height; y++) 00465 { 00466 Source = (const WORD *)(src + y * pitch); 00467 Dest = (WORD *) (dst + y * outpitch); 00468 for (x = 0; x < width; x++ ) 00469 { 00470 WORD green = (*Source++); 00471 WORD red = (*Source++); 00472 Dest[0] = green; 00473 Dest[1] = red; 00474 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the 00475 * shader overwrites it anyway 00476 */ 00477 Dest[2] = 0xffff; 00478 Dest += 3; 00479 } 00480 } 00481 } 00482 00483 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) 00484 { 00485 unsigned int x, y; 00486 const float *Source; 00487 float *Dest; 00488 UINT outpitch = (pitch * 3)/2; 00489 00490 for(y = 0; y < height; y++) 00491 { 00492 Source = (const float *)(src + y * pitch); 00493 Dest = (float *) (dst + y * outpitch); 00494 for (x = 0; x < width; x++ ) 00495 { 00496 float green = (*Source++); 00497 float red = (*Source++); 00498 Dest[0] = green; 00499 Dest[1] = red; 00500 Dest[2] = 1.0f; 00501 Dest += 3; 00502 } 00503 } 00504 } 00505 00506 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) 00507 { 00508 unsigned int x, y; 00509 UINT outpitch = pitch * 2; 00510 00511 for (y = 0; y < height; ++y) 00512 { 00513 const WORD *source = (const WORD *)(src + y * pitch); 00514 DWORD *dest = (DWORD *)(dst + y * outpitch); 00515 00516 for (x = 0; x < width; ++x) 00517 { 00518 /* The depth data is normalized, so needs to be scaled, 00519 * the stencil data isn't. Scale depth data by 00520 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */ 00521 WORD d15 = source[x] >> 1; 00522 DWORD d24 = (d15 << 9) + (d15 >> 6); 00523 dest[x] = (d24 << 8) | (source[x] & 0x1); 00524 } 00525 } 00526 } 00527 00528 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) 00529 { 00530 unsigned int x, y; 00531 00532 for (y = 0; y < height; ++y) 00533 { 00534 const DWORD *source = (const DWORD *)(src + y * pitch); 00535 DWORD *dest = (DWORD *)(dst + y * pitch); 00536 00537 for (x = 0; x < width; ++x) 00538 { 00539 /* Just need to clear out the X4 part. */ 00540 dest[x] = source[x] & ~0xf0; 00541 } 00542 } 00543 } 00544 00545 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) 00546 { 00547 unsigned int x, y; 00548 UINT outpitch = pitch * 2; 00549 00550 for (y = 0; y < height; ++y) 00551 { 00552 const DWORD *source = (const DWORD *)(src + y * pitch); 00553 float *dest_f = (float *)(dst + y * outpitch); 00554 DWORD *dest_s = (DWORD *)(dst + y * outpitch); 00555 00556 for (x = 0; x < width; ++x) 00557 { 00558 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8); 00559 dest_s[x * 2 + 1] = source[x] & 0xff; 00560 } 00561 } 00562 } 00563 00564 static const struct wined3d_format_texture_info format_texture_info[] = 00565 { 00566 /* format id internal srgbInternal rtInternal 00567 format type 00568 flags 00569 extension */ 00570 /* FourCC formats */ 00571 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type 00572 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The 00573 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based 00574 * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big 00575 * endian machine 00576 */ 00577 {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0, 00578 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, 00579 WINED3DFMT_FLAG_FILTERING, 00580 WINED3D_GL_EXT_NONE, NULL}, 00581 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0, 00582 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0, 00583 WINED3DFMT_FLAG_FILTERING, 00584 APPLE_YCBCR_422, NULL}, 00585 {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0, 00586 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, 00587 WINED3DFMT_FLAG_FILTERING, 00588 WINED3D_GL_EXT_NONE, NULL}, 00589 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0, 00590 GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0, 00591 WINED3DFMT_FLAG_FILTERING, 00592 APPLE_YCBCR_422, NULL}, 00593 {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0, 00594 GL_ALPHA, GL_UNSIGNED_BYTE, 0, 00595 WINED3DFMT_FLAG_FILTERING, 00596 WINED3D_GL_EXT_NONE, NULL}, 00597 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0, 00598 GL_RGBA, GL_UNSIGNED_BYTE, 0, 00599 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ 00600 | WINED3DFMT_FLAG_COMPRESSED, 00601 EXT_TEXTURE_COMPRESSION_S3TC, NULL}, 00602 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0, 00603 GL_RGBA, GL_UNSIGNED_BYTE, 0, 00604 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ 00605 | WINED3DFMT_FLAG_COMPRESSED, 00606 EXT_TEXTURE_COMPRESSION_S3TC, NULL}, 00607 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0, 00608 GL_RGBA, GL_UNSIGNED_BYTE, 0, 00609 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ 00610 | WINED3DFMT_FLAG_COMPRESSED, 00611 EXT_TEXTURE_COMPRESSION_S3TC, NULL}, 00612 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0, 00613 GL_RGBA, GL_UNSIGNED_BYTE, 0, 00614 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ 00615 | WINED3DFMT_FLAG_COMPRESSED, 00616 EXT_TEXTURE_COMPRESSION_S3TC, NULL}, 00617 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0, 00618 GL_RGBA, GL_UNSIGNED_BYTE, 0, 00619 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ 00620 | WINED3DFMT_FLAG_COMPRESSED, 00621 EXT_TEXTURE_COMPRESSION_S3TC, NULL}, 00622 /* IEEE formats */ 00623 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0, 00624 GL_RED, GL_FLOAT, 0, 00625 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 00626 ARB_TEXTURE_FLOAT, NULL}, 00627 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0, 00628 GL_RED, GL_FLOAT, 0, 00629 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 00630 ARB_TEXTURE_RG, NULL}, 00631 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0, 00632 GL_RGB, GL_FLOAT, 12, 00633 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 00634 ARB_TEXTURE_FLOAT, convert_r32g32_float}, 00635 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0, 00636 GL_RG, GL_FLOAT, 0, 00637 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 00638 ARB_TEXTURE_RG, NULL}, 00639 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0, 00640 GL_RGBA, GL_FLOAT, 0, 00641 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 00642 ARB_TEXTURE_FLOAT, NULL}, 00643 /* Float */ 00644 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0, 00645 GL_RED, GL_HALF_FLOAT_ARB, 0, 00646 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 00647 ARB_TEXTURE_FLOAT, NULL}, 00648 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0, 00649 GL_RED, GL_HALF_FLOAT_ARB, 0, 00650 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 00651 ARB_TEXTURE_RG, NULL}, 00652 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0, 00653 GL_RGB, GL_HALF_FLOAT_ARB, 6, 00654 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 00655 ARB_TEXTURE_FLOAT, convert_r16g16}, 00656 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0, 00657 GL_RG, GL_HALF_FLOAT_ARB, 0, 00658 WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 00659 ARB_TEXTURE_RG, NULL}, 00660 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0, 00661 GL_RGBA, GL_HALF_FLOAT_ARB, 0, 00662 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 00663 ARB_TEXTURE_FLOAT, NULL}, 00664 /* Palettized formats */ 00665 {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0, 00666 GL_ALPHA, GL_UNSIGNED_BYTE, 0, 00667 0, 00668 ARB_FRAGMENT_PROGRAM, NULL}, 00669 {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0, 00670 GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0, 00671 0, 00672 EXT_PALETTED_TEXTURE, NULL}, 00673 /* Standard ARGB formats */ 00674 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0, 00675 GL_BGR, GL_UNSIGNED_BYTE, 0, 00676 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, 00677 WINED3D_GL_EXT_NONE, NULL}, 00678 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0, 00679 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, 00680 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET 00681 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE | WINED3DFMT_FLAG_VTF, 00682 WINED3D_GL_EXT_NONE, NULL}, 00683 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0, 00684 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, 00685 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET 00686 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE, 00687 WINED3D_GL_EXT_NONE, NULL}, 00688 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8, 00689 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0, 00690 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, 00691 WINED3D_GL_EXT_NONE, NULL}, 00692 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0, 00693 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0, 00694 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 00695 WINED3D_GL_EXT_NONE, NULL}, 00696 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0, 00697 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0, 00698 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 00699 WINED3D_GL_EXT_NONE, NULL}, 00700 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0, 00701 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0, 00702 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, 00703 WINED3D_GL_EXT_NONE, NULL}, 00704 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0, 00705 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0, 00706 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 00707 WINED3D_GL_EXT_NONE, NULL}, 00708 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0, 00709 GL_ALPHA, GL_UNSIGNED_BYTE, 0, 00710 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 00711 WINED3D_GL_EXT_NONE, NULL}, 00712 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0, 00713 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0, 00714 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 00715 WINED3D_GL_EXT_NONE, NULL}, 00716 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0, 00717 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0, 00718 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, 00719 WINED3D_GL_EXT_NONE, NULL}, 00720 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0, 00721 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, 00722 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 00723 WINED3D_GL_EXT_NONE, NULL}, 00724 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0, 00725 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, 00726 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 00727 WINED3D_GL_EXT_NONE, NULL}, 00728 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16, 00729 GL_RGB, GL_UNSIGNED_SHORT, 6, 00730 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 00731 WINED3D_GL_EXT_NONE, convert_r16g16}, 00732 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0, 00733 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0, 00734 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, 00735 WINED3D_GL_EXT_NONE, NULL}, 00736 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0, 00737 GL_RGBA, GL_UNSIGNED_SHORT, 0, 00738 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, 00739 WINED3D_GL_EXT_NONE, NULL}, 00740 /* Luminance */ 00741 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0, 00742 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0, 00743 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, 00744 WINED3D_GL_EXT_NONE, NULL}, 00745 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0, 00746 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, 00747 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, 00748 WINED3D_GL_EXT_NONE, NULL}, 00749 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0, 00750 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2, 00751 WINED3DFMT_FLAG_FILTERING, 00752 WINED3D_GL_EXT_NONE, convert_l4a4_unorm}, 00753 /* Bump mapping stuff */ 00754 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0, 00755 GL_BGR, GL_UNSIGNED_BYTE, 3, 00756 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, 00757 WINED3D_GL_EXT_NONE, convert_r8g8_snorm}, 00758 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0, 00759 GL_DSDT_NV, GL_BYTE, 0, 00760 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, 00761 NV_TEXTURE_SHADER, NULL}, 00762 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0, 00763 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2, 00764 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, 00765 WINED3D_GL_EXT_NONE, convert_r5g5_snorm_l6_unorm}, 00766 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0, 00767 GL_DSDT_MAG_NV, GL_BYTE, 3, 00768 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, 00769 NV_TEXTURE_SHADER, convert_r5g5_snorm_l6_unorm_nv}, 00770 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0, 00771 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 00772 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, 00773 WINED3D_GL_EXT_NONE, convert_r8g8_snorm_l8x8_unorm}, 00774 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0, 00775 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4, 00776 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, 00777 NV_TEXTURE_SHADER, convert_r8g8_snorm_l8x8_unorm_nv}, 00778 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0, 00779 GL_BGRA, GL_UNSIGNED_BYTE, 4, 00780 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, 00781 WINED3D_GL_EXT_NONE, convert_r8g8b8a8_snorm}, 00782 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0, 00783 GL_RGBA, GL_BYTE, 0, 00784 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, 00785 NV_TEXTURE_SHADER, NULL}, 00786 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0, 00787 GL_BGR, GL_UNSIGNED_SHORT, 6, 00788 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, 00789 WINED3D_GL_EXT_NONE, convert_r16g16_snorm}, 00790 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0, 00791 GL_HILO_NV, GL_SHORT, 0, 00792 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, 00793 NV_TEXTURE_SHADER, NULL}, 00794 /* Depth stencil formats */ 00795 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, 00796 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, 00797 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, 00798 ARB_DEPTH_TEXTURE, NULL}, 00799 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0, 00800 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 00801 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, 00802 ARB_DEPTH_TEXTURE, NULL}, 00803 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, 00804 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, 00805 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, 00806 ARB_DEPTH_TEXTURE, NULL}, 00807 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0, 00808 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4, 00809 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, 00810 EXT_PACKED_DEPTH_STENCIL, convert_s1_uint_d15_unorm}, 00811 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, 00812 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4, 00813 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, 00814 ARB_FRAMEBUFFER_OBJECT, convert_s1_uint_d15_unorm}, 00815 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, 00816 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 00817 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH 00818 | WINED3DFMT_FLAG_SHADOW, 00819 ARB_DEPTH_TEXTURE, NULL}, 00820 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0, 00821 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0, 00822 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH 00823 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, 00824 EXT_PACKED_DEPTH_STENCIL, NULL}, 00825 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, 00826 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0, 00827 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH 00828 | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, 00829 ARB_FRAMEBUFFER_OBJECT, NULL}, 00830 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, 00831 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 00832 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH 00833 | WINED3DFMT_FLAG_SHADOW, 00834 ARB_DEPTH_TEXTURE, NULL}, 00835 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, 00836 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 00837 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, 00838 ARB_DEPTH_TEXTURE, NULL}, 00839 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0, 00840 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4, 00841 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, 00842 EXT_PACKED_DEPTH_STENCIL, convert_s4x4_uint_d24_unorm}, 00843 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, 00844 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4, 00845 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, 00846 ARB_FRAMEBUFFER_OBJECT, convert_s4x4_uint_d24_unorm}, 00847 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, 00848 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, 00849 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH 00850 | WINED3DFMT_FLAG_SHADOW, 00851 ARB_DEPTH_TEXTURE, NULL}, 00852 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0, 00853 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0, 00854 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 00855 WINED3D_GL_EXT_NONE, NULL}, 00856 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0, 00857 GL_DEPTH_COMPONENT, GL_FLOAT, 0, 00858 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, 00859 ARB_DEPTH_BUFFER_FLOAT, NULL}, 00860 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0, 00861 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, 00862 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, 00863 ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float}, 00864 /* Vendor-specific formats */ 00865 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0, 00866 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, 00867 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_COMPRESSED, 00868 ATI_TEXTURE_COMPRESSION_3DC, NULL}, 00869 {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2, GL_COMPRESSED_RED_GREEN_RGTC2, 0, 00870 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, 00871 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_COMPRESSED, 00872 ARB_TEXTURE_COMPRESSION_RGTC, NULL}, 00873 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0, 00874 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0, 00875 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH 00876 | WINED3DFMT_FLAG_STENCIL, 00877 EXT_PACKED_DEPTH_STENCIL, NULL}, 00878 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, 00879 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0, 00880 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH 00881 | WINED3DFMT_FLAG_STENCIL, 00882 ARB_FRAMEBUFFER_OBJECT, NULL}, 00883 {WINED3DFMT_NULL, GL_RGBA8, GL_RGBA8, 0, 00884 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, 00885 WINED3DFMT_FLAG_RENDERTARGET, 00886 ARB_FRAMEBUFFER_OBJECT, NULL}, 00887 }; 00888 00889 static inline int getFmtIdx(enum wined3d_format_id format_id) 00890 { 00891 /* First check if the format is at the position of its value. 00892 * This will catch the argb formats before the loop is entered. */ 00893 if (format_id < (sizeof(formats) / sizeof(*formats)) 00894 && formats[format_id].id == format_id) 00895 { 00896 return format_id; 00897 } 00898 else 00899 { 00900 unsigned int i; 00901 00902 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i) 00903 { 00904 if (formats[i].id == format_id) return i; 00905 } 00906 } 00907 return -1; 00908 } 00909 00910 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info) 00911 { 00912 UINT format_count = sizeof(formats) / sizeof(*formats); 00913 UINT i; 00914 00915 gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats)); 00916 if (!gl_info->formats) 00917 { 00918 ERR("Failed to allocate memory.\n"); 00919 return FALSE; 00920 } 00921 00922 for (i = 0; i < format_count; ++i) 00923 { 00924 struct wined3d_format *format = &gl_info->formats[i]; 00925 format->id = formats[i].id; 00926 format->red_mask = formats[i].redMask; 00927 format->green_mask = formats[i].greenMask; 00928 format->blue_mask = formats[i].blueMask; 00929 format->alpha_mask = formats[i].alphaMask; 00930 format->byte_count = formats[i].bpp; 00931 format->depth_size = formats[i].depthSize; 00932 format->stencil_size = formats[i].stencilSize; 00933 format->block_width = 1; 00934 format->block_height = 1; 00935 format->block_byte_count = formats[i].bpp; 00936 } 00937 00938 for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i) 00939 { 00940 int fmt_idx = getFmtIdx(format_base_flags[i].id); 00941 00942 if (fmt_idx == -1) 00943 { 00944 ERR("Format %s (%#x) not found.\n", 00945 debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id); 00946 HeapFree(GetProcessHeap(), 0, gl_info->formats); 00947 return FALSE; 00948 } 00949 00950 gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags; 00951 } 00952 00953 return TRUE; 00954 } 00955 00956 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info) 00957 { 00958 unsigned int i; 00959 00960 for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i) 00961 { 00962 struct wined3d_format *format; 00963 int fmt_idx = getFmtIdx(format_block_info[i].id); 00964 00965 if (fmt_idx == -1) 00966 { 00967 ERR("Format %s (%#x) not found.\n", 00968 debug_d3dformat(format_block_info[i].id), format_block_info[i].id); 00969 return FALSE; 00970 } 00971 00972 format = &gl_info->formats[fmt_idx]; 00973 format->block_width = format_block_info[i].block_width; 00974 format->block_height = format_block_info[i].block_height; 00975 format->block_byte_count = format_block_info[i].block_byte_count; 00976 format->flags |= WINED3DFMT_FLAG_BLOCKS; 00977 } 00978 00979 return TRUE; 00980 } 00981 00982 /* Context activation is done by the caller. */ 00983 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format) 00984 { 00985 /* Check if the default internal format is supported as a frame buffer 00986 * target, otherwise fall back to the render target internal. 00987 * 00988 * Try to stick to the standard format if possible, this limits precision differences. */ 00989 GLenum status; 00990 GLuint tex; 00991 00992 ENTER_GL(); 00993 00994 while(glGetError()); 00995 glDisable(GL_BLEND); 00996 00997 glGenTextures(1, &tex); 00998 glBindTexture(GL_TEXTURE_2D, tex); 00999 01000 glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0, format->glFormat, format->glType, NULL); 01001 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 01002 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 01003 01004 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); 01005 01006 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); 01007 checkGLcall("Framebuffer format check"); 01008 01009 if (status == GL_FRAMEBUFFER_COMPLETE) 01010 { 01011 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id)); 01012 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE; 01013 format->rtInternal = format->glInternal; 01014 } 01015 else 01016 { 01017 if (!format->rtInternal) 01018 { 01019 if (format->flags & WINED3DFMT_FLAG_RENDERTARGET) 01020 { 01021 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment," 01022 " and no fallback specified.\n", debug_d3dformat(format->id)); 01023 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET; 01024 } 01025 else 01026 { 01027 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id)); 01028 } 01029 format->rtInternal = format->glInternal; 01030 } 01031 else 01032 { 01033 TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n", 01034 debug_d3dformat(format->id)); 01035 01036 while(glGetError()); 01037 01038 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); 01039 01040 glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0, format->glFormat, format->glType, NULL); 01041 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 01042 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 01043 01044 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); 01045 01046 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); 01047 checkGLcall("Framebuffer format check"); 01048 01049 if (status == GL_FRAMEBUFFER_COMPLETE) 01050 { 01051 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n", 01052 debug_d3dformat(format->id)); 01053 } 01054 else 01055 { 01056 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n", 01057 debug_d3dformat(format->id)); 01058 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET; 01059 } 01060 } 01061 } 01062 01063 if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) 01064 || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING)) 01065 && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT 01066 && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA) 01067 { 01068 GLuint rb, tex2; 01069 DWORD readback[16 * 16], color; 01070 BYTE r, a; 01071 BOOL match = TRUE; 01072 01073 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] 01074 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL]) 01075 { 01076 gl_info->fbo_ops.glGenRenderbuffers(1, &rb); 01077 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb); 01078 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16); 01079 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb); 01080 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb); 01081 checkGLcall("RB attachment"); 01082 } 01083 01084 glEnable(GL_BLEND); 01085 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 01086 glClear(GL_COLOR_BUFFER_BIT); 01087 if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION) 01088 { 01089 while(glGetError()); 01090 TRACE("Format doesn't support post-pixelshader blending.\n"); 01091 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; 01092 } 01093 else 01094 { 01095 glViewport(0, 0, 16, 16); 01096 glDisable(GL_LIGHTING); 01097 glMatrixMode(GL_MODELVIEW); 01098 glLoadIdentity(); 01099 glMatrixMode(GL_PROJECTION); 01100 glLoadIdentity(); 01101 01102 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 01103 01104 /* Draw a full-black quad */ 01105 glBegin(GL_TRIANGLE_STRIP); 01106 glColor4ub(0x00, 0x00, 0x00, 0xff); 01107 glVertex3f(-1.0f, -1.0f, 0.0f); 01108 glColor4ub(0x00, 0x00, 0x00, 0xff); 01109 glVertex3f(1.0f, -1.0f, 0.0f); 01110 glColor4ub(0x00, 0x00, 0x00, 0xff); 01111 glVertex3f(-1.0f, 1.0f, 0.0f); 01112 glColor4ub(0x00, 0x00, 0x00, 0xff); 01113 glVertex3f(1.0f, 1.0f, 0.0f); 01114 glEnd(); 01115 01116 /* Draw a half-transparent red quad */ 01117 glBegin(GL_TRIANGLE_STRIP); 01118 glColor4ub(0xff, 0x00, 0x00, 0x80); 01119 glVertex3f(-1.0f, -1.0f, 0.0f); 01120 glColor4ub(0xff, 0x00, 0x00, 0x80); 01121 glVertex3f(1.0f, -1.0f, 0.0f); 01122 glColor4ub(0xff, 0x00, 0x00, 0x80); 01123 glVertex3f(-1.0f, 1.0f, 0.0f); 01124 glColor4ub(0xff, 0x00, 0x00, 0x80); 01125 glVertex3f(1.0f, 1.0f, 0.0f); 01126 glEnd(); 01127 01128 glGenTextures(1, &tex2); 01129 glBindTexture(GL_TEXTURE_2D, tex2); 01130 01131 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, 16, 16, 0); 01132 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback); 01133 checkGLcall("Post-pixelshader blending check"); 01134 01135 color = readback[7 * 16 + 7]; 01136 a = color >> 24; 01137 r = (color & 0x00ff0000) >> 16; 01138 01139 if (format->red_mask && (r < 0x7b || r > 0x84)) 01140 match = FALSE; 01141 /* If the alpha component is more than 1 bit */ 01142 else if ((format->alpha_mask & (format->alpha_mask - 1)) && (a < 0x9f || a > 0xdf)) 01143 match = FALSE; 01144 if (!match) 01145 { 01146 TRACE("Format doesn't support post-pixelshader blending.\n"); 01147 TRACE("Color output: %#x\n", color); 01148 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; 01149 } 01150 else 01151 { 01152 TRACE("Format supports post-pixelshader blending.\n"); 01153 format->flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; 01154 } 01155 01156 glBindTexture(GL_TEXTURE_2D, tex); 01157 glDeleteTextures(1, &tex2); 01158 } 01159 01160 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] 01161 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL]) 01162 { 01163 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); 01164 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); 01165 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb); 01166 checkGLcall("RB cleanup"); 01167 } 01168 } 01169 01170 if (format->glInternal != format->glGammaInternal) 01171 { 01172 glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0, format->glFormat, format->glType, NULL); 01173 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); 01174 01175 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); 01176 checkGLcall("Framebuffer format check"); 01177 01178 if (status == GL_FRAMEBUFFER_COMPLETE) 01179 { 01180 TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id)); 01181 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; 01182 } 01183 else 01184 { 01185 WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id)); 01186 } 01187 } 01188 else if (status == GL_FRAMEBUFFER_COMPLETE) 01189 format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; 01190 01191 glDeleteTextures(1, &tex); 01192 01193 LEAVE_GL(); 01194 } 01195 01196 /* Context activation is done by the caller. */ 01197 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info) 01198 { 01199 unsigned int i; 01200 GLuint fbo; 01201 01202 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) 01203 { 01204 ENTER_GL(); 01205 01206 gl_info->fbo_ops.glGenFramebuffers(1, &fbo); 01207 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); 01208 glDrawBuffer(GL_COLOR_ATTACHMENT0); 01209 glReadBuffer(GL_COLOR_ATTACHMENT0); 01210 01211 LEAVE_GL(); 01212 } 01213 01214 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i) 01215 { 01216 struct wined3d_format *format = &gl_info->formats[i]; 01217 01218 if (!format->glInternal) continue; 01219 01220 if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) 01221 { 01222 TRACE("Skipping format %s because it's a depth/stencil format.\n", 01223 debug_d3dformat(format->id)); 01224 continue; 01225 } 01226 01227 if (format->flags & WINED3DFMT_FLAG_COMPRESSED) 01228 { 01229 TRACE("Skipping format %s because it's a compressed format.\n", 01230 debug_d3dformat(format->id)); 01231 continue; 01232 } 01233 01234 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) 01235 { 01236 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id)); 01237 check_fbo_compat(gl_info, format); 01238 } 01239 else 01240 { 01241 format->rtInternal = format->glInternal; 01242 } 01243 } 01244 01245 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) 01246 { 01247 ENTER_GL(); 01248 01249 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); 01250 01251 LEAVE_GL(); 01252 } 01253 } 01254 01255 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info) 01256 { 01257 unsigned int i; 01258 01259 for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i) 01260 { 01261 int fmt_idx = getFmtIdx(format_texture_info[i].id); 01262 struct wined3d_format *format; 01263 01264 if (fmt_idx == -1) 01265 { 01266 ERR("Format %s (%#x) not found.\n", 01267 debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id); 01268 return FALSE; 01269 } 01270 01271 if (!gl_info->supported[format_texture_info[i].extension]) continue; 01272 01273 format = &gl_info->formats[fmt_idx]; 01274 01275 /* ARB_texture_rg defines floating point formats, but only if 01276 * ARB_texture_float is also supported. */ 01277 if (!gl_info->supported[ARB_TEXTURE_FLOAT] 01278 && (format->flags & WINED3DFMT_FLAG_FLOAT)) 01279 continue; 01280 01281 format->glInternal = format_texture_info[i].gl_internal; 01282 format->glGammaInternal = format_texture_info[i].gl_srgb_internal; 01283 format->rtInternal = format_texture_info[i].gl_rt_internal; 01284 format->glFormat = format_texture_info[i].gl_format; 01285 format->glType = format_texture_info[i].gl_type; 01286 format->color_fixup = COLOR_FIXUP_IDENTITY; 01287 format->flags |= format_texture_info[i].flags; 01288 format->heightscale = 1.0f; 01289 01290 if (format->glGammaInternal != format->glInternal) 01291 { 01292 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */ 01293 if (!gl_info->supported[EXT_TEXTURE_SRGB]) 01294 { 01295 format->glGammaInternal = format->glInternal; 01296 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE); 01297 } 01298 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) 01299 { 01300 format->glInternal = format->glGammaInternal; 01301 } 01302 } 01303 01304 /* Texture conversion stuff */ 01305 format->convert = format_texture_info[i].convert; 01306 format->conv_byte_count = format_texture_info[i].conv_byte_count; 01307 } 01308 01309 return TRUE; 01310 } 01311 01312 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff) 01313 { 01314 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE; 01315 c1 >>= 8; c2 >>= 8; 01316 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE; 01317 c1 >>= 8; c2 >>= 8; 01318 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE; 01319 c1 >>= 8; c2 >>= 8; 01320 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE; 01321 return TRUE; 01322 } 01323 01324 /* A context is provided by the caller */ 01325 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal) 01326 { 01327 static const DWORD data[] = {0x00000000, 0xffffffff}; 01328 GLuint tex, fbo, buffer; 01329 DWORD readback[16 * 1]; 01330 BOOL ret = FALSE; 01331 01332 /* Render a filtered texture and see what happens. This is intended to detect the lack of 01333 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of 01334 * falling back to software. If this changes in the future this code will get fooled and 01335 * apps might hit the software path due to incorrectly advertised caps. 01336 * 01337 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter 01338 * disable fallback, if Apple or ATI ever change the driver behavior they will break more 01339 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway 01340 */ 01341 01342 ENTER_GL(); 01343 while(glGetError()); 01344 01345 glGenTextures(1, &buffer); 01346 glBindTexture(GL_TEXTURE_2D, buffer); 01347 memset(readback, 0x7e, sizeof(readback)); 01348 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback); 01349 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 01350 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 01351 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 01352 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 01353 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 01354 01355 glGenTextures(1, &tex); 01356 glBindTexture(GL_TEXTURE_2D, tex); 01357 glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); 01358 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 01359 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 01360 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 01361 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 01362 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 01363 glEnable(GL_TEXTURE_2D); 01364 01365 gl_info->fbo_ops.glGenFramebuffers(1, &fbo); 01366 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); 01367 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0); 01368 glDrawBuffer(GL_COLOR_ATTACHMENT0); 01369 01370 glViewport(0, 0, 16, 1); 01371 glDisable(GL_LIGHTING); 01372 glMatrixMode(GL_MODELVIEW); 01373 glLoadIdentity(); 01374 glMatrixMode(GL_PROJECTION); 01375 glLoadIdentity(); 01376 01377 glClearColor(0, 1, 0, 0); 01378 glClear(GL_COLOR_BUFFER_BIT); 01379 01380 glBegin(GL_TRIANGLE_STRIP); 01381 glTexCoord2f(0.0, 0.0); 01382 glVertex2f(-1.0f, -1.0f); 01383 glTexCoord2f(1.0, 0.0); 01384 glVertex2f(1.0f, -1.0f); 01385 glTexCoord2f(0.0, 1.0); 01386 glVertex2f(-1.0f, 1.0f); 01387 glTexCoord2f(1.0, 1.0); 01388 glVertex2f(1.0f, 1.0f); 01389 glEnd(); 01390 01391 glBindTexture(GL_TEXTURE_2D, buffer); 01392 memset(readback, 0x7f, sizeof(readback)); 01393 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback); 01394 if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) || 01395 color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5)) 01396 { 01397 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n", 01398 readback[6], readback[9]); 01399 ret = FALSE; 01400 } 01401 else 01402 { 01403 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n", 01404 readback[6], readback[9]); 01405 ret = TRUE; 01406 } 01407 01408 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0); 01409 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); 01410 glDeleteTextures(1, &tex); 01411 glDeleteTextures(1, &buffer); 01412 01413 if(glGetError()) 01414 { 01415 FIXME("Error during filtering test for format %x, returning no filtering\n", internal); 01416 ret = FALSE; 01417 } 01418 LEAVE_GL(); 01419 return ret; 01420 } 01421 01422 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor) 01423 { 01424 struct wined3d_format *format; 01425 unsigned int fmt_idx, i; 01426 static const enum wined3d_format_id fmts16[] = 01427 { 01428 WINED3DFMT_R16_FLOAT, 01429 WINED3DFMT_R16G16_FLOAT, 01430 WINED3DFMT_R16G16B16A16_FLOAT, 01431 }; 01432 BOOL filtered; 01433 01434 if(wined3d_settings.offscreen_rendering_mode != ORM_FBO) 01435 { 01436 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n"); 01437 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT]) 01438 { 01439 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n"); 01440 filtered = TRUE; 01441 } 01442 else if (gl_info->limits.glsl_varyings > 44) 01443 { 01444 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n"); 01445 filtered = TRUE; 01446 } 01447 else 01448 { 01449 TRACE("Assuming no float16 blending\n"); 01450 filtered = FALSE; 01451 } 01452 01453 if(filtered) 01454 { 01455 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++) 01456 { 01457 fmt_idx = getFmtIdx(fmts16[i]); 01458 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING; 01459 } 01460 } 01461 return; 01462 } 01463 01464 for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++) 01465 { 01466 fmt_idx = getFmtIdx(fmts16[i]); 01467 format = &gl_info->formats[fmt_idx]; 01468 if (!format->glInternal) continue; /* Not supported by GL */ 01469 01470 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal); 01471 if(filtered) 01472 { 01473 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i])); 01474 format->flags |= WINED3DFMT_FLAG_FILTERING; 01475 } 01476 else 01477 { 01478 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i])); 01479 } 01480 } 01481 } 01482 01483 static void apply_format_fixups(struct wined3d_gl_info *gl_info) 01484 { 01485 int idx; 01486 01487 idx = getFmtIdx(WINED3DFMT_R16_FLOAT); 01488 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 01489 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W); 01490 01491 idx = getFmtIdx(WINED3DFMT_R32_FLOAT); 01492 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 01493 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W); 01494 01495 idx = getFmtIdx(WINED3DFMT_R16G16_UNORM); 01496 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 01497 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W); 01498 01499 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT); 01500 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 01501 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W); 01502 01503 idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT); 01504 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 01505 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W); 01506 01507 /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader. 01508 * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if 01509 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because 01510 * the only driver that implements it(fglrx) has a buggy implementation. 01511 * 01512 * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL 01513 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader 01514 * conversion for this format. 01515 */ 01516 if (!gl_info->supported[NV_TEXTURE_SHADER]) 01517 { 01518 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM); 01519 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 01520 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); 01521 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM); 01522 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 01523 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); 01524 } 01525 else 01526 { 01527 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM); 01528 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 01529 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); 01530 01531 idx = getFmtIdx(WINED3DFMT_R16G16_SNORM); 01532 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 01533 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); 01534 } 01535 01536 if (!gl_info->supported[NV_TEXTURE_SHADER]) 01537 { 01538 /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly 01539 * with each other 01540 */ 01541 idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM); 01542 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 01543 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE); 01544 idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM); 01545 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 01546 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W); 01547 idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM); 01548 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 01549 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W); 01550 } 01551 else 01552 { 01553 /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8 01554 * are converted at surface loading time, but they do not need any modification in 01555 * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats. 01556 * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion 01557 */ 01558 } 01559 01560 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC]) 01561 { 01562 idx = getFmtIdx(WINED3DFMT_ATI2N); 01563 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 01564 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); 01565 } 01566 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC]) 01567 { 01568 idx = getFmtIdx(WINED3DFMT_ATI2N); 01569 gl_info->formats[idx].color_fixup= create_color_fixup_desc( 01570 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); 01571 } 01572 01573 if (!gl_info->supported[APPLE_YCBCR_422]) 01574 { 01575 idx = getFmtIdx(WINED3DFMT_YUY2); 01576 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2); 01577 01578 idx = getFmtIdx(WINED3DFMT_UYVY); 01579 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY); 01580 } 01581 01582 idx = getFmtIdx(WINED3DFMT_YV12); 01583 gl_info->formats[idx].heightscale = 1.5f; 01584 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12); 01585 01586 if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM]) 01587 { 01588 idx = getFmtIdx(WINED3DFMT_P8_UINT); 01589 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8); 01590 } 01591 01592 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) 01593 { 01594 idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM); 01595 gl_info->formats[idx].gl_vtx_format = GL_BGRA; 01596 } 01597 01598 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX]) 01599 { 01600 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though. 01601 * It is the job of the vertex buffer code to make sure that the vbos have the right format */ 01602 idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT); 01603 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */ 01604 01605 idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT); 01606 gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; 01607 } 01608 } 01609 01610 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info) 01611 { 01612 unsigned int i; 01613 01614 for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i) 01615 { 01616 struct wined3d_format *format; 01617 int fmt_idx = getFmtIdx(format_vertex_info[i].id); 01618 01619 if (fmt_idx == -1) 01620 { 01621 ERR("Format %s (%#x) not found.\n", 01622 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id); 01623 return FALSE; 01624 } 01625 01626 format = &gl_info->formats[fmt_idx]; 01627 format->emit_idx = format_vertex_info[i].emit_idx; 01628 format->component_count = format_vertex_info[i].component_count; 01629 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type; 01630 format->gl_vtx_format = format_vertex_info[i].gl_vtx_format; 01631 format->gl_normalized = format_vertex_info[i].gl_normalized; 01632 format->component_size = format_vertex_info[i].component_size; 01633 } 01634 01635 return TRUE; 01636 } 01637 01638 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info) 01639 { 01640 if (!init_format_base_info(gl_info)) return FALSE; 01641 01642 if (!init_format_block_info(gl_info)) 01643 { 01644 HeapFree(GetProcessHeap(), 0, gl_info->formats); 01645 gl_info->formats = NULL; 01646 return FALSE; 01647 } 01648 01649 return TRUE; 01650 } 01651 01652 /* Context activation is done by the caller. */ 01653 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor) 01654 { 01655 if (!init_format_base_info(gl_info)) return FALSE; 01656 01657 if (!init_format_block_info(gl_info)) goto fail; 01658 if (!init_format_texture_info(gl_info)) goto fail; 01659 if (!init_format_vertex_info(gl_info)) goto fail; 01660 01661 apply_format_fixups(gl_info); 01662 init_format_fbo_compat_info(gl_info); 01663 init_format_filter_info(gl_info, vendor); 01664 01665 return TRUE; 01666 01667 fail: 01668 HeapFree(GetProcessHeap(), 0, gl_info->formats); 01669 gl_info->formats = NULL; 01670 return FALSE; 01671 } 01672 01673 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info, 01674 enum wined3d_format_id format_id) 01675 { 01676 int idx = getFmtIdx(format_id); 01677 01678 if (idx == -1) 01679 { 01680 FIXME("Can't find format %s (%#x) in the format lookup table\n", 01681 debug_d3dformat(format_id), format_id); 01682 /* Get the caller a valid pointer */ 01683 idx = getFmtIdx(WINED3DFMT_UNKNOWN); 01684 } 01685 01686 return &gl_info->formats[idx]; 01687 } 01688 01689 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height) 01690 { 01691 UINT size; 01692 01693 if (format->id == WINED3DFMT_UNKNOWN) 01694 { 01695 size = 0; 01696 } 01697 else if (format->flags & WINED3DFMT_FLAG_BLOCKS) 01698 { 01699 UINT row_block_count = (width + format->block_width - 1) / format->block_width; 01700 UINT row_count = (height + format->block_height - 1) / format->block_height; 01701 size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1)); 01702 } 01703 else 01704 { 01705 size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1)); 01706 } 01707 01708 if (format->heightscale != 0.0f) 01709 { 01710 /* The D3D format requirements make sure that the resulting format is an integer again */ 01711 size = (UINT) (size * format->heightscale); 01712 } 01713 01714 return size; 01715 } 01716 01717 /***************************************************************************** 01718 * Trace formatting of useful values 01719 */ 01720 const char *debug_d3dformat(enum wined3d_format_id format_id) 01721 { 01722 switch (format_id) 01723 { 01724 #define FMT_TO_STR(format_id) case format_id: return #format_id 01725 FMT_TO_STR(WINED3DFMT_UNKNOWN); 01726 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM); 01727 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM); 01728 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM); 01729 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM); 01730 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM); 01731 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM); 01732 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM); 01733 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM); 01734 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM); 01735 FMT_TO_STR(WINED3DFMT_P8_UINT); 01736 FMT_TO_STR(WINED3DFMT_L8_UNORM); 01737 FMT_TO_STR(WINED3DFMT_L8A8_UNORM); 01738 FMT_TO_STR(WINED3DFMT_L4A4_UNORM); 01739 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM); 01740 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM); 01741 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM); 01742 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM); 01743 FMT_TO_STR(WINED3DFMT_UYVY); 01744 FMT_TO_STR(WINED3DFMT_YUY2); 01745 FMT_TO_STR(WINED3DFMT_YV12); 01746 FMT_TO_STR(WINED3DFMT_DXT1); 01747 FMT_TO_STR(WINED3DFMT_DXT2); 01748 FMT_TO_STR(WINED3DFMT_DXT3); 01749 FMT_TO_STR(WINED3DFMT_DXT4); 01750 FMT_TO_STR(WINED3DFMT_DXT5); 01751 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8); 01752 FMT_TO_STR(WINED3DFMT_G8R8_G8B8); 01753 FMT_TO_STR(WINED3DFMT_R8G8_B8G8); 01754 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE); 01755 FMT_TO_STR(WINED3DFMT_D32_UNORM); 01756 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM); 01757 FMT_TO_STR(WINED3DFMT_X8D24_UNORM); 01758 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM); 01759 FMT_TO_STR(WINED3DFMT_L16_UNORM); 01760 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT); 01761 FMT_TO_STR(WINED3DFMT_VERTEXDATA); 01762 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx); 01763 FMT_TO_STR(WINED3DFMT_ATI2N); 01764 FMT_TO_STR(WINED3DFMT_NVDB); 01765 FMT_TO_STR(WINED3DFMT_NVHU); 01766 FMT_TO_STR(WINED3DFMT_NVHS); 01767 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS); 01768 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT); 01769 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT); 01770 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT); 01771 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS); 01772 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT); 01773 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT); 01774 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT); 01775 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS); 01776 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT); 01777 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM); 01778 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT); 01779 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM); 01780 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT); 01781 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS); 01782 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT); 01783 FMT_TO_STR(WINED3DFMT_R32G32_UINT); 01784 FMT_TO_STR(WINED3DFMT_R32G32_SINT); 01785 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS); 01786 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT); 01787 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS); 01788 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT); 01789 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS); 01790 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM); 01791 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT); 01792 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM); 01793 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT); 01794 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS); 01795 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM); 01796 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB); 01797 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT); 01798 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM); 01799 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT); 01800 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS); 01801 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT); 01802 FMT_TO_STR(WINED3DFMT_R16G16_UNORM); 01803 FMT_TO_STR(WINED3DFMT_R16G16_UINT); 01804 FMT_TO_STR(WINED3DFMT_R16G16_SNORM); 01805 FMT_TO_STR(WINED3DFMT_R16G16_SINT); 01806 FMT_TO_STR(WINED3DFMT_R32_TYPELESS); 01807 FMT_TO_STR(WINED3DFMT_D32_FLOAT); 01808 FMT_TO_STR(WINED3DFMT_R32_FLOAT); 01809 FMT_TO_STR(WINED3DFMT_R32_UINT); 01810 FMT_TO_STR(WINED3DFMT_R32_SINT); 01811 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS); 01812 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT); 01813 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS); 01814 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT); 01815 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS); 01816 FMT_TO_STR(WINED3DFMT_R8G8_UNORM); 01817 FMT_TO_STR(WINED3DFMT_R8G8_UINT); 01818 FMT_TO_STR(WINED3DFMT_R8G8_SNORM); 01819 FMT_TO_STR(WINED3DFMT_R8G8_SINT); 01820 FMT_TO_STR(WINED3DFMT_R16_TYPELESS); 01821 FMT_TO_STR(WINED3DFMT_R16_FLOAT); 01822 FMT_TO_STR(WINED3DFMT_D16_UNORM); 01823 FMT_TO_STR(WINED3DFMT_R16_UNORM); 01824 FMT_TO_STR(WINED3DFMT_R16_UINT); 01825 FMT_TO_STR(WINED3DFMT_R16_SNORM); 01826 FMT_TO_STR(WINED3DFMT_R16_SINT); 01827 FMT_TO_STR(WINED3DFMT_R8_TYPELESS); 01828 FMT_TO_STR(WINED3DFMT_R8_UNORM); 01829 FMT_TO_STR(WINED3DFMT_R8_UINT); 01830 FMT_TO_STR(WINED3DFMT_R8_SNORM); 01831 FMT_TO_STR(WINED3DFMT_R8_SINT); 01832 FMT_TO_STR(WINED3DFMT_A8_UNORM); 01833 FMT_TO_STR(WINED3DFMT_R1_UNORM); 01834 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP); 01835 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM); 01836 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM); 01837 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS); 01838 FMT_TO_STR(WINED3DFMT_BC1_UNORM); 01839 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB); 01840 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS); 01841 FMT_TO_STR(WINED3DFMT_BC2_UNORM); 01842 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB); 01843 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS); 01844 FMT_TO_STR(WINED3DFMT_BC3_UNORM); 01845 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB); 01846 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS); 01847 FMT_TO_STR(WINED3DFMT_BC4_UNORM); 01848 FMT_TO_STR(WINED3DFMT_BC4_SNORM); 01849 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS); 01850 FMT_TO_STR(WINED3DFMT_BC5_UNORM); 01851 FMT_TO_STR(WINED3DFMT_BC5_SNORM); 01852 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM); 01853 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM); 01854 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM); 01855 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM); 01856 FMT_TO_STR(WINED3DFMT_INTZ); 01857 FMT_TO_STR(WINED3DFMT_NULL); 01858 FMT_TO_STR(WINED3DFMT_R16); 01859 FMT_TO_STR(WINED3DFMT_AL16); 01860 #undef FMT_TO_STR 01861 default: 01862 { 01863 char fourcc[5]; 01864 fourcc[0] = (char)(format_id); 01865 fourcc[1] = (char)(format_id >> 8); 01866 fourcc[2] = (char)(format_id >> 16); 01867 fourcc[3] = (char)(format_id >> 24); 01868 fourcc[4] = 0; 01869 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3])) 01870 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc); 01871 else 01872 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id); 01873 } 01874 return "unrecognized"; 01875 } 01876 } 01877 01878 const char *debug_d3ddevicetype(enum wined3d_device_type device_type) 01879 { 01880 switch (device_type) 01881 { 01882 #define DEVTYPE_TO_STR(dev) case dev: return #dev 01883 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_HAL); 01884 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_REF); 01885 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_SW); 01886 #undef DEVTYPE_TO_STR 01887 default: 01888 FIXME("Unrecognized device type %#x.\n", device_type); 01889 return "unrecognized"; 01890 } 01891 } 01892 01893 const char *debug_d3dusage(DWORD usage) 01894 { 01895 char buf[333]; 01896 01897 buf[0] = '\0'; 01898 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; } 01899 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET); 01900 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL); 01901 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY); 01902 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING); 01903 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP); 01904 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS); 01905 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES); 01906 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES); 01907 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC); 01908 WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP); 01909 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP); 01910 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL); 01911 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY); 01912 #undef WINED3DUSAGE_TO_STR 01913 if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage); 01914 01915 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0"; 01916 } 01917 01918 const char *debug_d3dusagequery(DWORD usagequery) 01919 { 01920 char buf[238]; 01921 01922 buf[0] = '\0'; 01923 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; } 01924 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER); 01925 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP); 01926 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING); 01927 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD); 01928 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE); 01929 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE); 01930 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP); 01931 #undef WINED3DUSAGEQUERY_TO_STR 01932 if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery); 01933 01934 return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0"; 01935 } 01936 01937 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) { 01938 switch (method) { 01939 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u 01940 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT); 01941 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU); 01942 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV); 01943 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV); 01944 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV); 01945 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP); 01946 WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED); 01947 #undef WINED3DDECLMETHOD_TO_STR 01948 default: 01949 FIXME("Unrecognized %u declaration method!\n", method); 01950 return "unrecognized"; 01951 } 01952 } 01953 01954 const char* debug_d3ddeclusage(BYTE usage) { 01955 switch (usage) { 01956 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u 01957 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION); 01958 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT); 01959 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES); 01960 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL); 01961 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE); 01962 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD); 01963 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT); 01964 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL); 01965 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR); 01966 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT); 01967 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR); 01968 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG); 01969 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH); 01970 WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE); 01971 #undef WINED3DDECLUSAGE_TO_STR 01972 default: 01973 FIXME("Unrecognized %u declaration usage!\n", usage); 01974 return "unrecognized"; 01975 } 01976 } 01977 01978 const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type) 01979 { 01980 switch (resource_type) 01981 { 01982 #define RES_TO_STR(res) case res: return #res 01983 RES_TO_STR(WINED3D_RTYPE_SURFACE); 01984 RES_TO_STR(WINED3D_RTYPE_VOLUME); 01985 RES_TO_STR(WINED3D_RTYPE_TEXTURE); 01986 RES_TO_STR(WINED3D_RTYPE_VOLUME_TEXTURE); 01987 RES_TO_STR(WINED3D_RTYPE_CUBE_TEXTURE); 01988 RES_TO_STR(WINED3D_RTYPE_BUFFER); 01989 #undef RES_TO_STR 01990 default: 01991 FIXME("Unrecognized resource type %#x.\n", resource_type); 01992 return "unrecognized"; 01993 } 01994 } 01995 01996 const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type) 01997 { 01998 switch (primitive_type) 01999 { 02000 #define PRIM_TO_STR(prim) case prim: return #prim 02001 PRIM_TO_STR(WINED3D_PT_UNDEFINED); 02002 PRIM_TO_STR(WINED3D_PT_POINTLIST); 02003 PRIM_TO_STR(WINED3D_PT_LINELIST); 02004 PRIM_TO_STR(WINED3D_PT_LINESTRIP); 02005 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST); 02006 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP); 02007 PRIM_TO_STR(WINED3D_PT_TRIANGLEFAN); 02008 PRIM_TO_STR(WINED3D_PT_LINELIST_ADJ); 02009 PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ); 02010 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ); 02011 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ); 02012 #undef PRIM_TO_STR 02013 default: 02014 FIXME("Unrecognized %u primitive type!\n", primitive_type); 02015 return "unrecognized"; 02016 } 02017 } 02018 02019 const char *debug_d3drenderstate(enum wined3d_render_state state) 02020 { 02021 switch (state) 02022 { 02023 #define D3DSTATE_TO_STR(u) case u: return #u 02024 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIAS); 02025 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREPERSPECTIVE); 02026 D3DSTATE_TO_STR(WINED3D_RS_WRAPU); 02027 D3DSTATE_TO_STR(WINED3D_RS_WRAPV); 02028 D3DSTATE_TO_STR(WINED3D_RS_ZENABLE); 02029 D3DSTATE_TO_STR(WINED3D_RS_FILLMODE); 02030 D3DSTATE_TO_STR(WINED3D_RS_SHADEMODE); 02031 D3DSTATE_TO_STR(WINED3D_RS_LINEPATTERN); 02032 D3DSTATE_TO_STR(WINED3D_RS_MONOENABLE); 02033 D3DSTATE_TO_STR(WINED3D_RS_ROP2); 02034 D3DSTATE_TO_STR(WINED3D_RS_PLANEMASK); 02035 D3DSTATE_TO_STR(WINED3D_RS_ZWRITEENABLE); 02036 D3DSTATE_TO_STR(WINED3D_RS_ALPHATESTENABLE); 02037 D3DSTATE_TO_STR(WINED3D_RS_LASTPIXEL); 02038 D3DSTATE_TO_STR(WINED3D_RS_SRCBLEND); 02039 D3DSTATE_TO_STR(WINED3D_RS_DESTBLEND); 02040 D3DSTATE_TO_STR(WINED3D_RS_CULLMODE); 02041 D3DSTATE_TO_STR(WINED3D_RS_ZFUNC); 02042 D3DSTATE_TO_STR(WINED3D_RS_ALPHAREF); 02043 D3DSTATE_TO_STR(WINED3D_RS_ALPHAFUNC); 02044 D3DSTATE_TO_STR(WINED3D_RS_DITHERENABLE); 02045 D3DSTATE_TO_STR(WINED3D_RS_ALPHABLENDENABLE); 02046 D3DSTATE_TO_STR(WINED3D_RS_FOGENABLE); 02047 D3DSTATE_TO_STR(WINED3D_RS_SPECULARENABLE); 02048 D3DSTATE_TO_STR(WINED3D_RS_ZVISIBLE); 02049 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXEL); 02050 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXELX); 02051 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEDALPHA); 02052 D3DSTATE_TO_STR(WINED3D_RS_FOGCOLOR); 02053 D3DSTATE_TO_STR(WINED3D_RS_FOGTABLEMODE); 02054 D3DSTATE_TO_STR(WINED3D_RS_FOGSTART); 02055 D3DSTATE_TO_STR(WINED3D_RS_FOGEND); 02056 D3DSTATE_TO_STR(WINED3D_RS_FOGDENSITY); 02057 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEENABLE); 02058 D3DSTATE_TO_STR(WINED3D_RS_EDGEANTIALIAS); 02059 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYENABLE); 02060 D3DSTATE_TO_STR(WINED3D_RS_MIPMAPLODBIAS); 02061 D3DSTATE_TO_STR(WINED3D_RS_RANGEFOGENABLE); 02062 D3DSTATE_TO_STR(WINED3D_RS_ANISOTROPY); 02063 D3DSTATE_TO_STR(WINED3D_RS_FLUSHBATCH); 02064 D3DSTATE_TO_STR(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT); 02065 D3DSTATE_TO_STR(WINED3D_RS_STENCILENABLE); 02066 D3DSTATE_TO_STR(WINED3D_RS_STENCILFAIL); 02067 D3DSTATE_TO_STR(WINED3D_RS_STENCILZFAIL); 02068 D3DSTATE_TO_STR(WINED3D_RS_STENCILPASS); 02069 D3DSTATE_TO_STR(WINED3D_RS_STENCILFUNC); 02070 D3DSTATE_TO_STR(WINED3D_RS_STENCILREF); 02071 D3DSTATE_TO_STR(WINED3D_RS_STENCILMASK); 02072 D3DSTATE_TO_STR(WINED3D_RS_STENCILWRITEMASK); 02073 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREFACTOR); 02074 D3DSTATE_TO_STR(WINED3D_RS_WRAP0); 02075 D3DSTATE_TO_STR(WINED3D_RS_WRAP1); 02076 D3DSTATE_TO_STR(WINED3D_RS_WRAP2); 02077 D3DSTATE_TO_STR(WINED3D_RS_WRAP3); 02078 D3DSTATE_TO_STR(WINED3D_RS_WRAP4); 02079 D3DSTATE_TO_STR(WINED3D_RS_WRAP5); 02080 D3DSTATE_TO_STR(WINED3D_RS_WRAP6); 02081 D3DSTATE_TO_STR(WINED3D_RS_WRAP7); 02082 D3DSTATE_TO_STR(WINED3D_RS_CLIPPING); 02083 D3DSTATE_TO_STR(WINED3D_RS_LIGHTING); 02084 D3DSTATE_TO_STR(WINED3D_RS_EXTENTS); 02085 D3DSTATE_TO_STR(WINED3D_RS_AMBIENT); 02086 D3DSTATE_TO_STR(WINED3D_RS_FOGVERTEXMODE); 02087 D3DSTATE_TO_STR(WINED3D_RS_COLORVERTEX); 02088 D3DSTATE_TO_STR(WINED3D_RS_LOCALVIEWER); 02089 D3DSTATE_TO_STR(WINED3D_RS_NORMALIZENORMALS); 02090 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYBLENDENABLE); 02091 D3DSTATE_TO_STR(WINED3D_RS_DIFFUSEMATERIALSOURCE); 02092 D3DSTATE_TO_STR(WINED3D_RS_SPECULARMATERIALSOURCE); 02093 D3DSTATE_TO_STR(WINED3D_RS_AMBIENTMATERIALSOURCE); 02094 D3DSTATE_TO_STR(WINED3D_RS_EMISSIVEMATERIALSOURCE); 02095 D3DSTATE_TO_STR(WINED3D_RS_VERTEXBLEND); 02096 D3DSTATE_TO_STR(WINED3D_RS_CLIPPLANEENABLE); 02097 D3DSTATE_TO_STR(WINED3D_RS_SOFTWAREVERTEXPROCESSING); 02098 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE); 02099 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MIN); 02100 D3DSTATE_TO_STR(WINED3D_RS_POINTSPRITEENABLE); 02101 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALEENABLE); 02102 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_A); 02103 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_B); 02104 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_C); 02105 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEANTIALIAS); 02106 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEMASK); 02107 D3DSTATE_TO_STR(WINED3D_RS_PATCHEDGESTYLE); 02108 D3DSTATE_TO_STR(WINED3D_RS_PATCHSEGMENTS); 02109 D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN); 02110 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX); 02111 D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE); 02112 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE); 02113 D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR); 02114 D3DSTATE_TO_STR(WINED3D_RS_BLENDOP); 02115 D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE); 02116 D3DSTATE_TO_STR(WINED3D_RS_NORMALDEGREE); 02117 D3DSTATE_TO_STR(WINED3D_RS_SCISSORTESTENABLE); 02118 D3DSTATE_TO_STR(WINED3D_RS_SLOPESCALEDEPTHBIAS); 02119 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIASEDLINEENABLE); 02120 D3DSTATE_TO_STR(WINED3D_RS_MINTESSELLATIONLEVEL); 02121 D3DSTATE_TO_STR(WINED3D_RS_MAXTESSELLATIONLEVEL); 02122 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_X); 02123 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Y); 02124 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Z); 02125 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_W); 02126 D3DSTATE_TO_STR(WINED3D_RS_ENABLEADAPTIVETESSELLATION); 02127 D3DSTATE_TO_STR(WINED3D_RS_TWOSIDEDSTENCILMODE); 02128 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFAIL); 02129 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILZFAIL); 02130 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILPASS); 02131 D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFUNC); 02132 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1); 02133 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2); 02134 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3); 02135 D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR); 02136 D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE); 02137 D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS); 02138 D3DSTATE_TO_STR(WINED3D_RS_WRAP8); 02139 D3DSTATE_TO_STR(WINED3D_RS_WRAP9); 02140 D3DSTATE_TO_STR(WINED3D_RS_WRAP10); 02141 D3DSTATE_TO_STR(WINED3D_RS_WRAP11); 02142 D3DSTATE_TO_STR(WINED3D_RS_WRAP12); 02143 D3DSTATE_TO_STR(WINED3D_RS_WRAP13); 02144 D3DSTATE_TO_STR(WINED3D_RS_WRAP14); 02145 D3DSTATE_TO_STR(WINED3D_RS_WRAP15); 02146 D3DSTATE_TO_STR(WINED3D_RS_SEPARATEALPHABLENDENABLE); 02147 D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA); 02148 D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA); 02149 D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA); 02150 #undef D3DSTATE_TO_STR 02151 default: 02152 FIXME("Unrecognized %u render state!\n", state); 02153 return "unrecognized"; 02154 } 02155 } 02156 02157 const char *debug_d3dsamplerstate(enum wined3d_sampler_state state) 02158 { 02159 switch (state) 02160 { 02161 #define D3DSTATE_TO_STR(u) case u: return #u 02162 D3DSTATE_TO_STR(WINED3D_SAMP_BORDER_COLOR); 02163 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_U); 02164 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_V); 02165 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_W); 02166 D3DSTATE_TO_STR(WINED3D_SAMP_MAG_FILTER); 02167 D3DSTATE_TO_STR(WINED3D_SAMP_MIN_FILTER); 02168 D3DSTATE_TO_STR(WINED3D_SAMP_MIP_FILTER); 02169 D3DSTATE_TO_STR(WINED3D_SAMP_MIPMAP_LOD_BIAS); 02170 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_MIP_LEVEL); 02171 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_ANISOTROPY); 02172 D3DSTATE_TO_STR(WINED3D_SAMP_SRGB_TEXTURE); 02173 D3DSTATE_TO_STR(WINED3D_SAMP_ELEMENT_INDEX); 02174 D3DSTATE_TO_STR(WINED3D_SAMP_DMAP_OFFSET); 02175 #undef D3DSTATE_TO_STR 02176 default: 02177 FIXME("Unrecognized %u sampler state!\n", state); 02178 return "unrecognized"; 02179 } 02180 } 02181 02182 const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type) 02183 { 02184 switch (filter_type) 02185 { 02186 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u 02187 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_NONE); 02188 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_POINT); 02189 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_LINEAR); 02190 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_ANISOTROPIC); 02191 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_FLAT_CUBIC); 02192 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_CUBIC); 02193 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_PYRAMIDAL_QUAD); 02194 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_QUAD); 02195 #undef D3DTEXTUREFILTERTYPE_TO_STR 02196 default: 02197 FIXME("Unrecognied texture filter type 0x%08x.\n", filter_type); 02198 return "unrecognized"; 02199 } 02200 } 02201 02202 const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state) 02203 { 02204 switch (state) 02205 { 02206 #define D3DSTATE_TO_STR(u) case u: return #u 02207 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_OP); 02208 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG1); 02209 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG2); 02210 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_OP); 02211 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG1); 02212 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG2); 02213 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT00); 02214 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT01); 02215 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT10); 02216 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT11); 02217 D3DSTATE_TO_STR(WINED3D_TSS_TEXCOORD_INDEX); 02218 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LSCALE); 02219 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LOFFSET); 02220 D3DSTATE_TO_STR(WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS); 02221 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG0); 02222 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG0); 02223 D3DSTATE_TO_STR(WINED3D_TSS_RESULT_ARG); 02224 D3DSTATE_TO_STR(WINED3D_TSS_CONSTANT); 02225 #undef D3DSTATE_TO_STR 02226 default: 02227 FIXME("Unrecognized %u texture state!\n", state); 02228 return "unrecognized"; 02229 } 02230 } 02231 02232 const char *debug_d3dtop(enum wined3d_texture_op d3dtop) 02233 { 02234 switch (d3dtop) 02235 { 02236 #define D3DTOP_TO_STR(u) case u: return #u 02237 D3DTOP_TO_STR(WINED3D_TOP_DISABLE); 02238 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG1); 02239 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG2); 02240 D3DTOP_TO_STR(WINED3D_TOP_MODULATE); 02241 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_2X); 02242 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_4X); 02243 D3DTOP_TO_STR(WINED3D_TOP_ADD); 02244 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED); 02245 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED_2X); 02246 D3DTOP_TO_STR(WINED3D_TOP_SUBTRACT); 02247 D3DTOP_TO_STR(WINED3D_TOP_ADD_SMOOTH); 02248 D3DTOP_TO_STR(WINED3D_TOP_BLEND_DIFFUSE_ALPHA); 02249 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA); 02250 D3DTOP_TO_STR(WINED3D_TOP_BLEND_FACTOR_ALPHA); 02251 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM); 02252 D3DTOP_TO_STR(WINED3D_TOP_BLEND_CURRENT_ALPHA); 02253 D3DTOP_TO_STR(WINED3D_TOP_PREMODULATE); 02254 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR); 02255 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA); 02256 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR); 02257 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA); 02258 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP); 02259 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP_LUMINANCE); 02260 D3DTOP_TO_STR(WINED3D_TOP_DOTPRODUCT3); 02261 D3DTOP_TO_STR(WINED3D_TOP_MULTIPLY_ADD); 02262 D3DTOP_TO_STR(WINED3D_TOP_LERP); 02263 #undef D3DTOP_TO_STR 02264 default: 02265 FIXME("Unrecognized texture op %#x.\n", d3dtop); 02266 return "unrecognized"; 02267 } 02268 } 02269 02270 const char *debug_d3dtstype(enum wined3d_transform_state tstype) 02271 { 02272 switch (tstype) 02273 { 02274 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype 02275 TSTYPE_TO_STR(WINED3D_TS_VIEW); 02276 TSTYPE_TO_STR(WINED3D_TS_PROJECTION); 02277 TSTYPE_TO_STR(WINED3D_TS_TEXTURE0); 02278 TSTYPE_TO_STR(WINED3D_TS_TEXTURE1); 02279 TSTYPE_TO_STR(WINED3D_TS_TEXTURE2); 02280 TSTYPE_TO_STR(WINED3D_TS_TEXTURE3); 02281 TSTYPE_TO_STR(WINED3D_TS_TEXTURE4); 02282 TSTYPE_TO_STR(WINED3D_TS_TEXTURE5); 02283 TSTYPE_TO_STR(WINED3D_TS_TEXTURE6); 02284 TSTYPE_TO_STR(WINED3D_TS_TEXTURE7); 02285 TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(0)); 02286 #undef TSTYPE_TO_STR 02287 default: 02288 if (tstype > 256 && tstype < 512) 02289 { 02290 FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype); 02291 return ("WINED3D_TS_WORLD_MATRIX > 0"); 02292 } 02293 FIXME("Unrecognized transform state %#x.\n", tstype); 02294 return "unrecognized"; 02295 } 02296 } 02297 02298 const char *debug_d3dstate(DWORD state) 02299 { 02300 if (STATE_IS_RENDER(state)) 02301 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0))); 02302 if (STATE_IS_TEXTURESTAGE(state)) 02303 { 02304 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); 02305 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0); 02306 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)", 02307 texture_stage, debug_d3dtexturestate(texture_state)); 02308 } 02309 if (STATE_IS_SAMPLER(state)) 02310 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0)); 02311 if (STATE_IS_PIXELSHADER(state)) 02312 return "STATE_PIXELSHADER"; 02313 if (STATE_IS_TRANSFORM(state)) 02314 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0))); 02315 if (STATE_IS_STREAMSRC(state)) 02316 return "STATE_STREAMSRC"; 02317 if (STATE_IS_INDEXBUFFER(state)) 02318 return "STATE_INDEXBUFFER"; 02319 if (STATE_IS_VDECL(state)) 02320 return "STATE_VDECL"; 02321 if (STATE_IS_VSHADER(state)) 02322 return "STATE_VSHADER"; 02323 if (STATE_IS_VIEWPORT(state)) 02324 return "STATE_VIEWPORT"; 02325 if (STATE_IS_VERTEXSHADERCONSTANT(state)) 02326 return "STATE_VERTEXSHADERCONSTANT"; 02327 if (STATE_IS_PIXELSHADERCONSTANT(state)) 02328 return "STATE_PIXELSHADERCONSTANT"; 02329 if (STATE_IS_ACTIVELIGHT(state)) 02330 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0)); 02331 if (STATE_IS_SCISSORRECT(state)) 02332 return "STATE_SCISSORRECT"; 02333 if (STATE_IS_CLIPPLANE(state)) 02334 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0)); 02335 if (STATE_IS_MATERIAL(state)) 02336 return "STATE_MATERIAL"; 02337 if (STATE_IS_FRONTFACE(state)) 02338 return "STATE_FRONTFACE"; 02339 if (STATE_IS_POINTSPRITECOORDORIGIN(state)) 02340 return "STATE_POINTSPRITECOORDORIGIN"; 02341 if (STATE_IS_BASEVERTEXINDEX(state)) 02342 return "STATE_BASEVERTEXINDEX"; 02343 if (STATE_IS_FRAMEBUFFER(state)) 02344 return "STATE_FRAMEBUFFER"; 02345 02346 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state); 02347 } 02348 02349 const char *debug_d3dpool(enum wined3d_pool pool) 02350 { 02351 switch (pool) 02352 { 02353 #define POOL_TO_STR(p) case p: return #p 02354 POOL_TO_STR(WINED3D_POOL_DEFAULT); 02355 POOL_TO_STR(WINED3D_POOL_MANAGED); 02356 POOL_TO_STR(WINED3D_POOL_SYSTEM_MEM); 02357 POOL_TO_STR(WINED3D_POOL_SCRATCH); 02358 #undef POOL_TO_STR 02359 default: 02360 FIXME("Unrecognized pool %#x.\n", pool); 02361 return "unrecognized"; 02362 } 02363 } 02364 02365 const char *debug_fbostatus(GLenum status) { 02366 switch(status) { 02367 #define FBOSTATUS_TO_STR(u) case u: return #u 02368 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE); 02369 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT); 02370 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT); 02371 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT); 02372 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT); 02373 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER); 02374 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER); 02375 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE); 02376 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED); 02377 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED); 02378 #undef FBOSTATUS_TO_STR 02379 default: 02380 FIXME("Unrecognied FBO status 0x%08x\n", status); 02381 return "unrecognized"; 02382 } 02383 } 02384 02385 const char *debug_glerror(GLenum error) { 02386 switch(error) { 02387 #define GLERROR_TO_STR(u) case u: return #u 02388 GLERROR_TO_STR(GL_NO_ERROR); 02389 GLERROR_TO_STR(GL_INVALID_ENUM); 02390 GLERROR_TO_STR(GL_INVALID_VALUE); 02391 GLERROR_TO_STR(GL_INVALID_OPERATION); 02392 GLERROR_TO_STR(GL_STACK_OVERFLOW); 02393 GLERROR_TO_STR(GL_STACK_UNDERFLOW); 02394 GLERROR_TO_STR(GL_OUT_OF_MEMORY); 02395 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION); 02396 #undef GLERROR_TO_STR 02397 default: 02398 FIXME("Unrecognied GL error 0x%08x\n", error); 02399 return "unrecognized"; 02400 } 02401 } 02402 02403 const char *debug_d3dbasis(enum wined3d_basis_type basis) 02404 { 02405 switch (basis) 02406 { 02407 case WINED3D_BASIS_BEZIER: return "WINED3D_BASIS_BEZIER"; 02408 case WINED3D_BASIS_BSPLINE: return "WINED3D_BASIS_BSPLINE"; 02409 case WINED3D_BASIS_INTERPOLATE: return "WINED3D_BASIS_INTERPOLATE"; 02410 default: return "unrecognized"; 02411 } 02412 } 02413 02414 const char *debug_d3ddegree(enum wined3d_degree_type degree) 02415 { 02416 switch (degree) 02417 { 02418 case WINED3D_DEGREE_LINEAR: return "WINED3D_DEGREE_LINEAR"; 02419 case WINED3D_DEGREE_QUADRATIC: return "WINED3D_DEGREE_QUADRATIC"; 02420 case WINED3D_DEGREE_CUBIC: return "WINED3D_DEGREE_CUBIC"; 02421 case WINED3D_DEGREE_QUINTIC: return "WINED3D_DEGREE_QUINTIC"; 02422 default: return "unrecognized"; 02423 } 02424 } 02425 02426 static const char *debug_fixup_channel_source(enum fixup_channel_source source) 02427 { 02428 switch(source) 02429 { 02430 #define WINED3D_TO_STR(x) case x: return #x 02431 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO); 02432 WINED3D_TO_STR(CHANNEL_SOURCE_ONE); 02433 WINED3D_TO_STR(CHANNEL_SOURCE_X); 02434 WINED3D_TO_STR(CHANNEL_SOURCE_Y); 02435 WINED3D_TO_STR(CHANNEL_SOURCE_Z); 02436 WINED3D_TO_STR(CHANNEL_SOURCE_W); 02437 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0); 02438 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1); 02439 #undef WINED3D_TO_STR 02440 default: 02441 FIXME("Unrecognized fixup_channel_source %#x\n", source); 02442 return "unrecognized"; 02443 } 02444 } 02445 02446 static const char *debug_complex_fixup(enum complex_fixup fixup) 02447 { 02448 switch(fixup) 02449 { 02450 #define WINED3D_TO_STR(x) case x: return #x 02451 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2); 02452 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY); 02453 WINED3D_TO_STR(COMPLEX_FIXUP_YV12); 02454 WINED3D_TO_STR(COMPLEX_FIXUP_P8); 02455 #undef WINED3D_TO_STR 02456 default: 02457 FIXME("Unrecognized complex fixup %#x\n", fixup); 02458 return "unrecognized"; 02459 } 02460 } 02461 02462 void dump_color_fixup_desc(struct color_fixup_desc fixup) 02463 { 02464 if (is_complex_fixup(fixup)) 02465 { 02466 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup))); 02467 return; 02468 } 02469 02470 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : ""); 02471 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : ""); 02472 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : ""); 02473 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : ""); 02474 } 02475 02476 const char *debug_surflocation(DWORD flag) { 02477 char buf[128]; 02478 02479 buf[0] = 0; 02480 if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM"); /* 17 */ 02481 if (flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE"); /* 19 */ 02482 if (flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE"); /* 18 */ 02483 if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX"); /* 18 */ 02484 if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE"); /* 25 */ 02485 if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED"); /* 22 */ 02486 return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0"); 02487 } 02488 02489 BOOL is_invalid_op(const struct wined3d_state *state, int stage, 02490 enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3) 02491 { 02492 if (op == WINED3D_TOP_DISABLE) 02493 return FALSE; 02494 if (state->textures[stage]) 02495 return FALSE; 02496 02497 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE 02498 && op != WINED3D_TOP_SELECT_ARG2) 02499 return TRUE; 02500 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE 02501 && op != WINED3D_TOP_SELECT_ARG1) 02502 return TRUE; 02503 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE 02504 && (op == WINED3D_TOP_MULTIPLY_ADD || op == WINED3D_TOP_LERP)) 02505 return TRUE; 02506 02507 return FALSE; 02508 } 02509 02510 /* Setup this textures matrix according to the texture flags*/ 02511 /* GL locking is done by the caller (state handler) */ 02512 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, 02513 enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control) 02514 { 02515 float mat[16]; 02516 02517 glMatrixMode(GL_TEXTURE); 02518 checkGLcall("glMatrixMode(GL_TEXTURE)"); 02519 02520 if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed) 02521 { 02522 glLoadIdentity(); 02523 checkGLcall("glLoadIdentity()"); 02524 return; 02525 } 02526 02527 if (flags == (WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED)) 02528 { 02529 ERR("Invalid texture transform flags: WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED.\n"); 02530 return; 02531 } 02532 02533 memcpy(mat, smat, 16 * sizeof(float)); 02534 02535 if (flags & WINED3D_TTFF_PROJECTED) 02536 { 02537 if (!ffp_proj_control) 02538 { 02539 switch (flags & ~WINED3D_TTFF_PROJECTED) 02540 { 02541 case WINED3D_TTFF_COUNT2: 02542 mat[ 3] = mat[ 1]; 02543 mat[ 7] = mat[ 5]; 02544 mat[11] = mat[ 9]; 02545 mat[15] = mat[13]; 02546 mat[ 1] = mat[ 5] = mat[ 9] = mat[13] = 0.0f; 02547 break; 02548 case WINED3D_TTFF_COUNT3: 02549 mat[ 3] = mat[ 2]; 02550 mat[ 7] = mat[ 6]; 02551 mat[11] = mat[10]; 02552 mat[15] = mat[14]; 02553 mat[ 2] = mat[ 6] = mat[10] = mat[14] = 0.0f; 02554 break; 02555 } 02556 } 02557 } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */ 02558 if(!calculatedCoords) { 02559 switch(vtx_fmt) 02560 { 02561 case WINED3DFMT_R32_FLOAT: 02562 /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th. 02563 * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because 02564 * the input value to the transformation will be 0, so the matrix value is irrelevant 02565 */ 02566 mat[12] = mat[4]; 02567 mat[13] = mat[5]; 02568 mat[14] = mat[6]; 02569 mat[15] = mat[7]; 02570 break; 02571 case WINED3DFMT_R32G32_FLOAT: 02572 /* See above, just 3rd and 4th coord 02573 */ 02574 mat[12] = mat[8]; 02575 mat[13] = mat[9]; 02576 mat[14] = mat[10]; 02577 mat[15] = mat[11]; 02578 break; 02579 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */ 02580 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */ 02581 02582 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0 02583 * into a bad place. The division elimination below will apply to make sure the 02584 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0 02585 */ 02586 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */ 02587 break; 02588 default: 02589 FIXME("Unexpected fixed function texture coord input\n"); 02590 } 02591 } 02592 if (!ffp_proj_control) 02593 { 02594 switch (flags & ~WINED3D_TTFF_PROJECTED) 02595 { 02596 /* case WINED3D_TTFF_COUNT1: Won't ever get here. */ 02597 case WINED3D_TTFF_COUNT2: 02598 mat[2] = mat[6] = mat[10] = mat[14] = 0; 02599 /* OpenGL divides the first 3 vertex coord by the 4th by default, 02600 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that 02601 * the 4th coord evaluates to 1.0 to eliminate that. 02602 * 02603 * If the fixed function pipeline is used, the 4th value remains unused, 02604 * so there is no danger in doing this. With vertex shaders we have a 02605 * problem. Should an app hit that problem, the code here would have to 02606 * check for pixel shaders, and the shader has to undo the default gl divide. 02607 * 02608 * A more serious problem occurs if the app passes 4 coordinates in, and the 02609 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow 02610 * or a replacement shader. */ 02611 default: 02612 mat[3] = mat[7] = mat[11] = 0; mat[15] = 1; 02613 } 02614 } 02615 } 02616 02617 glLoadMatrixf(mat); 02618 checkGLcall("glLoadMatrixf(mat)"); 02619 } 02620 02621 /* This small helper function is used to convert a bitmask into the number of masked bits */ 02622 unsigned int count_bits(unsigned int mask) 02623 { 02624 unsigned int count; 02625 for (count = 0; mask; ++count) 02626 { 02627 mask &= mask - 1; 02628 } 02629 return count; 02630 } 02631 02632 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB. 02633 * The later function requires individual color components. */ 02634 BOOL getColorBits(const struct wined3d_format *format, 02635 BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize) 02636 { 02637 TRACE("format %s.\n", debug_d3dformat(format->id)); 02638 02639 switch (format->id) 02640 { 02641 case WINED3DFMT_B10G10R10A2_UNORM: 02642 case WINED3DFMT_R10G10B10A2_UNORM: 02643 case WINED3DFMT_B8G8R8X8_UNORM: 02644 case WINED3DFMT_B8G8R8_UNORM: 02645 case WINED3DFMT_B8G8R8A8_UNORM: 02646 case WINED3DFMT_R8G8B8A8_UNORM: 02647 case WINED3DFMT_B5G5R5X1_UNORM: 02648 case WINED3DFMT_B5G5R5A1_UNORM: 02649 case WINED3DFMT_B5G6R5_UNORM: 02650 case WINED3DFMT_B4G4R4X4_UNORM: 02651 case WINED3DFMT_B4G4R4A4_UNORM: 02652 case WINED3DFMT_B2G3R3_UNORM: 02653 case WINED3DFMT_P8_UINT_A8_UNORM: 02654 case WINED3DFMT_P8_UINT: 02655 break; 02656 default: 02657 FIXME("Unsupported format %s.\n", debug_d3dformat(format->id)); 02658 return FALSE; 02659 } 02660 02661 *redSize = count_bits(format->red_mask); 02662 *greenSize = count_bits(format->green_mask); 02663 *blueSize = count_bits(format->blue_mask); 02664 *alphaSize = count_bits(format->alpha_mask); 02665 *totalSize = *redSize + *greenSize + *blueSize + *alphaSize; 02666 02667 TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n", 02668 *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id)); 02669 return TRUE; 02670 } 02671 02672 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */ 02673 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize) 02674 { 02675 TRACE("format %s.\n", debug_d3dformat(format->id)); 02676 02677 switch (format->id) 02678 { 02679 case WINED3DFMT_D16_LOCKABLE: 02680 case WINED3DFMT_D16_UNORM: 02681 case WINED3DFMT_S1_UINT_D15_UNORM: 02682 case WINED3DFMT_X8D24_UNORM: 02683 case WINED3DFMT_S4X4_UINT_D24_UNORM: 02684 case WINED3DFMT_D24_UNORM_S8_UINT: 02685 case WINED3DFMT_S8_UINT_D24_FLOAT: 02686 case WINED3DFMT_D32_UNORM: 02687 case WINED3DFMT_D32_FLOAT: 02688 case WINED3DFMT_INTZ: 02689 break; 02690 default: 02691 FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id)); 02692 return FALSE; 02693 } 02694 02695 *depthSize = format->depth_size; 02696 *stencilSize = format->stencil_size; 02697 02698 TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n", 02699 *depthSize, *stencilSize, debug_d3dformat(format->id)); 02700 return TRUE; 02701 } 02702 02703 /* Note: It's the caller's responsibility to ensure values can be expressed 02704 * in the requested format. UNORM formats for example can only express values 02705 * in the range 0.0f -> 1.0f. */ 02706 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color) 02707 { 02708 static const struct 02709 { 02710 enum wined3d_format_id format_id; 02711 float r_mul; 02712 float g_mul; 02713 float b_mul; 02714 float a_mul; 02715 BYTE r_shift; 02716 BYTE g_shift; 02717 BYTE b_shift; 02718 BYTE a_shift; 02719 } 02720 conv[] = 02721 { 02722 {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24}, 02723 {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24}, 02724 {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24}, 02725 {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0}, 02726 {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15}, 02727 {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15}, 02728 {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0}, 02729 {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12}, 02730 {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12}, 02731 {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0}, 02732 {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24}, 02733 {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24}, 02734 {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30}, 02735 {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30}, 02736 }; 02737 const struct wined3d_format *format = surface->resource.format; 02738 unsigned int i; 02739 02740 TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n", 02741 color->r, color->g, color->b, color->a, debug_d3dformat(format->id)); 02742 02743 for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i) 02744 { 02745 DWORD ret; 02746 02747 if (format->id != conv[i].format_id) continue; 02748 02749 ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift; 02750 ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift; 02751 ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift; 02752 ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift; 02753 02754 TRACE("Returning 0x%08x.\n", ret); 02755 02756 return ret; 02757 } 02758 02759 if (format->id == WINED3DFMT_P8_UINT) 02760 { 02761 PALETTEENTRY *e; 02762 BYTE r, g, b, a; 02763 02764 if (!surface->palette) 02765 { 02766 WARN("Surface doesn't have a palette, returning 0.\n"); 02767 return 0; 02768 } 02769 02770 r = (BYTE)((color->r * 255.0f) + 0.5f); 02771 g = (BYTE)((color->g * 255.0f) + 0.5f); 02772 b = (BYTE)((color->b * 255.0f) + 0.5f); 02773 a = (BYTE)((color->a * 255.0f) + 0.5f); 02774 02775 e = &surface->palette->palents[a]; 02776 if (e->peRed == r && e->peGreen == g && e->peBlue == b) 02777 return a; 02778 02779 WARN("Alpha didn't match index, searching full palette.\n"); 02780 02781 for (i = 0; i < 256; ++i) 02782 { 02783 e = &surface->palette->palents[i]; 02784 if (e->peRed == r && e->peGreen == g && e->peBlue == b) 02785 return i; 02786 } 02787 02788 FIXME("Unable to convert color to palette index.\n"); 02789 02790 return 0; 02791 } 02792 02793 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id)); 02794 02795 return 0; 02796 } 02797 02798 /* DirectDraw stuff */ 02799 enum wined3d_format_id pixelformat_for_depth(DWORD depth) 02800 { 02801 switch (depth) 02802 { 02803 case 8: return WINED3DFMT_P8_UINT; 02804 case 15: return WINED3DFMT_B5G5R5X1_UNORM; 02805 case 16: return WINED3DFMT_B5G6R5_UNORM; 02806 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */ 02807 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */ 02808 default: return WINED3DFMT_UNKNOWN; 02809 } 02810 } 02811 02812 void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1, 02813 const struct wined3d_matrix *src2) 02814 { 02815 struct wined3d_matrix temp; 02816 02817 /* Now do the multiplication 'by hand'. 02818 I know that all this could be optimised, but this will be done later :-) */ 02819 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); 02820 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); 02821 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); 02822 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); 02823 02824 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); 02825 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); 02826 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); 02827 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); 02828 02829 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); 02830 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); 02831 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); 02832 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); 02833 02834 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); 02835 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); 02836 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); 02837 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); 02838 02839 /* And copy the new matrix in the good storage.. */ 02840 memcpy(dest, &temp, 16 * sizeof(float)); 02841 } 02842 02843 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) { 02844 DWORD size = 0; 02845 int i; 02846 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT; 02847 02848 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float); 02849 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD); 02850 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD); 02851 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD); 02852 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) { 02853 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break; 02854 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break; 02855 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break; 02856 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break; 02857 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break; 02858 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break; 02859 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break; 02860 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break; 02861 default: ERR("Unexpected position mask\n"); 02862 } 02863 for (i = 0; i < numTextures; i++) { 02864 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float); 02865 } 02866 02867 return size; 02868 } 02869 02870 void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_state *state, 02871 struct ffp_frag_settings *settings, BOOL ignore_textype) 02872 { 02873 #define ARG1 0x01 02874 #define ARG2 0x02 02875 #define ARG0 0x04 02876 static const unsigned char args[WINED3D_TOP_LERP + 1] = 02877 { 02878 /* undefined */ 0, 02879 /* D3DTOP_DISABLE */ 0, 02880 /* D3DTOP_SELECTARG1 */ ARG1, 02881 /* D3DTOP_SELECTARG2 */ ARG2, 02882 /* D3DTOP_MODULATE */ ARG1 | ARG2, 02883 /* D3DTOP_MODULATE2X */ ARG1 | ARG2, 02884 /* D3DTOP_MODULATE4X */ ARG1 | ARG2, 02885 /* D3DTOP_ADD */ ARG1 | ARG2, 02886 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2, 02887 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2, 02888 /* D3DTOP_SUBTRACT */ ARG1 | ARG2, 02889 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2, 02890 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2, 02891 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2, 02892 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2, 02893 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2, 02894 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2, 02895 /* D3DTOP_PREMODULATE */ ARG1 | ARG2, 02896 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2, 02897 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2, 02898 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2, 02899 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2, 02900 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2, 02901 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2, 02902 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2, 02903 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0, 02904 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0 02905 }; 02906 unsigned int i; 02907 DWORD ttff; 02908 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2; 02909 const struct wined3d_surface *rt = state->fb->render_targets[0]; 02910 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; 02911 02912 for (i = 0; i < gl_info->limits.texture_stages; ++i) 02913 { 02914 const struct wined3d_texture *texture; 02915 02916 settings->op[i].padding = 0; 02917 if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE) 02918 { 02919 settings->op[i].cop = WINED3D_TOP_DISABLE; 02920 settings->op[i].aop = WINED3D_TOP_DISABLE; 02921 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED; 02922 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED; 02923 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY; 02924 settings->op[i].dst = resultreg; 02925 settings->op[i].tex_type = tex_1d; 02926 settings->op[i].projected = proj_none; 02927 i++; 02928 break; 02929 } 02930 02931 if ((texture = state->textures[i])) 02932 { 02933 settings->op[i].color_fixup = texture->resource.format->color_fixup; 02934 if (ignore_textype) 02935 { 02936 settings->op[i].tex_type = tex_1d; 02937 } 02938 else 02939 { 02940 switch (texture->target) 02941 { 02942 case GL_TEXTURE_1D: 02943 settings->op[i].tex_type = tex_1d; 02944 break; 02945 case GL_TEXTURE_2D: 02946 settings->op[i].tex_type = tex_2d; 02947 break; 02948 case GL_TEXTURE_3D: 02949 settings->op[i].tex_type = tex_3d; 02950 break; 02951 case GL_TEXTURE_CUBE_MAP_ARB: 02952 settings->op[i].tex_type = tex_cube; 02953 break; 02954 case GL_TEXTURE_RECTANGLE_ARB: 02955 settings->op[i].tex_type = tex_rect; 02956 break; 02957 } 02958 } 02959 } else { 02960 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY; 02961 settings->op[i].tex_type = tex_1d; 02962 } 02963 02964 cop = state->texture_states[i][WINED3D_TSS_COLOR_OP]; 02965 aop = state->texture_states[i][WINED3D_TSS_ALPHA_OP]; 02966 02967 carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG1] : ARG_UNUSED; 02968 carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG2] : ARG_UNUSED; 02969 carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG0] : ARG_UNUSED; 02970 02971 if (is_invalid_op(state, i, cop, carg1, carg2, carg0)) 02972 { 02973 carg0 = ARG_UNUSED; 02974 carg2 = ARG_UNUSED; 02975 carg1 = WINED3DTA_CURRENT; 02976 cop = WINED3D_TOP_SELECT_ARG1; 02977 } 02978 02979 if (cop == WINED3D_TOP_DOTPRODUCT3) 02980 { 02981 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates 02982 * the color result to the alpha component of the destination 02983 */ 02984 aop = cop; 02985 aarg1 = carg1; 02986 aarg2 = carg2; 02987 aarg0 = carg0; 02988 } 02989 else 02990 { 02991 aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] : ARG_UNUSED; 02992 aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] : ARG_UNUSED; 02993 aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] : ARG_UNUSED; 02994 } 02995 02996 if (!i && state->textures[0] && state->render_states[WINED3D_RS_COLORKEYENABLE]) 02997 { 02998 GLenum texture_dimensions; 02999 03000 texture = state->textures[0]; 03001 texture_dimensions = texture->target; 03002 03003 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) 03004 { 03005 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]); 03006 03007 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask) 03008 { 03009 if (aop == WINED3D_TOP_DISABLE) 03010 { 03011 aarg1 = WINED3DTA_TEXTURE; 03012 aop = WINED3D_TOP_SELECT_ARG1; 03013 } 03014 else if (aop == WINED3D_TOP_SELECT_ARG1 && aarg1 != WINED3DTA_TEXTURE) 03015 { 03016 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE]) 03017 { 03018 aarg2 = WINED3DTA_TEXTURE; 03019 aop = WINED3D_TOP_MODULATE; 03020 } 03021 else aarg1 = WINED3DTA_TEXTURE; 03022 } 03023 else if (aop == WINED3D_TOP_SELECT_ARG2 && aarg2 != WINED3DTA_TEXTURE) 03024 { 03025 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE]) 03026 { 03027 aarg1 = WINED3DTA_TEXTURE; 03028 aop = WINED3D_TOP_MODULATE; 03029 } 03030 else aarg2 = WINED3DTA_TEXTURE; 03031 } 03032 } 03033 } 03034 } 03035 03036 if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0)) 03037 { 03038 aarg0 = ARG_UNUSED; 03039 aarg2 = ARG_UNUSED; 03040 aarg1 = WINED3DTA_CURRENT; 03041 aop = WINED3D_TOP_SELECT_ARG1; 03042 } 03043 03044 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE 03045 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) 03046 { 03047 ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS]; 03048 if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3)) 03049 settings->op[i].projected = proj_count3; 03050 else if (ttff & WINED3D_TTFF_PROJECTED) 03051 settings->op[i].projected = proj_count4; 03052 else 03053 settings->op[i].projected = proj_none; 03054 } 03055 else 03056 { 03057 settings->op[i].projected = proj_none; 03058 } 03059 03060 settings->op[i].cop = cop; 03061 settings->op[i].aop = aop; 03062 settings->op[i].carg0 = carg0; 03063 settings->op[i].carg1 = carg1; 03064 settings->op[i].carg2 = carg2; 03065 settings->op[i].aarg0 = aarg0; 03066 settings->op[i].aarg1 = aarg1; 03067 settings->op[i].aarg2 = aarg2; 03068 03069 if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP) 03070 settings->op[i].dst = tempreg; 03071 else 03072 settings->op[i].dst = resultreg; 03073 } 03074 03075 /* Clear unsupported stages */ 03076 for(; i < MAX_TEXTURES; i++) { 03077 memset(&settings->op[i], 0xff, sizeof(settings->op[i])); 03078 } 03079 03080 if (!state->render_states[WINED3D_RS_FOGENABLE]) 03081 { 03082 settings->fog = FOG_OFF; 03083 } 03084 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE) 03085 { 03086 if (use_vs(state) || state->vertex_declaration->position_transformed) 03087 { 03088 settings->fog = FOG_LINEAR; 03089 } 03090 else 03091 { 03092 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE]) 03093 { 03094 case WINED3D_FOG_NONE: 03095 case WINED3D_FOG_LINEAR: 03096 settings->fog = FOG_LINEAR; 03097 break; 03098 case WINED3D_FOG_EXP: 03099 settings->fog = FOG_EXP; 03100 break; 03101 case WINED3D_FOG_EXP2: 03102 settings->fog = FOG_EXP2; 03103 break; 03104 } 03105 } 03106 } 03107 else 03108 { 03109 switch (state->render_states[WINED3D_RS_FOGTABLEMODE]) 03110 { 03111 case WINED3D_FOG_LINEAR: 03112 settings->fog = FOG_LINEAR; 03113 break; 03114 case WINED3D_FOG_EXP: 03115 settings->fog = FOG_EXP; 03116 break; 03117 case WINED3D_FOG_EXP2: 03118 settings->fog = FOG_EXP2; 03119 break; 03120 } 03121 } 03122 if (state->render_states[WINED3D_RS_SRGBWRITEENABLE] 03123 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE) 03124 { 03125 settings->sRGB_write = 1; 03126 } else { 03127 settings->sRGB_write = 0; 03128 } 03129 if (device->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING] 03130 || !state->render_states[WINED3D_RS_CLIPPLANEENABLE]) 03131 { 03132 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if 03133 * the fixed function vertex pipeline is used(which always supports clipplanes), or 03134 * if no clipplane is enabled 03135 */ 03136 settings->emul_clipplanes = 0; 03137 } else { 03138 settings->emul_clipplanes = 1; 03139 } 03140 } 03141 03142 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders, 03143 const struct ffp_frag_settings *settings) 03144 { 03145 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings); 03146 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL; 03147 } 03148 03149 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc) 03150 { 03151 /* Note that the key is the implementation independent part of the ffp_frag_desc structure, 03152 * whereas desc points to an extended structure with implementation specific parts. */ 03153 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1) 03154 { 03155 ERR("Failed to insert ffp frag shader.\n"); 03156 } 03157 } 03158 03159 /* Activates the texture dimension according to the bound D3D texture. 03160 * Does not care for the colorop or correct gl texture unit(when using nvrc) 03161 * Requires the caller to activate the correct unit before 03162 */ 03163 /* GL locking is done by the caller (state handler) */ 03164 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info) 03165 { 03166 if (texture) 03167 { 03168 switch (texture->target) 03169 { 03170 case GL_TEXTURE_2D: 03171 glDisable(GL_TEXTURE_3D); 03172 checkGLcall("glDisable(GL_TEXTURE_3D)"); 03173 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) 03174 { 03175 glDisable(GL_TEXTURE_CUBE_MAP_ARB); 03176 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); 03177 } 03178 if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) 03179 { 03180 glDisable(GL_TEXTURE_RECTANGLE_ARB); 03181 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); 03182 } 03183 glEnable(GL_TEXTURE_2D); 03184 checkGLcall("glEnable(GL_TEXTURE_2D)"); 03185 break; 03186 case GL_TEXTURE_RECTANGLE_ARB: 03187 glDisable(GL_TEXTURE_2D); 03188 checkGLcall("glDisable(GL_TEXTURE_2D)"); 03189 glDisable(GL_TEXTURE_3D); 03190 checkGLcall("glDisable(GL_TEXTURE_3D)"); 03191 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) 03192 { 03193 glDisable(GL_TEXTURE_CUBE_MAP_ARB); 03194 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); 03195 } 03196 glEnable(GL_TEXTURE_RECTANGLE_ARB); 03197 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)"); 03198 break; 03199 case GL_TEXTURE_3D: 03200 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) 03201 { 03202 glDisable(GL_TEXTURE_CUBE_MAP_ARB); 03203 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); 03204 } 03205 if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) 03206 { 03207 glDisable(GL_TEXTURE_RECTANGLE_ARB); 03208 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); 03209 } 03210 glDisable(GL_TEXTURE_2D); 03211 checkGLcall("glDisable(GL_TEXTURE_2D)"); 03212 glEnable(GL_TEXTURE_3D); 03213 checkGLcall("glEnable(GL_TEXTURE_3D)"); 03214 break; 03215 case GL_TEXTURE_CUBE_MAP_ARB: 03216 glDisable(GL_TEXTURE_2D); 03217 checkGLcall("glDisable(GL_TEXTURE_2D)"); 03218 glDisable(GL_TEXTURE_3D); 03219 checkGLcall("glDisable(GL_TEXTURE_3D)"); 03220 if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) 03221 { 03222 glDisable(GL_TEXTURE_RECTANGLE_ARB); 03223 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); 03224 } 03225 glEnable(GL_TEXTURE_CUBE_MAP_ARB); 03226 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)"); 03227 break; 03228 } 03229 } else { 03230 glEnable(GL_TEXTURE_2D); 03231 checkGLcall("glEnable(GL_TEXTURE_2D)"); 03232 glDisable(GL_TEXTURE_3D); 03233 checkGLcall("glDisable(GL_TEXTURE_3D)"); 03234 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) 03235 { 03236 glDisable(GL_TEXTURE_CUBE_MAP_ARB); 03237 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); 03238 } 03239 if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) 03240 { 03241 glDisable(GL_TEXTURE_RECTANGLE_ARB); 03242 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); 03243 } 03244 /* Binding textures is done by samplers. A dummy texture will be bound */ 03245 } 03246 } 03247 03248 /* GL locking is done by the caller (state handler) */ 03249 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) 03250 { 03251 DWORD sampler = state_id - STATE_SAMPLER(0); 03252 DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler]; 03253 03254 /* No need to enable / disable anything here for unused samplers. The 03255 * tex_colorop handler takes care. Also no action is needed with pixel 03256 * shaders, or if tex_colorop will take care of this business. */ 03257 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) 03258 return; 03259 if (sampler >= state->lowest_disabled_stage) 03260 return; 03261 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP))) 03262 return; 03263 03264 texture_activate_dimensions(state->textures[sampler], context->gl_info); 03265 } 03266 03267 void *wined3d_rb_alloc(size_t size) 03268 { 03269 return HeapAlloc(GetProcessHeap(), 0, size); 03270 } 03271 03272 void *wined3d_rb_realloc(void *ptr, size_t size) 03273 { 03274 return HeapReAlloc(GetProcessHeap(), 0, ptr, size); 03275 } 03276 03277 void wined3d_rb_free(void *ptr) 03278 { 03279 HeapFree(GetProcessHeap(), 0, ptr); 03280 } 03281 03282 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry) 03283 { 03284 const struct ffp_frag_settings *ka = key; 03285 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings; 03286 03287 return memcmp(ka, kb, sizeof(*ka)); 03288 } 03289 03290 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions = 03291 { 03292 wined3d_rb_alloc, 03293 wined3d_rb_realloc, 03294 wined3d_rb_free, 03295 ffp_frag_program_key_compare, 03296 }; 03297 03298 UINT wined3d_log2i(UINT32 x) 03299 { 03300 static const UINT l[] = 03301 { 03302 ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 03303 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 03304 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 03305 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 03306 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 03307 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 03308 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 03309 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 03310 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 03311 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 03312 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 03313 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 03314 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 03315 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 03316 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 03317 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 03318 }; 03319 UINT32 i; 03320 03321 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x]; 03322 } 03323 03324 /* Set the shader type for this device, depending on the given capabilities 03325 * and the user preferences in wined3d_settings. */ 03326 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected) 03327 { 03328 BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20); 03329 03330 if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE; 03331 else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl) 03332 { 03333 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are 03334 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB 03335 * shaders only on this card. */ 03336 if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB; 03337 else *vs_selected = SHADER_GLSL; 03338 } 03339 else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB; 03340 else *vs_selected = SHADER_NONE; 03341 03342 if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE; 03343 else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL; 03344 else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB; 03345 else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI; 03346 else *ps_selected = SHADER_NONE; 03347 } 03348 03349 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op, 03350 const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format, 03351 const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format) 03352 { 03353 static const struct blit_shader * const blitters[] = 03354 { 03355 &arbfp_blit, 03356 &ffp_blit, 03357 &cpu_blit, 03358 }; 03359 unsigned int i; 03360 03361 for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i) 03362 { 03363 if (blitters[i]->blit_supported(gl_info, blit_op, 03364 src_rect, src_usage, src_pool, src_format, 03365 dst_rect, dst_usage, dst_pool, dst_format)) 03366 return blitters[i]; 03367 } 03368 03369 return NULL; 03370 } 03371 03372 void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect) 03373 { 03374 const struct wined3d_viewport *vp = &state->viewport; 03375 03376 SetRect(rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height); 03377 03378 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE]) 03379 IntersectRect(rect, rect, &state->scissor_rect); 03380 } Generated on Sat May 26 2012 04:20:45 for ReactOS by
1.7.6.1
|