1 /* 2 * Utility functions for the WineD3D Library 3 * 4 * Copyright 2002-2004 Jason Edmeades 5 * Copyright 2003-2004 Raphael Junqueira 6 * Copyright 2004 Christian Costa 7 * Copyright 2005 Oliver Stieber 8 * Copyright 2006-2008 Henri Verbeet 9 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers 10 * Copyright 2009-2010 Henri Verbeet for CodeWeavers 11 * 12 * This library is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU Lesser General Public 14 * License as published by the Free Software Foundation; either 15 * version 2.1 of the License, or (at your option) any later version. 16 * 17 * This library is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 * Lesser General Public License for more details. 21 * 22 * You should have received a copy of the GNU Lesser General Public 23 * License along with this library; if not, write to the Free Software 24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 25 */ 26 27 #include "config.h" 28 #include "wine/port.h" 29 30 #include <stdio.h> 31 32 #include "wined3d_private.h" 33 34 WINE_DEFAULT_DEBUG_CHANNEL(d3d); 35 36 #define WINED3D_FORMAT_FOURCC_BASE (WINED3DFMT_BC7_UNORM_SRGB + 1) 37 38 static const struct 39 { 40 enum wined3d_format_id id; 41 unsigned int idx; 42 } 43 format_index_remap[] = 44 { 45 {WINED3DFMT_UYVY, WINED3D_FORMAT_FOURCC_BASE}, 46 {WINED3DFMT_YUY2, WINED3D_FORMAT_FOURCC_BASE + 1}, 47 {WINED3DFMT_YV12, WINED3D_FORMAT_FOURCC_BASE + 2}, 48 {WINED3DFMT_DXT1, WINED3D_FORMAT_FOURCC_BASE + 3}, 49 {WINED3DFMT_DXT2, WINED3D_FORMAT_FOURCC_BASE + 4}, 50 {WINED3DFMT_DXT3, WINED3D_FORMAT_FOURCC_BASE + 5}, 51 {WINED3DFMT_DXT4, WINED3D_FORMAT_FOURCC_BASE + 6}, 52 {WINED3DFMT_DXT5, WINED3D_FORMAT_FOURCC_BASE + 7}, 53 {WINED3DFMT_MULTI2_ARGB8, WINED3D_FORMAT_FOURCC_BASE + 8}, 54 {WINED3DFMT_G8R8_G8B8, WINED3D_FORMAT_FOURCC_BASE + 9}, 55 {WINED3DFMT_R8G8_B8G8, WINED3D_FORMAT_FOURCC_BASE + 10}, 56 {WINED3DFMT_ATI1N, WINED3D_FORMAT_FOURCC_BASE + 11}, 57 {WINED3DFMT_ATI2N, WINED3D_FORMAT_FOURCC_BASE + 12}, 58 {WINED3DFMT_INST, WINED3D_FORMAT_FOURCC_BASE + 13}, 59 {WINED3DFMT_NVDB, WINED3D_FORMAT_FOURCC_BASE + 14}, 60 {WINED3DFMT_NVHU, WINED3D_FORMAT_FOURCC_BASE + 15}, 61 {WINED3DFMT_NVHS, WINED3D_FORMAT_FOURCC_BASE + 16}, 62 {WINED3DFMT_INTZ, WINED3D_FORMAT_FOURCC_BASE + 17}, 63 {WINED3DFMT_RESZ, WINED3D_FORMAT_FOURCC_BASE + 18}, 64 {WINED3DFMT_NULL, WINED3D_FORMAT_FOURCC_BASE + 19}, 65 {WINED3DFMT_R16, WINED3D_FORMAT_FOURCC_BASE + 20}, 66 {WINED3DFMT_AL16, WINED3D_FORMAT_FOURCC_BASE + 21}, 67 {WINED3DFMT_NV12, WINED3D_FORMAT_FOURCC_BASE + 22}, 68 }; 69 70 #define WINED3D_FORMAT_COUNT (WINED3D_FORMAT_FOURCC_BASE + ARRAY_SIZE(format_index_remap)) 71 72 struct wined3d_format_channels 73 { 74 enum wined3d_format_id id; 75 DWORD red_size, green_size, blue_size, alpha_size; 76 DWORD red_offset, green_offset, blue_offset, alpha_offset; 77 UINT bpp; 78 BYTE depth_size, stencil_size; 79 }; 80 81 static const struct wined3d_format_channels formats[] = 82 { 83 /* size offset 84 * format id r g b a r g b a bpp depth stencil */ 85 {WINED3DFMT_UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 86 /* FourCC formats */ 87 {WINED3DFMT_UYVY, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0}, 88 {WINED3DFMT_YUY2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0}, 89 {WINED3DFMT_YV12, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 90 {WINED3DFMT_NV12, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 91 {WINED3DFMT_DXT1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 92 {WINED3DFMT_DXT2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 93 {WINED3DFMT_DXT3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 94 {WINED3DFMT_DXT4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 95 {WINED3DFMT_DXT5, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 96 {WINED3DFMT_MULTI2_ARGB8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 97 {WINED3DFMT_G8R8_G8B8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 98 {WINED3DFMT_R8G8_B8G8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 99 /* Hmm? */ 100 {WINED3DFMT_R8G8_SNORM_Cx, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0}, 101 {WINED3DFMT_R11G11B10_FLOAT, 11, 11, 10, 0, 0, 11, 22, 0, 4, 0, 0}, 102 /* Palettized formats */ 103 {WINED3DFMT_P8_UINT_A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 8, 2, 0, 0}, 104 {WINED3DFMT_P8_UINT, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 105 /* Standard ARGB formats. */ 106 {WINED3DFMT_B8G8R8_UNORM, 8, 8, 8, 0, 16, 8, 0, 0, 3, 0, 0}, 107 {WINED3DFMT_B5G6R5_UNORM, 5, 6, 5, 0, 11, 5, 0, 0, 2, 0, 0}, 108 {WINED3DFMT_B5G5R5X1_UNORM, 5, 5, 5, 0, 10, 5, 0, 0, 2, 0, 0}, 109 {WINED3DFMT_B5G5R5A1_UNORM, 5, 5, 5, 1, 10, 5, 0, 15, 2, 0, 0}, 110 {WINED3DFMT_B4G4R4A4_UNORM, 4, 4, 4, 4, 8, 4, 0, 12, 2, 0, 0}, 111 {WINED3DFMT_B2G3R3_UNORM, 3, 3, 2, 0, 5, 2, 0, 0, 1, 0, 0}, 112 {WINED3DFMT_A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 0, 1, 0, 0}, 113 {WINED3DFMT_B2G3R3A8_UNORM, 3, 3, 2, 8, 5, 2, 0, 8, 2, 0, 0}, 114 {WINED3DFMT_B4G4R4X4_UNORM, 4, 4, 4, 0, 8, 4, 0, 0, 2, 0, 0}, 115 {WINED3DFMT_R8G8B8X8_UNORM, 8, 8, 8, 0, 0, 8, 16, 0, 4, 0, 0}, 116 {WINED3DFMT_B10G10R10A2_UNORM, 10, 10, 10, 2, 20, 10, 0, 30, 4, 0, 0}, 117 /* Luminance */ 118 {WINED3DFMT_L8_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 119 {WINED3DFMT_L8A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 8, 2, 0, 0}, 120 {WINED3DFMT_L4A4_UNORM, 0, 0, 0, 4, 0, 0, 0, 4, 1, 0, 0}, 121 {WINED3DFMT_L16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0}, 122 /* Bump mapping stuff */ 123 {WINED3DFMT_R5G5_SNORM_L6_UNORM, 5, 5, 0, 0, 0, 5, 0, 0, 2, 0, 0}, 124 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 8, 8, 0, 0, 0, 8, 0, 0, 4, 0, 0}, 125 {WINED3DFMT_R8G8B8A8_SNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0}, 126 {WINED3DFMT_R10G11B11_SNORM, 10, 11, 11, 0, 0, 10, 21, 0, 4, 0, 0}, 127 {WINED3DFMT_R10G10B10X2_UINT, 10, 10, 10, 0, 0, 10, 20, 0, 4, 0, 0}, 128 {WINED3DFMT_R10G10B10X2_SNORM, 10, 10, 10, 0, 0, 10, 20, 0, 4, 0, 0}, 129 {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0}, 130 /* Depth stencil formats */ 131 {WINED3DFMT_D16_LOCKABLE, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0}, 132 {WINED3DFMT_D32_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0}, 133 {WINED3DFMT_S1_UINT_D15_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 15, 1}, 134 {WINED3DFMT_X8D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 0}, 135 {WINED3DFMT_S4X4_UINT_D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 4}, 136 {WINED3DFMT_D16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0}, 137 {WINED3DFMT_D32_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0}, 138 {WINED3DFMT_S8_UINT_D24_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8}, 139 /* Vendor-specific formats */ 140 {WINED3DFMT_ATI1N, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 141 {WINED3DFMT_ATI2N, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 142 {WINED3DFMT_NVDB, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 143 {WINED3DFMT_INST, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 144 {WINED3DFMT_INTZ, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8}, 145 {WINED3DFMT_RESZ, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 146 {WINED3DFMT_NVHU, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0}, 147 {WINED3DFMT_NVHS, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0}, 148 {WINED3DFMT_NULL, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0}, 149 /* Unsure about them, could not find a Windows driver that supports them */ 150 {WINED3DFMT_R16, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0}, 151 {WINED3DFMT_AL16, 0, 0, 0, 16, 0, 0, 0, 16, 4, 0, 0}, 152 /* DirectX 10 HDR formats */ 153 {WINED3DFMT_R9G9B9E5_SHAREDEXP, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0}, 154 /* Typeless */ 155 {WINED3DFMT_R32G32B32A32_TYPELESS, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0}, 156 {WINED3DFMT_R32G32B32_TYPELESS, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0}, 157 {WINED3DFMT_R16G16B16A16_TYPELESS, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0}, 158 {WINED3DFMT_R32G32_TYPELESS, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0}, 159 {WINED3DFMT_R32G8X24_TYPELESS, 0, 0, 0, 0, 0, 0, 0, 0, 8, 32, 8}, 160 {WINED3DFMT_R10G10B10A2_TYPELESS, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0}, 161 {WINED3DFMT_R8G8B8A8_TYPELESS, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0}, 162 {WINED3DFMT_R16G16_TYPELESS, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0}, 163 {WINED3DFMT_R32_TYPELESS, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0}, 164 {WINED3DFMT_R24G8_TYPELESS, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8}, 165 {WINED3DFMT_R8G8_TYPELESS, 8, 8, 0, 0, 0, 8, 0, 0, 2, 0, 0}, 166 {WINED3DFMT_R16_TYPELESS, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0}, 167 {WINED3DFMT_R8_TYPELESS, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 168 {WINED3DFMT_BC1_TYPELESS, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 169 {WINED3DFMT_BC2_TYPELESS, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 170 {WINED3DFMT_BC3_TYPELESS, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 171 {WINED3DFMT_BC4_TYPELESS, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 172 {WINED3DFMT_BC5_TYPELESS, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 173 {WINED3DFMT_BC6H_TYPELESS, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 174 {WINED3DFMT_BC7_TYPELESS, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 175 {WINED3DFMT_B8G8R8A8_TYPELESS, 8, 8, 8, 8, 16, 8, 0, 24, 4, 0, 0}, 176 {WINED3DFMT_B8G8R8X8_TYPELESS, 8, 8, 8, 0, 16, 8, 0, 0, 4, 0, 0}, 177 }; 178 179 enum wined3d_channel_type 180 { 181 WINED3D_CHANNEL_TYPE_NONE, 182 WINED3D_CHANNEL_TYPE_UNORM, 183 WINED3D_CHANNEL_TYPE_SNORM, 184 WINED3D_CHANNEL_TYPE_UINT, 185 WINED3D_CHANNEL_TYPE_SINT, 186 WINED3D_CHANNEL_TYPE_FLOAT, 187 WINED3D_CHANNEL_TYPE_DEPTH, 188 WINED3D_CHANNEL_TYPE_STENCIL, 189 WINED3D_CHANNEL_TYPE_UNUSED, 190 }; 191 192 struct wined3d_typed_format_info 193 { 194 enum wined3d_format_id id; 195 enum wined3d_format_id typeless_id; 196 const char *channels; 197 }; 198 199 /** 200 * The last entry for a given typeless format defines its internal format. 201 * 202 * u - WINED3D_CHANNEL_TYPE_UNORM 203 * i - WINED3D_CHANNEL_TYPE_SNORM 204 * U - WINED3D_CHANNEL_TYPE_UINT 205 * I - WINED3D_CHANNEL_TYPE_SINT 206 * F - WINED3D_CHANNEL_TYPE_FLOAT 207 * D - WINED3D_CHANNEL_TYPE_DEPTH 208 * S - WINED3D_CHANNEL_TYPE_STENCIL 209 * X - WINED3D_CHANNEL_TYPE_UNUSED 210 */ 211 static const struct wined3d_typed_format_info typed_formats[] = 212 { 213 {WINED3DFMT_R32G32B32A32_UINT, WINED3DFMT_R32G32B32A32_TYPELESS, "UUUU"}, 214 {WINED3DFMT_R32G32B32A32_SINT, WINED3DFMT_R32G32B32A32_TYPELESS, "IIII"}, 215 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_R32G32B32A32_TYPELESS, "FFFF"}, 216 {WINED3DFMT_R32G32B32_UINT, WINED3DFMT_R32G32B32_TYPELESS, "UUU"}, 217 {WINED3DFMT_R32G32B32_SINT, WINED3DFMT_R32G32B32_TYPELESS, "III"}, 218 {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_R32G32B32_TYPELESS, "FFF"}, 219 {WINED3DFMT_R16G16B16A16_UNORM, WINED3DFMT_R16G16B16A16_TYPELESS, "uuuu"}, 220 {WINED3DFMT_R16G16B16A16_SNORM, WINED3DFMT_R16G16B16A16_TYPELESS, "iiii"}, 221 {WINED3DFMT_R16G16B16A16_UINT, WINED3DFMT_R16G16B16A16_TYPELESS, "UUUU"}, 222 {WINED3DFMT_R16G16B16A16_SINT, WINED3DFMT_R16G16B16A16_TYPELESS, "IIII"}, 223 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_R16G16B16A16_TYPELESS, "FFFF"}, 224 {WINED3DFMT_R32G32_UINT, WINED3DFMT_R32G32_TYPELESS, "UU"}, 225 {WINED3DFMT_R32G32_SINT, WINED3DFMT_R32G32_TYPELESS, "II"}, 226 {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_R32G32_TYPELESS, "FF"}, 227 {WINED3DFMT_R32_FLOAT_X8X24_TYPELESS, WINED3DFMT_R32G8X24_TYPELESS, "DX"}, 228 {WINED3DFMT_X32_TYPELESS_G8X24_UINT, WINED3DFMT_R32G8X24_TYPELESS, "XS"}, 229 {WINED3DFMT_D32_FLOAT_S8X24_UINT, WINED3DFMT_R32G8X24_TYPELESS, "DS"}, 230 {WINED3DFMT_R10G10B10A2_SNORM, WINED3DFMT_R10G10B10A2_TYPELESS, "iiii"}, 231 {WINED3DFMT_R10G10B10A2_UINT, WINED3DFMT_R10G10B10A2_TYPELESS, "UUUU"}, 232 {WINED3DFMT_R10G10B10A2_UNORM, WINED3DFMT_R10G10B10A2_TYPELESS, "uuuu"}, 233 {WINED3DFMT_R8G8B8A8_UINT, WINED3DFMT_R8G8B8A8_TYPELESS, "UUUU"}, 234 {WINED3DFMT_R8G8B8A8_SINT, WINED3DFMT_R8G8B8A8_TYPELESS, "IIII"}, 235 {WINED3DFMT_R8G8B8A8_SNORM, WINED3DFMT_R8G8B8A8_TYPELESS, "iiii"}, 236 {WINED3DFMT_R8G8B8A8_UNORM_SRGB, WINED3DFMT_R8G8B8A8_TYPELESS, "uuuu"}, 237 {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_R8G8B8A8_TYPELESS, "uuuu"}, 238 {WINED3DFMT_R16G16_UNORM, WINED3DFMT_R16G16_TYPELESS, "uu"}, 239 {WINED3DFMT_R16G16_SNORM, WINED3DFMT_R16G16_TYPELESS, "ii"}, 240 {WINED3DFMT_R16G16_UINT, WINED3DFMT_R16G16_TYPELESS, "UU"}, 241 {WINED3DFMT_R16G16_SINT, WINED3DFMT_R16G16_TYPELESS, "II"}, 242 {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_R16G16_TYPELESS, "FF"}, 243 {WINED3DFMT_D32_FLOAT, WINED3DFMT_R32_TYPELESS, "D"}, 244 {WINED3DFMT_R32_FLOAT, WINED3DFMT_R32_TYPELESS, "F"}, 245 {WINED3DFMT_R32_UINT, WINED3DFMT_R32_TYPELESS, "U"}, 246 {WINED3DFMT_R32_SINT, WINED3DFMT_R32_TYPELESS, "I"}, 247 {WINED3DFMT_R24_UNORM_X8_TYPELESS, WINED3DFMT_R24G8_TYPELESS, "DX"}, 248 {WINED3DFMT_X24_TYPELESS_G8_UINT, WINED3DFMT_R24G8_TYPELESS, "XS"}, 249 {WINED3DFMT_D24_UNORM_S8_UINT, WINED3DFMT_R24G8_TYPELESS, "DS"}, 250 {WINED3DFMT_R8G8_SNORM, WINED3DFMT_R8G8_TYPELESS, "ii"}, 251 {WINED3DFMT_R8G8_UNORM, WINED3DFMT_R8G8_TYPELESS, "uu"}, 252 {WINED3DFMT_R8G8_UINT, WINED3DFMT_R8G8_TYPELESS, "UU"}, 253 {WINED3DFMT_R8G8_SINT, WINED3DFMT_R8G8_TYPELESS, "II"}, 254 {WINED3DFMT_D16_UNORM, WINED3DFMT_R16_TYPELESS, "D"}, 255 {WINED3DFMT_R16_UNORM, WINED3DFMT_R16_TYPELESS, "u"}, 256 {WINED3DFMT_R16_SNORM, WINED3DFMT_R16_TYPELESS, "i"}, 257 {WINED3DFMT_R16_UINT, WINED3DFMT_R16_TYPELESS, "U"}, 258 {WINED3DFMT_R16_SINT, WINED3DFMT_R16_TYPELESS, "I"}, 259 {WINED3DFMT_R16_FLOAT, WINED3DFMT_R16_TYPELESS, "F"}, 260 {WINED3DFMT_R8_UNORM, WINED3DFMT_R8_TYPELESS, "u"}, 261 {WINED3DFMT_R8_SNORM, WINED3DFMT_R8_TYPELESS, "i"}, 262 {WINED3DFMT_R8_UINT, WINED3DFMT_R8_TYPELESS, "U"}, 263 {WINED3DFMT_R8_SINT, WINED3DFMT_R8_TYPELESS, "I"}, 264 {WINED3DFMT_BC1_UNORM_SRGB, WINED3DFMT_BC1_TYPELESS, ""}, 265 {WINED3DFMT_BC1_UNORM, WINED3DFMT_BC1_TYPELESS, ""}, 266 {WINED3DFMT_BC2_UNORM_SRGB, WINED3DFMT_BC2_TYPELESS, ""}, 267 {WINED3DFMT_BC2_UNORM, WINED3DFMT_BC2_TYPELESS, ""}, 268 {WINED3DFMT_BC3_UNORM_SRGB, WINED3DFMT_BC3_TYPELESS, ""}, 269 {WINED3DFMT_BC3_UNORM, WINED3DFMT_BC3_TYPELESS, ""}, 270 {WINED3DFMT_BC4_UNORM, WINED3DFMT_BC4_TYPELESS, ""}, 271 {WINED3DFMT_BC4_SNORM, WINED3DFMT_BC4_TYPELESS, ""}, 272 {WINED3DFMT_BC5_UNORM, WINED3DFMT_BC5_TYPELESS, ""}, 273 {WINED3DFMT_BC5_SNORM, WINED3DFMT_BC5_TYPELESS, ""}, 274 {WINED3DFMT_BC6H_UF16, WINED3DFMT_BC6H_TYPELESS, ""}, 275 {WINED3DFMT_BC6H_SF16, WINED3DFMT_BC6H_TYPELESS, ""}, 276 {WINED3DFMT_BC7_UNORM_SRGB, WINED3DFMT_BC7_TYPELESS, ""}, 277 {WINED3DFMT_BC7_UNORM, WINED3DFMT_BC7_TYPELESS, ""}, 278 {WINED3DFMT_B8G8R8A8_UNORM_SRGB, WINED3DFMT_B8G8R8A8_TYPELESS, "uuuu"}, 279 {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_B8G8R8A8_TYPELESS, "uuuu"}, 280 {WINED3DFMT_B8G8R8X8_UNORM_SRGB, WINED3DFMT_B8G8R8X8_TYPELESS, "uuuX"}, 281 {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_B8G8R8X8_TYPELESS, "uuuX"}, 282 }; 283 284 struct wined3d_typeless_format_depth_stencil_info 285 { 286 enum wined3d_format_id typeless_id; 287 enum wined3d_format_id depth_stencil_id; 288 enum wined3d_format_id depth_view_id; 289 enum wined3d_format_id stencil_view_id; 290 BOOL separate_depth_view_format; 291 }; 292 293 static const struct wined3d_typeless_format_depth_stencil_info typeless_depth_stencil_formats[] = 294 { 295 {WINED3DFMT_R32G8X24_TYPELESS, WINED3DFMT_D32_FLOAT_S8X24_UINT, 296 WINED3DFMT_R32_FLOAT_X8X24_TYPELESS, WINED3DFMT_X32_TYPELESS_G8X24_UINT, TRUE}, 297 {WINED3DFMT_R24G8_TYPELESS, WINED3DFMT_D24_UNORM_S8_UINT, 298 WINED3DFMT_R24_UNORM_X8_TYPELESS, WINED3DFMT_X24_TYPELESS_G8_UINT, TRUE}, 299 {WINED3DFMT_R32_TYPELESS, WINED3DFMT_D32_FLOAT, WINED3DFMT_R32_FLOAT}, 300 {WINED3DFMT_R16_TYPELESS, WINED3DFMT_D16_UNORM, WINED3DFMT_R16_UNORM}, 301 }; 302 303 struct wined3d_format_ddi_info 304 { 305 enum wined3d_format_id id; 306 D3DDDIFORMAT ddi_format; 307 }; 308 309 static const struct wined3d_format_ddi_info ddi_formats[] = 310 { 311 {WINED3DFMT_B8G8R8_UNORM, D3DDDIFMT_R8G8B8}, 312 {WINED3DFMT_B8G8R8A8_UNORM, D3DDDIFMT_A8R8G8B8}, 313 {WINED3DFMT_B8G8R8X8_UNORM, D3DDDIFMT_X8R8G8B8}, 314 {WINED3DFMT_B5G6R5_UNORM, D3DDDIFMT_R5G6B5}, 315 {WINED3DFMT_B5G5R5X1_UNORM, D3DDDIFMT_X1R5G5B5}, 316 {WINED3DFMT_B5G5R5A1_UNORM, D3DDDIFMT_A1R5G5B5}, 317 {WINED3DFMT_B4G4R4A4_UNORM, D3DDDIFMT_A4R4G4B4}, 318 {WINED3DFMT_B4G4R4X4_UNORM, D3DDDIFMT_X4R4G4B4}, 319 {WINED3DFMT_P8_UINT, D3DDDIFMT_P8}, 320 }; 321 322 struct wined3d_format_base_flags 323 { 324 enum wined3d_format_id id; 325 DWORD flags; 326 }; 327 328 /* The ATI2N format behaves like an uncompressed format in LockRect(), but 329 * still needs to use the correct block based calculation for e.g. the 330 * resource size. */ 331 static const struct wined3d_format_base_flags format_base_flags[] = 332 { 333 {WINED3DFMT_ATI1N, WINED3DFMT_FLAG_BROKEN_PITCH}, 334 {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_BROKEN_PITCH}, 335 {WINED3DFMT_R11G11B10_FLOAT, WINED3DFMT_FLAG_FLOAT}, 336 {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT}, 337 {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT}, 338 {WINED3DFMT_D32_FLOAT_S8X24_UINT, WINED3DFMT_FLAG_FLOAT}, 339 {WINED3DFMT_INST, WINED3DFMT_FLAG_EXTENSION}, 340 {WINED3DFMT_NULL, WINED3DFMT_FLAG_EXTENSION}, 341 {WINED3DFMT_NVDB, WINED3DFMT_FLAG_EXTENSION}, 342 {WINED3DFMT_RESZ, WINED3DFMT_FLAG_EXTENSION}, 343 }; 344 345 struct wined3d_format_block_info 346 { 347 enum wined3d_format_id id; 348 UINT block_width; 349 UINT block_height; 350 UINT block_byte_count; 351 BOOL verify; 352 }; 353 354 static const struct wined3d_format_block_info format_block_info[] = 355 { 356 {WINED3DFMT_DXT1, 4, 4, 8, TRUE}, 357 {WINED3DFMT_DXT2, 4, 4, 16, TRUE}, 358 {WINED3DFMT_DXT3, 4, 4, 16, TRUE}, 359 {WINED3DFMT_DXT4, 4, 4, 16, TRUE}, 360 {WINED3DFMT_DXT5, 4, 4, 16, TRUE}, 361 {WINED3DFMT_BC1_UNORM, 4, 4, 8, TRUE}, 362 {WINED3DFMT_BC2_UNORM, 4, 4, 16, TRUE}, 363 {WINED3DFMT_BC3_UNORM, 4, 4, 16, TRUE}, 364 {WINED3DFMT_BC4_UNORM, 4, 4, 8, TRUE}, 365 {WINED3DFMT_BC4_SNORM, 4, 4, 8, TRUE}, 366 {WINED3DFMT_BC5_UNORM, 4, 4, 16, TRUE}, 367 {WINED3DFMT_BC5_SNORM, 4, 4, 16, TRUE}, 368 {WINED3DFMT_BC6H_UF16, 4, 4, 16, TRUE}, 369 {WINED3DFMT_BC6H_SF16, 4, 4, 16, TRUE}, 370 {WINED3DFMT_BC7_UNORM, 4, 4, 16, TRUE}, 371 {WINED3DFMT_ATI1N, 4, 4, 8, FALSE}, 372 {WINED3DFMT_ATI2N, 4, 4, 16, FALSE}, 373 {WINED3DFMT_YUY2, 2, 1, 4, FALSE}, 374 {WINED3DFMT_UYVY, 2, 1, 4, FALSE}, 375 }; 376 377 struct wined3d_format_vertex_info 378 { 379 enum wined3d_format_id id; 380 enum wined3d_ffp_emit_idx emit_idx; 381 unsigned int component_count; 382 GLenum gl_vtx_type; 383 GLboolean gl_normalized; 384 enum wined3d_gl_extension extension; 385 }; 386 387 static const struct wined3d_format_vertex_info format_vertex_info[] = 388 { 389 {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, GL_FALSE}, 390 {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, GL_FALSE}, 391 {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, GL_FALSE}, 392 {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, GL_FALSE}, 393 {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE }, 394 {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, GL_FALSE}, 395 {WINED3DFMT_R16G16_UINT, WINED3D_FFP_EMIT_INVALID, 2, GL_UNSIGNED_SHORT, GL_FALSE}, 396 {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, GL_FALSE}, 397 {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, GL_FALSE}, 398 {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, GL_TRUE }, 399 {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, GL_TRUE }, 400 {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, GL_TRUE }, 401 {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, GL_TRUE }, 402 {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, GL_TRUE }, 403 {WINED3DFMT_R10G10B10X2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, GL_FALSE}, 404 {WINED3DFMT_R10G10B10X2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, GL_TRUE }, 405 {WINED3DFMT_R10G10B10A2_UNORM, WINED3D_FFP_EMIT_INVALID, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 406 ARB_VERTEX_TYPE_2_10_10_10_REV}, 407 {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_HALF_FLOAT, GL_FALSE}, 408 {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_HALF_FLOAT, GL_FALSE}, 409 {WINED3DFMT_R8G8B8A8_SNORM, WINED3D_FFP_EMIT_INVALID, 4, GL_BYTE, GL_TRUE }, 410 {WINED3DFMT_R8G8B8A8_SINT, WINED3D_FFP_EMIT_INVALID, 4, GL_BYTE, GL_FALSE}, 411 {WINED3DFMT_R16G16B16A16_UINT, WINED3D_FFP_EMIT_INVALID, 4, GL_UNSIGNED_SHORT, GL_FALSE}, 412 {WINED3DFMT_R8_UNORM, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_BYTE, GL_TRUE}, 413 {WINED3DFMT_R8_UINT, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_BYTE, GL_FALSE}, 414 {WINED3DFMT_R8_SINT, WINED3D_FFP_EMIT_INVALID, 1, GL_BYTE, GL_FALSE}, 415 {WINED3DFMT_R16_UINT, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_SHORT, GL_FALSE}, 416 {WINED3DFMT_R16_SINT, WINED3D_FFP_EMIT_INVALID, 1, GL_SHORT, GL_FALSE}, 417 {WINED3DFMT_R32_UINT, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_INT, GL_FALSE}, 418 {WINED3DFMT_R32_SINT, WINED3D_FFP_EMIT_INVALID, 1, GL_INT, GL_FALSE}, 419 {WINED3DFMT_R32G32_UINT, WINED3D_FFP_EMIT_INVALID, 2, GL_UNSIGNED_INT, GL_FALSE}, 420 {WINED3DFMT_R32G32_SINT, WINED3D_FFP_EMIT_INVALID, 2, GL_INT, GL_FALSE}, 421 {WINED3DFMT_R32G32B32_UINT, WINED3D_FFP_EMIT_INVALID, 3, GL_UNSIGNED_INT, GL_FALSE}, 422 {WINED3DFMT_R32G32B32A32_UINT, WINED3D_FFP_EMIT_INVALID, 4, GL_UNSIGNED_INT, GL_FALSE}, 423 {WINED3DFMT_R32G32B32A32_SINT, WINED3D_FFP_EMIT_INVALID, 4, GL_INT, GL_FALSE}, 424 }; 425 426 struct wined3d_format_texture_info 427 { 428 enum wined3d_format_id id; 429 GLint gl_internal; 430 GLint gl_srgb_internal; 431 GLint gl_rt_internal; 432 GLint gl_format; 433 GLint gl_type; 434 unsigned int conv_byte_count; 435 unsigned int flags; 436 enum wined3d_gl_extension extension; 437 void (*upload)(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, unsigned int src_slice_pitch, 438 unsigned int dst_row_pitch, unsigned int dst_slice_pitch, 439 unsigned int width, unsigned int height, unsigned int depth); 440 void (*download)(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, unsigned int src_slice_pitch, 441 unsigned int dst_row_pitch, unsigned int dst_slice_pitch, 442 unsigned int width, unsigned int height, unsigned int depth); 443 }; 444 445 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, 446 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) 447 { 448 /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not 449 * format+type combination to load it. Thus convert it to A8L8, then load it 450 * with A4L4 internal, but A8L8 format+type 451 */ 452 unsigned int x, y, z; 453 const unsigned char *Source; 454 unsigned char *Dest; 455 456 for (z = 0; z < depth; z++) 457 { 458 for (y = 0; y < height; y++) 459 { 460 Source = src + z * src_slice_pitch + y * src_row_pitch; 461 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch; 462 for (x = 0; x < width; x++ ) 463 { 464 unsigned char color = (*Source++); 465 /* A */ Dest[1] = (color & 0xf0u) << 0; 466 /* L */ Dest[0] = (color & 0x0fu) << 4; 467 Dest += 2; 468 } 469 } 470 } 471 } 472 473 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, 474 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) 475 { 476 unsigned int x, y, z; 477 unsigned char r_in, g_in, l_in; 478 const unsigned short *texel_in; 479 unsigned short *texel_out; 480 481 /* Emulating signed 5 bit values with unsigned 5 bit values has some precision problems by design: 482 * E.g. the signed input value 0 becomes 16. GL normalizes it to 16 / 31 = 0.516. We convert it 483 * back to a signed value by subtracting 0.5 and multiplying by 2.0. The resulting value is 484 * ((16 / 31) - 0.5) * 2.0 = 0.032, which is quite different from the intended result 0.000. */ 485 for (z = 0; z < depth; z++) 486 { 487 for (y = 0; y < height; y++) 488 { 489 texel_out = (unsigned short *) (dst + z * dst_slice_pitch + y * dst_row_pitch); 490 texel_in = (const unsigned short *)(src + z * src_slice_pitch + y * src_row_pitch); 491 for (x = 0; x < width; x++ ) 492 { 493 l_in = (*texel_in & 0xfc00u) >> 10; 494 g_in = (*texel_in & 0x03e0u) >> 5; 495 r_in = *texel_in & 0x001fu; 496 497 *texel_out = ((r_in + 16) << 11) | (l_in << 5) | (g_in + 16); 498 texel_out++; 499 texel_in++; 500 } 501 } 502 } 503 } 504 505 static void convert_r5g5_snorm_l6_unorm_ext(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, 506 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) 507 { 508 unsigned int x, y, z; 509 unsigned char *texel_out, r_out, g_out, r_in, g_in, l_in; 510 const unsigned short *texel_in; 511 512 for (z = 0; z < depth; z++) 513 { 514 for (y = 0; y < height; y++) 515 { 516 texel_in = (const unsigned short *)(src + z * src_slice_pitch + y * src_row_pitch); 517 texel_out = dst + z * dst_slice_pitch + y * dst_row_pitch; 518 for (x = 0; x < width; x++ ) 519 { 520 l_in = (*texel_in & 0xfc00u) >> 10; 521 g_in = (*texel_in & 0x03e0u) >> 5; 522 r_in = *texel_in & 0x001fu; 523 524 r_out = r_in << 3; 525 if (!(r_in & 0x10)) /* r > 0 */ 526 r_out |= r_in >> 1; 527 528 g_out = g_in << 3; 529 if (!(g_in & 0x10)) /* g > 0 */ 530 g_out |= g_in >> 1; 531 532 texel_out[0] = r_out; 533 texel_out[1] = g_out; 534 texel_out[2] = l_in << 1 | l_in >> 5; 535 texel_out[3] = 0; 536 537 texel_out += 4; 538 texel_in++; 539 } 540 } 541 } 542 } 543 544 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, 545 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) 546 { 547 unsigned int x, y, z; 548 unsigned char *texel_out, ds_out, dt_out, r_in, g_in, l_in; 549 const unsigned short *texel_in; 550 551 /* This makes the gl surface bigger(24 bit instead of 16), but it works with 552 * fixed function and shaders without further conversion once the surface is 553 * loaded. 554 * 555 * The difference between this function and convert_r5g5_snorm_l6_unorm_ext 556 * is that convert_r5g5_snorm_l6_unorm_ext creates a 32 bit XRGB texture and 557 * this function creates a 24 bit DSDT_MAG texture. Trying to load a DSDT_MAG 558 * internal with a 32 bit DSDT_MAG_INTENSITY or DSDT_MAG_VIB format fails. */ 559 for (z = 0; z < depth; z++) 560 { 561 for (y = 0; y < height; y++) 562 { 563 texel_in = (const unsigned short *)(src + z * src_slice_pitch + y * src_row_pitch); 564 texel_out = dst + z * dst_slice_pitch + y * dst_row_pitch; 565 for (x = 0; x < width; x++ ) 566 { 567 l_in = (*texel_in & 0xfc00u) >> 10; 568 g_in = (*texel_in & 0x03e0u) >> 5; 569 r_in = *texel_in & 0x001fu; 570 571 ds_out = r_in << 3; 572 if (!(r_in & 0x10)) /* r > 0 */ 573 ds_out |= r_in >> 1; 574 575 dt_out = g_in << 3; 576 if (!(g_in & 0x10)) /* g > 0 */ 577 dt_out |= g_in >> 1; 578 579 texel_out[0] = ds_out; 580 texel_out[1] = dt_out; 581 texel_out[2] = l_in << 1 | l_in >> 5; 582 583 texel_out += 3; 584 texel_in++; 585 } 586 } 587 } 588 } 589 590 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, 591 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) 592 { 593 unsigned int x, y, z; 594 const short *Source; 595 unsigned char *Dest; 596 597 for (z = 0; z < depth; z++) 598 { 599 for (y = 0; y < height; y++) 600 { 601 Source = (const short *)(src + z * src_slice_pitch + y * src_row_pitch); 602 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch; 603 for (x = 0; x < width; x++ ) 604 { 605 const short color = (*Source++); 606 /* B */ Dest[0] = 0xff; 607 /* G */ Dest[1] = (color >> 8) + 128; /* V */ 608 /* R */ Dest[2] = (color & 0xff) + 128; /* U */ 609 Dest += 3; 610 } 611 } 612 } 613 } 614 615 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, 616 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) 617 { 618 unsigned int x, y, z; 619 const DWORD *Source; 620 unsigned char *Dest; 621 622 /* Doesn't work correctly with the fixed function pipeline, but can work in 623 * shaders if the shader is adjusted. (There's no use for this format in gl's 624 * standard fixed function pipeline anyway). 625 */ 626 for (z = 0; z < depth; z++) 627 { 628 for (y = 0; y < height; y++) 629 { 630 Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch); 631 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch; 632 for (x = 0; x < width; x++ ) 633 { 634 LONG color = (*Source++); 635 /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */ 636 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ 637 /* R */ Dest[2] = (color & 0xff) + 128; /* U */ 638 Dest += 4; 639 } 640 } 641 } 642 } 643 644 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, 645 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) 646 { 647 unsigned int x, y, z; 648 const DWORD *Source; 649 unsigned char *Dest; 650 651 /* This implementation works with the fixed function pipeline and shaders 652 * without further modification after converting the surface. 653 */ 654 for (z = 0; z < depth; z++) 655 { 656 for (y = 0; y < height; y++) 657 { 658 Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch); 659 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch; 660 for (x = 0; x < width; x++ ) 661 { 662 LONG color = (*Source++); 663 /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */ 664 /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */ 665 /* U */ Dest[0] = (color & 0xff); /* U */ 666 /* I */ Dest[3] = 255; /* X */ 667 Dest += 4; 668 } 669 } 670 } 671 } 672 673 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, 674 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) 675 { 676 unsigned int x, y, z; 677 const DWORD *Source; 678 unsigned char *Dest; 679 680 for (z = 0; z < depth; z++) 681 { 682 for (y = 0; y < height; y++) 683 { 684 Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch); 685 Dest = dst + z * dst_slice_pitch + y * dst_row_pitch; 686 for (x = 0; x < width; x++ ) 687 { 688 LONG color = (*Source++); 689 /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */ 690 /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ 691 /* R */ Dest[2] = (color & 0xff) + 128; /* U */ 692 /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */ 693 Dest += 4; 694 } 695 } 696 } 697 } 698 699 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, 700 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) 701 { 702 unsigned int x, y, z; 703 const DWORD *Source; 704 unsigned short *Dest; 705 706 for (z = 0; z < depth; z++) 707 { 708 for (y = 0; y < height; y++) 709 { 710 Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch); 711 Dest = (unsigned short *) (dst + z * dst_slice_pitch + y * dst_row_pitch); 712 for (x = 0; x < width; x++ ) 713 { 714 const DWORD color = (*Source++); 715 /* B */ Dest[0] = 0xffff; 716 /* G */ Dest[1] = (color >> 16) + 32768; /* V */ 717 /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */ 718 Dest += 3; 719 } 720 } 721 } 722 } 723 724 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, 725 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) 726 { 727 unsigned int x, y, z; 728 const WORD *Source; 729 WORD *Dest; 730 731 for (z = 0; z < depth; z++) 732 { 733 for (y = 0; y < height; y++) 734 { 735 Source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch); 736 Dest = (WORD *) (dst + z * dst_slice_pitch + y * dst_row_pitch); 737 for (x = 0; x < width; x++ ) 738 { 739 WORD green = (*Source++); 740 WORD red = (*Source++); 741 Dest[0] = green; 742 Dest[1] = red; 743 /* Strictly speaking not correct for R16G16F, but it doesn't matter because the 744 * shader overwrites it anyway */ 745 Dest[2] = 0xffff; 746 Dest += 3; 747 } 748 } 749 } 750 } 751 752 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, 753 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) 754 { 755 unsigned int x, y, z; 756 const float *Source; 757 float *Dest; 758 759 for (z = 0; z < depth; z++) 760 { 761 for (y = 0; y < height; y++) 762 { 763 Source = (const float *)(src + z * src_slice_pitch + y * src_row_pitch); 764 Dest = (float *) (dst + z * dst_slice_pitch + y * dst_row_pitch); 765 for (x = 0; x < width; x++ ) 766 { 767 float green = (*Source++); 768 float red = (*Source++); 769 Dest[0] = green; 770 Dest[1] = red; 771 Dest[2] = 1.0f; 772 Dest += 3; 773 } 774 } 775 } 776 } 777 778 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, 779 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) 780 { 781 unsigned int x, y, z; 782 783 for (z = 0; z < depth; z++) 784 { 785 for (y = 0; y < height; ++y) 786 { 787 const WORD *source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch); 788 DWORD *dest = (DWORD *)(dst + z * dst_slice_pitch + y * dst_row_pitch); 789 790 for (x = 0; x < width; ++x) 791 { 792 /* The depth data is normalized, so needs to be scaled, 793 * the stencil data isn't. Scale depth data by 794 * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */ 795 WORD d15 = source[x] >> 1; 796 DWORD d24 = (d15 << 9) + (d15 >> 6); 797 dest[x] = (d24 << 8) | (source[x] & 0x1); 798 } 799 } 800 } 801 } 802 803 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, 804 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) 805 { 806 unsigned int x, y, z; 807 808 for (z = 0; z < depth; z++) 809 { 810 for (y = 0; y < height; ++y) 811 { 812 const DWORD *source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch); 813 DWORD *dest = (DWORD *)(dst + z * dst_slice_pitch + y * dst_row_pitch); 814 815 for (x = 0; x < width; ++x) 816 { 817 /* Just need to clear out the X4 part. */ 818 dest[x] = source[x] & ~0xf0; 819 } 820 } 821 } 822 } 823 824 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, 825 UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) 826 { 827 unsigned int x, y, z; 828 829 for (z = 0; z < depth; z++) 830 { 831 for (y = 0; y < height; ++y) 832 { 833 const DWORD *source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch); 834 float *dest_f = (float *)(dst + z * dst_slice_pitch + y * dst_row_pitch); 835 DWORD *dest_s = (DWORD *)dest_f; 836 837 for (x = 0; x < width; ++x) 838 { 839 dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00u) >> 8); 840 dest_s[x * 2 + 1] = source[x] & 0xff; 841 } 842 } 843 } 844 } 845 846 static void x8_d24_unorm_upload(const BYTE *src, BYTE *dst, 847 unsigned int src_row_pitch, unsigned int src_slice_pitch, 848 unsigned int dst_row_pitch, unsigned int dst_slice_pitch, 849 unsigned int width, unsigned int height, unsigned int depth) 850 { 851 unsigned int x, y, z; 852 853 for (z = 0; z < depth; ++z) 854 { 855 for (y = 0; y < height; ++y) 856 { 857 const DWORD *source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch); 858 DWORD *dest = (DWORD *)(dst + z * dst_slice_pitch + y * dst_row_pitch); 859 860 for (x = 0; x < width; ++x) 861 { 862 dest[x] = source[x] << 8 | ((source[x] >> 16) & 0xff); 863 } 864 } 865 } 866 } 867 868 static void x8_d24_unorm_download(const BYTE *src, BYTE *dst, 869 unsigned int src_row_pitch, unsigned int src_slice_pitch, 870 unsigned int dst_row_pitch, unsigned int dst_slice_pitch, 871 unsigned int width, unsigned int height, unsigned int depth) 872 { 873 unsigned int x, y, z; 874 875 for (z = 0; z < depth; ++z) 876 { 877 for (y = 0; y < height; ++y) 878 { 879 const DWORD *source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch); 880 DWORD *dest = (DWORD *)(dst + z * dst_slice_pitch + y * dst_row_pitch); 881 882 for (x = 0; x < width; ++x) 883 { 884 dest[x] = source[x] >> 8; 885 } 886 } 887 } 888 } 889 890 static BOOL color_in_range(const struct wined3d_color_key *color_key, DWORD color) 891 { 892 /* FIXME: Is this really how color keys are supposed to work? I think it 893 * makes more sense to compare the individual channels. */ 894 return color >= color_key->color_space_low_value 895 && color <= color_key->color_space_high_value; 896 } 897 898 static void convert_p8_uint_b8g8r8a8_unorm(const BYTE *src, unsigned int src_pitch, 899 BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height, 900 const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) 901 { 902 const BYTE *src_row; 903 unsigned int x, y; 904 DWORD *dst_row; 905 906 if (!palette) 907 { 908 /* FIXME: This should probably use the system palette. */ 909 FIXME("P8 surface loaded without a palette.\n"); 910 911 for (y = 0; y < height; ++y) 912 { 913 memset(&dst[dst_pitch * y], 0, width * 4); 914 } 915 916 return; 917 } 918 919 for (y = 0; y < height; ++y) 920 { 921 src_row = &src[src_pitch * y]; 922 dst_row = (DWORD *)&dst[dst_pitch * y]; 923 for (x = 0; x < width; ++x) 924 { 925 BYTE src_color = src_row[x]; 926 dst_row[x] = 0xff000000 927 | (palette->colors[src_color].rgbRed << 16) 928 | (palette->colors[src_color].rgbGreen << 8) 929 | palette->colors[src_color].rgbBlue; 930 } 931 } 932 } 933 934 static void convert_b5g6r5_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, unsigned int src_pitch, 935 BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height, 936 const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) 937 { 938 const WORD *src_row; 939 unsigned int x, y; 940 WORD *dst_row; 941 942 for (y = 0; y < height; ++y) 943 { 944 src_row = (WORD *)&src[src_pitch * y]; 945 dst_row = (WORD *)&dst[dst_pitch * y]; 946 for (x = 0; x < width; ++x) 947 { 948 WORD src_color = src_row[x]; 949 if (!color_in_range(color_key, src_color)) 950 dst_row[x] = 0x8000u | ((src_color & 0xffc0u) >> 1) | (src_color & 0x1fu); 951 else 952 dst_row[x] = ((src_color & 0xffc0u) >> 1) | (src_color & 0x1fu); 953 } 954 } 955 } 956 957 static void convert_b5g5r5x1_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, unsigned int src_pitch, 958 BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height, 959 const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) 960 { 961 const WORD *src_row; 962 unsigned int x, y; 963 WORD *dst_row; 964 965 for (y = 0; y < height; ++y) 966 { 967 src_row = (WORD *)&src[src_pitch * y]; 968 dst_row = (WORD *)&dst[dst_pitch * y]; 969 for (x = 0; x < width; ++x) 970 { 971 WORD src_color = src_row[x]; 972 if (color_in_range(color_key, src_color)) 973 dst_row[x] = src_color & ~0x8000; 974 else 975 dst_row[x] = src_color | 0x8000; 976 } 977 } 978 } 979 980 static void convert_b8g8r8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch, 981 BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height, 982 const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) 983 { 984 const BYTE *src_row; 985 unsigned int x, y; 986 DWORD *dst_row; 987 988 for (y = 0; y < height; ++y) 989 { 990 src_row = &src[src_pitch * y]; 991 dst_row = (DWORD *)&dst[dst_pitch * y]; 992 for (x = 0; x < width; ++x) 993 { 994 DWORD src_color = (src_row[x * 3 + 2] << 16) | (src_row[x * 3 + 1] << 8) | src_row[x * 3]; 995 if (!color_in_range(color_key, src_color)) 996 dst_row[x] = src_color | 0xff000000; 997 } 998 } 999 } 1000 1001 static void convert_b8g8r8x8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch, 1002 BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height, 1003 const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) 1004 { 1005 const DWORD *src_row; 1006 unsigned int x, y; 1007 DWORD *dst_row; 1008 1009 for (y = 0; y < height; ++y) 1010 { 1011 src_row = (DWORD *)&src[src_pitch * y]; 1012 dst_row = (DWORD *)&dst[dst_pitch * y]; 1013 for (x = 0; x < width; ++x) 1014 { 1015 DWORD src_color = src_row[x]; 1016 if (color_in_range(color_key, src_color)) 1017 dst_row[x] = src_color & ~0xff000000; 1018 else 1019 dst_row[x] = src_color | 0xff000000; 1020 } 1021 } 1022 } 1023 1024 static void convert_b8g8r8a8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch, 1025 BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height, 1026 const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) 1027 { 1028 const DWORD *src_row; 1029 unsigned int x, y; 1030 DWORD *dst_row; 1031 1032 for (y = 0; y < height; ++y) 1033 { 1034 src_row = (DWORD *)&src[src_pitch * y]; 1035 dst_row = (DWORD *)&dst[dst_pitch * y]; 1036 for (x = 0; x < width; ++x) 1037 { 1038 DWORD src_color = src_row[x]; 1039 if (color_in_range(color_key, src_color)) 1040 src_color &= ~0xff000000; 1041 dst_row[x] = src_color; 1042 } 1043 } 1044 } 1045 1046 const struct wined3d_color_key_conversion * wined3d_format_get_color_key_conversion( 1047 const struct wined3d_texture *texture, BOOL need_alpha_ck) 1048 { 1049 const struct wined3d_format *format = texture->resource.format; 1050 unsigned int i; 1051 1052 static const struct 1053 { 1054 enum wined3d_format_id src_format; 1055 struct wined3d_color_key_conversion conversion; 1056 } 1057 color_key_info[] = 1058 { 1059 {WINED3DFMT_B5G6R5_UNORM, {WINED3DFMT_B5G5R5A1_UNORM, convert_b5g6r5_unorm_b5g5r5a1_unorm_color_key }}, 1060 {WINED3DFMT_B5G5R5X1_UNORM, {WINED3DFMT_B5G5R5A1_UNORM, convert_b5g5r5x1_unorm_b5g5r5a1_unorm_color_key }}, 1061 {WINED3DFMT_B8G8R8_UNORM, {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8_unorm_b8g8r8a8_unorm_color_key }}, 1062 {WINED3DFMT_B8G8R8X8_UNORM, {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8x8_unorm_b8g8r8a8_unorm_color_key }}, 1063 {WINED3DFMT_B8G8R8A8_UNORM, {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8a8_unorm_b8g8r8a8_unorm_color_key }}, 1064 }; 1065 static const struct wined3d_color_key_conversion convert_p8 = 1066 { 1067 WINED3DFMT_B8G8R8A8_UNORM, convert_p8_uint_b8g8r8a8_unorm 1068 }; 1069 1070 if (need_alpha_ck && (texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY)) 1071 { 1072 for (i = 0; i < ARRAY_SIZE(color_key_info); ++i) 1073 { 1074 if (color_key_info[i].src_format == format->id) 1075 return &color_key_info[i].conversion; 1076 } 1077 1078 FIXME("Color-keying not supported with format %s.\n", debug_d3dformat(format->id)); 1079 } 1080 1081 /* FIXME: This should check if the blitter backend can do P8 conversion, 1082 * instead of checking for ARB_fragment_program. */ 1083 if (format->id == WINED3DFMT_P8_UINT 1084 && !(texture->resource.device->adapter->gl_info.supported[ARB_FRAGMENT_PROGRAM] 1085 && texture->swapchain && texture == texture->swapchain->front_buffer)) 1086 return &convert_p8; 1087 1088 return NULL; 1089 } 1090 1091 /* The following formats explicitly don't have WINED3DFMT_FLAG_TEXTURE set: 1092 * 1093 * These are never supported on native. 1094 * WINED3DFMT_B8G8R8_UNORM 1095 * WINED3DFMT_B2G3R3_UNORM 1096 * WINED3DFMT_L4A4_UNORM 1097 * WINED3DFMT_S1_UINT_D15_UNORM 1098 * WINED3DFMT_S4X4_UINT_D24_UNORM 1099 * 1100 * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of ddraw. 1101 * Since it is not widely available, don't offer it. Further no Windows driver 1102 * offers WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either. 1103 * WINED3DFMT_P8_UINT 1104 * WINED3DFMT_P8_UINT_A8_UNORM 1105 * 1106 * These formats seem to be similar to the HILO formats in 1107 * GL_NV_texture_shader. NVHU is said to be GL_UNSIGNED_HILO16, 1108 * NVHS GL_SIGNED_HILO16. Rumours say that D3D computes a 3rd channel 1109 * similarly to D3DFMT_CxV8U8 (So NVHS could be called D3DFMT_CxV16U16). ATI 1110 * refused to support formats which can easily be emulated with pixel shaders, 1111 * so applications have to deal with not having NVHS and NVHU. 1112 * WINED3DFMT_NVHU 1113 * WINED3DFMT_NVHS */ 1114 static const struct wined3d_format_texture_info format_texture_info[] = 1115 { 1116 /* format id gl_internal gl_srgb_internal gl_rt_internal 1117 gl_format gl_type conv_byte_count 1118 flags 1119 extension upload download */ 1120 /* FourCC formats */ 1121 /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type 1122 * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The 1123 * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based 1124 * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big 1125 * endian machine 1126 */ 1127 {WINED3DFMT_UYVY, GL_RG8, GL_RG8, 0, 1128 GL_RG, GL_UNSIGNED_BYTE, 0, 1129 WINED3DFMT_FLAG_FILTERING, 1130 ARB_TEXTURE_RG, NULL}, 1131 {WINED3DFMT_UYVY, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE8_ALPHA8, 0, 1132 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, 1133 WINED3DFMT_FLAG_FILTERING, 1134 WINED3D_GL_LEGACY_CONTEXT, NULL}, 1135 {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0, 1136 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 0, 1137 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING, 1138 APPLE_YCBCR_422, NULL}, 1139 {WINED3DFMT_YUY2, GL_RG8, GL_RG8, 0, 1140 GL_RG, GL_UNSIGNED_BYTE, 0, 1141 WINED3DFMT_FLAG_FILTERING, 1142 ARB_TEXTURE_RG, NULL}, 1143 {WINED3DFMT_YUY2, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE8_ALPHA8, 0, 1144 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, 1145 WINED3DFMT_FLAG_FILTERING, 1146 WINED3D_GL_LEGACY_CONTEXT, NULL}, 1147 {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0, 1148 GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, 0, 1149 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING, 1150 APPLE_YCBCR_422, NULL}, 1151 {WINED3DFMT_YV12, GL_R8, GL_R8, 0, 1152 GL_RED, GL_UNSIGNED_BYTE, 0, 1153 WINED3DFMT_FLAG_FILTERING, 1154 ARB_TEXTURE_RG, NULL}, 1155 {WINED3DFMT_YV12, GL_ALPHA8, GL_ALPHA8, 0, 1156 GL_ALPHA, GL_UNSIGNED_BYTE, 0, 1157 WINED3DFMT_FLAG_FILTERING, 1158 WINED3D_GL_LEGACY_CONTEXT, NULL}, 1159 {WINED3DFMT_NV12, GL_R8, GL_R8, 0, 1160 GL_RED, GL_UNSIGNED_BYTE, 0, 1161 WINED3DFMT_FLAG_FILTERING, 1162 ARB_TEXTURE_RG, NULL}, 1163 {WINED3DFMT_NV12, GL_ALPHA8, GL_ALPHA8, 0, 1164 GL_ALPHA, GL_UNSIGNED_BYTE, 0, 1165 WINED3DFMT_FLAG_FILTERING, 1166 WINED3D_GL_LEGACY_CONTEXT, NULL}, 1167 {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0, 1168 GL_RGBA, GL_UNSIGNED_BYTE, 0, 1169 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1170 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED, 1171 EXT_TEXTURE_COMPRESSION_S3TC, NULL}, 1172 {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0, 1173 GL_RGBA, GL_UNSIGNED_BYTE, 0, 1174 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1175 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED, 1176 EXT_TEXTURE_COMPRESSION_S3TC, NULL}, 1177 {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0, 1178 GL_RGBA, GL_UNSIGNED_BYTE, 0, 1179 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1180 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED, 1181 EXT_TEXTURE_COMPRESSION_S3TC, NULL}, 1182 {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0, 1183 GL_RGBA, GL_UNSIGNED_BYTE, 0, 1184 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1185 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED, 1186 EXT_TEXTURE_COMPRESSION_S3TC, NULL}, 1187 {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0, 1188 GL_RGBA, GL_UNSIGNED_BYTE, 0, 1189 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1190 | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED, 1191 EXT_TEXTURE_COMPRESSION_S3TC, NULL}, 1192 {WINED3DFMT_BC1_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0, 1193 GL_RGBA, GL_UNSIGNED_BYTE, 0, 1194 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1195 | WINED3DFMT_FLAG_COMPRESSED, 1196 EXT_TEXTURE_COMPRESSION_S3TC, NULL}, 1197 {WINED3DFMT_BC2_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0, 1198 GL_RGBA, GL_UNSIGNED_BYTE, 0, 1199 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1200 | WINED3DFMT_FLAG_COMPRESSED, 1201 EXT_TEXTURE_COMPRESSION_S3TC, NULL}, 1202 {WINED3DFMT_BC3_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0, 1203 GL_RGBA, GL_UNSIGNED_BYTE, 0, 1204 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1205 | WINED3DFMT_FLAG_COMPRESSED, 1206 EXT_TEXTURE_COMPRESSION_S3TC, NULL}, 1207 {WINED3DFMT_BC4_UNORM, GL_COMPRESSED_RED_RGTC1, GL_COMPRESSED_RED_RGTC1, 0, 1208 GL_RED, GL_UNSIGNED_BYTE, 0, 1209 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1210 | WINED3DFMT_FLAG_COMPRESSED, 1211 ARB_TEXTURE_COMPRESSION_RGTC, NULL}, 1212 {WINED3DFMT_BC4_SNORM, GL_COMPRESSED_SIGNED_RED_RGTC1, GL_COMPRESSED_SIGNED_RED_RGTC1, 0, 1213 GL_RED, GL_UNSIGNED_BYTE, 0, 1214 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1215 | WINED3DFMT_FLAG_COMPRESSED, 1216 ARB_TEXTURE_COMPRESSION_RGTC, NULL}, 1217 {WINED3DFMT_BC5_UNORM, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0, 1218 GL_RG, GL_UNSIGNED_BYTE, 0, 1219 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1220 | WINED3DFMT_FLAG_COMPRESSED, 1221 ARB_TEXTURE_COMPRESSION_RGTC, NULL}, 1222 {WINED3DFMT_BC5_SNORM, GL_COMPRESSED_SIGNED_RG_RGTC2, GL_COMPRESSED_SIGNED_RG_RGTC2, 0, 1223 GL_RG, GL_UNSIGNED_BYTE, 0, 1224 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1225 | WINED3DFMT_FLAG_COMPRESSED, 1226 ARB_TEXTURE_COMPRESSION_RGTC, NULL}, 1227 {WINED3DFMT_BC6H_UF16, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB, 0, 1228 GL_RGB, GL_UNSIGNED_BYTE, 0, 1229 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1230 | WINED3DFMT_FLAG_COMPRESSED, 1231 ARB_TEXTURE_COMPRESSION_BPTC, NULL}, 1232 {WINED3DFMT_BC6H_SF16, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, 0, 1233 GL_RGB, GL_UNSIGNED_BYTE, 0, 1234 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1235 | WINED3DFMT_FLAG_COMPRESSED, 1236 ARB_TEXTURE_COMPRESSION_BPTC, NULL}, 1237 {WINED3DFMT_BC7_UNORM, GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB, 0, 1238 GL_RGBA, GL_UNSIGNED_BYTE, 0, 1239 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1240 | WINED3DFMT_FLAG_COMPRESSED, 1241 ARB_TEXTURE_COMPRESSION_BPTC, NULL}, 1242 /* IEEE formats */ 1243 {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0, 1244 GL_RED, GL_FLOAT, 0, 1245 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 1246 ARB_TEXTURE_FLOAT, NULL}, 1247 {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0, 1248 GL_RED, GL_FLOAT, 0, 1249 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 1250 ARB_TEXTURE_RG, NULL}, 1251 {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0, 1252 GL_RGB, GL_FLOAT, 12, 1253 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 1254 ARB_TEXTURE_FLOAT, convert_r32g32_float}, 1255 {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0, 1256 GL_RG, GL_FLOAT, 0, 1257 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 1258 ARB_TEXTURE_RG, NULL}, 1259 {WINED3DFMT_R32G32B32_FLOAT, GL_RGB32F, GL_RGB32F, 0, 1260 GL_RGB, GL_FLOAT, 0, 1261 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1262 ARB_TEXTURE_FLOAT, NULL}, 1263 {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0, 1264 GL_RGBA, GL_FLOAT, 0, 1265 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 1266 ARB_TEXTURE_FLOAT, NULL}, 1267 /* Float */ 1268 {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0, 1269 GL_RED, GL_HALF_FLOAT_ARB, 0, 1270 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 1271 ARB_TEXTURE_FLOAT, NULL}, 1272 {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0, 1273 GL_RED, GL_HALF_FLOAT_ARB, 0, 1274 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 1275 ARB_TEXTURE_RG, NULL}, 1276 {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0, 1277 GL_RGB, GL_HALF_FLOAT_ARB, 6, 1278 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 1279 ARB_TEXTURE_FLOAT, convert_r16g16}, 1280 {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0, 1281 GL_RG, GL_HALF_FLOAT_ARB, 0, 1282 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 1283 ARB_TEXTURE_RG, NULL}, 1284 {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0, 1285 GL_RGBA, GL_HALF_FLOAT_ARB, 0, 1286 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET 1287 | WINED3DFMT_FLAG_VTF, 1288 ARB_TEXTURE_FLOAT, NULL}, 1289 {WINED3DFMT_R11G11B10_FLOAT, GL_R11F_G11F_B10F, GL_R11F_G11F_B10F, 0, 1290 GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, 0, 1291 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET, 1292 EXT_PACKED_FLOAT}, 1293 /* Palettized formats */ 1294 {WINED3DFMT_P8_UINT, GL_R8, GL_R8, 0, 1295 GL_RED, GL_UNSIGNED_BYTE, 0, 1296 0, 1297 ARB_TEXTURE_RG, NULL}, 1298 {WINED3DFMT_P8_UINT, GL_ALPHA8, GL_ALPHA8, 0, 1299 GL_ALPHA, GL_UNSIGNED_BYTE, 0, 1300 0, 1301 WINED3D_GL_LEGACY_CONTEXT, NULL}, 1302 /* Standard ARGB formats */ 1303 {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0, 1304 GL_BGR, GL_UNSIGNED_BYTE, 0, 1305 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, 1306 WINED3D_GL_EXT_NONE, NULL}, 1307 {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0, 1308 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, 1309 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1310 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE 1311 | WINED3DFMT_FLAG_VTF, 1312 WINED3D_GL_EXT_NONE, NULL}, 1313 {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0, 1314 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, 1315 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1316 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE, 1317 WINED3D_GL_EXT_NONE, NULL}, 1318 {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8, 1319 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0, 1320 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1321 | WINED3DFMT_FLAG_RENDERTARGET, 1322 WINED3D_GL_EXT_NONE, NULL}, 1323 {WINED3DFMT_B5G6R5_UNORM, GL_RGB565, GL_RGB565, GL_RGB8, 1324 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0, 1325 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1326 | WINED3DFMT_FLAG_RENDERTARGET, 1327 ARB_ES2_COMPATIBILITY, NULL}, 1328 {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5, 0, 1329 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0, 1330 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1331 | WINED3DFMT_FLAG_RENDERTARGET, 1332 WINED3D_GL_EXT_NONE, NULL}, 1333 {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0, 1334 GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0, 1335 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 1336 WINED3D_GL_EXT_NONE, NULL}, 1337 {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0, 1338 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0, 1339 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1340 | WINED3DFMT_FLAG_SRGB_READ, 1341 WINED3D_GL_EXT_NONE, NULL}, 1342 {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0, 1343 GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0, 1344 WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 1345 WINED3D_GL_EXT_NONE, NULL}, 1346 {WINED3DFMT_R8_UNORM, GL_R8, GL_R8, 0, 1347 GL_RED, GL_UNSIGNED_BYTE, 0, 1348 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1349 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, 1350 ARB_TEXTURE_RG, NULL}, 1351 {WINED3DFMT_A8_UNORM, GL_R8, GL_R8, 0, 1352 GL_RED, GL_UNSIGNED_BYTE, 0, 1353 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 1354 ARB_TEXTURE_RG, NULL}, 1355 {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0, 1356 GL_ALPHA, GL_UNSIGNED_BYTE, 0, 1357 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 1358 WINED3D_GL_LEGACY_CONTEXT, NULL}, 1359 {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0, 1360 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0, 1361 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 1362 WINED3D_GL_EXT_NONE, NULL}, 1363 {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0, 1364 GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0, 1365 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1366 | WINED3DFMT_FLAG_RENDERTARGET, 1367 WINED3D_GL_EXT_NONE, NULL}, 1368 {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0, 1369 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, 1370 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1371 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE 1372 | WINED3DFMT_FLAG_VTF, 1373 WINED3D_GL_EXT_NONE, NULL}, 1374 {WINED3DFMT_R8G8B8A8_UINT, GL_RGBA8UI, GL_RGBA8UI, 0, 1375 GL_RGBA_INTEGER, GL_UNSIGNED_INT_8_8_8_8_REV, 0, 1376 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1377 ARB_TEXTURE_RGB10_A2UI, NULL}, 1378 {WINED3DFMT_R8G8B8A8_SINT, GL_RGBA8I, GL_RGBA8I, 0, 1379 GL_RGBA_INTEGER, GL_BYTE, 0, 1380 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1381 EXT_TEXTURE_INTEGER, NULL}, 1382 {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0, 1383 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, 1384 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 1385 WINED3D_GL_EXT_NONE, NULL}, 1386 {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16, 1387 GL_RGB, GL_UNSIGNED_SHORT, 6, 1388 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 1389 WINED3D_GL_EXT_NONE, convert_r16g16}, 1390 {WINED3DFMT_R16G16_UNORM, GL_RG16, GL_RG16, 0, 1391 GL_RG, GL_UNSIGNED_SHORT, 0, 1392 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1393 | WINED3DFMT_FLAG_RENDERTARGET, 1394 ARB_TEXTURE_RG, NULL}, 1395 {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0, 1396 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0, 1397 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1398 | WINED3DFMT_FLAG_RENDERTARGET, 1399 WINED3D_GL_EXT_NONE, NULL}, 1400 {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0, 1401 GL_RGBA, GL_UNSIGNED_SHORT, 0, 1402 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1403 | WINED3DFMT_FLAG_RENDERTARGET, 1404 WINED3D_GL_EXT_NONE, NULL}, 1405 {WINED3DFMT_R8G8_UNORM, GL_RG8, GL_RG8, 0, 1406 GL_RG, GL_UNSIGNED_BYTE, 0, 1407 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1408 | WINED3DFMT_FLAG_RENDERTARGET, 1409 ARB_TEXTURE_RG, NULL}, 1410 {WINED3DFMT_R8G8_UINT, GL_RG8UI, GL_RG8UI, 0, 1411 GL_RG_INTEGER, GL_UNSIGNED_BYTE, 0, 1412 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1413 ARB_TEXTURE_RG, NULL}, 1414 {WINED3DFMT_R8G8_SINT, GL_RG8I, GL_RG8I, 0, 1415 GL_RG_INTEGER, GL_BYTE, 0, 1416 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1417 ARB_TEXTURE_RG, NULL}, 1418 {WINED3DFMT_R16G16B16A16_UINT, GL_RGBA16UI, GL_RGBA16UI, 0, 1419 GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, 0, 1420 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1421 EXT_TEXTURE_INTEGER, NULL}, 1422 {WINED3DFMT_R16G16B16A16_SINT, GL_RGBA16I, GL_RGBA16I, 0, 1423 GL_RGBA_INTEGER, GL_SHORT, 0, 1424 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1425 EXT_TEXTURE_INTEGER, NULL}, 1426 {WINED3DFMT_R32G32_UINT, GL_RG32UI, GL_RG32UI, 0, 1427 GL_RG_INTEGER, GL_UNSIGNED_INT, 0, 1428 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1429 ARB_TEXTURE_RG, NULL}, 1430 {WINED3DFMT_R32G32_SINT, GL_RG32I, GL_RG32I, 0, 1431 GL_RG_INTEGER, GL_INT, 0, 1432 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1433 ARB_TEXTURE_RG, NULL}, 1434 {WINED3DFMT_R16G16_UINT, GL_RG16UI, GL_RG16UI, 0, 1435 GL_RG_INTEGER, GL_UNSIGNED_SHORT, 0, 1436 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1437 ARB_TEXTURE_RG, NULL}, 1438 {WINED3DFMT_R16G16_SINT, GL_RG16I, GL_RG16I, 0, 1439 GL_RG_INTEGER, GL_SHORT, 0, 1440 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1441 ARB_TEXTURE_RG, NULL}, 1442 {WINED3DFMT_R32_UINT, GL_R32UI, GL_R32UI, 0, 1443 GL_RED_INTEGER, GL_UNSIGNED_INT, 0, 1444 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1445 ARB_TEXTURE_RG, NULL}, 1446 {WINED3DFMT_R32_SINT, GL_R32I, GL_R32I, 0, 1447 GL_RED_INTEGER, GL_INT, 0, 1448 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1449 ARB_TEXTURE_RG, NULL}, 1450 {WINED3DFMT_R16_UNORM, GL_R16, GL_R16, 0, 1451 GL_RED, GL_UNSIGNED_SHORT, 0, 1452 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1453 | WINED3DFMT_FLAG_RENDERTARGET, 1454 ARB_TEXTURE_RG, NULL}, 1455 {WINED3DFMT_R16_UINT, GL_R16UI, GL_R16UI, 0, 1456 GL_RED_INTEGER, GL_UNSIGNED_SHORT, 0, 1457 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1458 ARB_TEXTURE_RG, NULL}, 1459 {WINED3DFMT_R16_SINT, GL_R16I, GL_R16I, 0, 1460 GL_RED_INTEGER, GL_SHORT, 0, 1461 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1462 ARB_TEXTURE_RG, NULL}, 1463 {WINED3DFMT_R8_UINT, GL_R8UI, GL_R8UI, 0, 1464 GL_RED_INTEGER, GL_UNSIGNED_BYTE, 0, 1465 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1466 ARB_TEXTURE_RG, NULL}, 1467 {WINED3DFMT_R8_SINT, GL_R8I, GL_R8I, 0, 1468 GL_RED_INTEGER, GL_BYTE, 0, 1469 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1470 ARB_TEXTURE_RG, NULL}, 1471 /* Luminance */ 1472 {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0, 1473 GL_LUMINANCE, GL_UNSIGNED_BYTE, 0, 1474 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1475 | WINED3DFMT_FLAG_SRGB_READ, 1476 WINED3D_GL_LEGACY_CONTEXT, NULL}, 1477 {WINED3DFMT_L8_UNORM, GL_R8, GL_R8, 0, 1478 GL_RED, GL_UNSIGNED_BYTE, 0, 1479 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1480 | WINED3DFMT_FLAG_RENDERTARGET, 1481 ARB_TEXTURE_RG, NULL}, 1482 {WINED3DFMT_L8A8_UNORM, GL_RG8, GL_RG8, 0, 1483 GL_RG, GL_UNSIGNED_BYTE, 0, 1484 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 1485 ARB_TEXTURE_RG, NULL}, 1486 {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0, 1487 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, 1488 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1489 | WINED3DFMT_FLAG_SRGB_READ, 1490 WINED3D_GL_LEGACY_CONTEXT, NULL}, 1491 {WINED3DFMT_L4A4_UNORM, GL_RG8, GL_RG8, 0, 1492 GL_RG, GL_UNSIGNED_BYTE, 2, 1493 WINED3DFMT_FLAG_FILTERING, 1494 ARB_TEXTURE_RG, convert_l4a4_unorm}, 1495 {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0, 1496 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2, 1497 WINED3DFMT_FLAG_FILTERING, 1498 WINED3D_GL_LEGACY_CONTEXT, convert_l4a4_unorm}, 1499 {WINED3DFMT_L16_UNORM, GL_R16, GL_R16, 0, 1500 GL_RED, GL_UNSIGNED_SHORT, 0, 1501 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 1502 ARB_TEXTURE_RG, NULL}, 1503 {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0, 1504 GL_LUMINANCE, GL_UNSIGNED_SHORT, 0, 1505 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 1506 WINED3D_GL_LEGACY_CONTEXT, NULL}, 1507 /* Bump mapping stuff */ 1508 {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0, 1509 GL_BGR, GL_UNSIGNED_BYTE, 3, 1510 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1511 | WINED3DFMT_FLAG_BUMPMAP, 1512 WINED3D_GL_EXT_NONE, convert_r8g8_snorm}, 1513 {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0, 1514 GL_DSDT_NV, GL_BYTE, 0, 1515 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1516 | WINED3DFMT_FLAG_BUMPMAP, 1517 NV_TEXTURE_SHADER, NULL}, 1518 {WINED3DFMT_R8G8_SNORM, GL_RG8_SNORM, GL_RG8_SNORM, 0, 1519 GL_RG, GL_BYTE, 0, 1520 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1521 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_BUMPMAP, 1522 EXT_TEXTURE_SNORM, NULL}, 1523 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0, 1524 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2, 1525 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1526 | WINED3DFMT_FLAG_BUMPMAP, 1527 WINED3D_GL_EXT_NONE, convert_r5g5_snorm_l6_unorm}, 1528 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0, 1529 GL_DSDT_MAG_NV, GL_BYTE, 3, 1530 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1531 | WINED3DFMT_FLAG_BUMPMAP, 1532 NV_TEXTURE_SHADER, convert_r5g5_snorm_l6_unorm_nv}, 1533 {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB8_SNORM, GL_RGB8_SNORM, 0, 1534 GL_RGBA, GL_BYTE, 4, 1535 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1536 | WINED3DFMT_FLAG_BUMPMAP, 1537 EXT_TEXTURE_SNORM, convert_r5g5_snorm_l6_unorm_ext}, 1538 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0, 1539 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 1540 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1541 | WINED3DFMT_FLAG_BUMPMAP, 1542 WINED3D_GL_EXT_NONE, convert_r8g8_snorm_l8x8_unorm}, 1543 {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0, 1544 GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4, 1545 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1546 | WINED3DFMT_FLAG_BUMPMAP, 1547 NV_TEXTURE_SHADER, convert_r8g8_snorm_l8x8_unorm_nv}, 1548 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0, 1549 GL_BGRA, GL_UNSIGNED_BYTE, 4, 1550 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1551 | WINED3DFMT_FLAG_BUMPMAP, 1552 WINED3D_GL_EXT_NONE, convert_r8g8b8a8_snorm}, 1553 {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0, 1554 GL_RGBA, GL_BYTE, 0, 1555 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1556 | WINED3DFMT_FLAG_BUMPMAP, 1557 NV_TEXTURE_SHADER, NULL}, 1558 {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8_SNORM, GL_RGBA8_SNORM, 0, 1559 GL_RGBA, GL_BYTE, 0, 1560 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1561 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_BUMPMAP, 1562 EXT_TEXTURE_SNORM, NULL}, 1563 {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0, 1564 GL_BGR, GL_UNSIGNED_SHORT, 6, 1565 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1566 | WINED3DFMT_FLAG_BUMPMAP, 1567 WINED3D_GL_EXT_NONE, convert_r16g16_snorm}, 1568 {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0, 1569 GL_HILO_NV, GL_SHORT, 0, 1570 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1571 | WINED3DFMT_FLAG_BUMPMAP, 1572 NV_TEXTURE_SHADER, NULL}, 1573 {WINED3DFMT_R16G16_SNORM, GL_RG16_SNORM, GL_RG16_SNORM, 0, 1574 GL_RG, GL_SHORT, 0, 1575 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1576 | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_BUMPMAP, 1577 EXT_TEXTURE_SNORM, NULL}, 1578 {WINED3DFMT_R16G16B16A16_SNORM, GL_RGBA16_SNORM, GL_RGBA16_SNORM, 0, 1579 GL_RGBA, GL_SHORT, 0, 1580 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1581 | WINED3DFMT_FLAG_RENDERTARGET, 1582 EXT_TEXTURE_SNORM, NULL}, 1583 {WINED3DFMT_R16_SNORM, GL_R16_SNORM, GL_R16_SNORM, 0, 1584 GL_RED, GL_SHORT, 0, 1585 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1586 | WINED3DFMT_FLAG_RENDERTARGET, 1587 EXT_TEXTURE_SNORM, NULL}, 1588 {WINED3DFMT_R8_SNORM, GL_R8_SNORM, GL_R8_SNORM, 0, 1589 GL_RED, GL_BYTE, 0, 1590 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1591 | WINED3DFMT_FLAG_RENDERTARGET, 1592 EXT_TEXTURE_SNORM, NULL}, 1593 /* Depth stencil formats */ 1594 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0, 1595 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, 1596 WINED3DFMT_FLAG_DEPTH, 1597 WINED3D_GL_EXT_NONE, NULL}, 1598 {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, 0, 1599 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, 1600 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, 1601 ARB_DEPTH_TEXTURE, NULL}, 1602 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0, 1603 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 1604 WINED3DFMT_FLAG_DEPTH, 1605 WINED3D_GL_EXT_NONE, NULL}, 1606 {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0, 1607 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 1608 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, 1609 ARB_DEPTH_TEXTURE, NULL}, 1610 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, 0, 1611 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, 1612 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, 1613 ARB_DEPTH_TEXTURE, NULL}, 1614 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0, 1615 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4, 1616 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, 1617 EXT_PACKED_DEPTH_STENCIL, convert_s1_uint_d15_unorm}, 1618 {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, 1619 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4, 1620 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, 1621 ARB_FRAMEBUFFER_OBJECT, convert_s1_uint_d15_unorm}, 1622 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, 1623 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 1624 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1625 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, 1626 ARB_DEPTH_TEXTURE, NULL}, 1627 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0, 1628 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0, 1629 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1630 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, 1631 EXT_PACKED_DEPTH_STENCIL, NULL}, 1632 {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, 1633 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0, 1634 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1635 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, 1636 ARB_FRAMEBUFFER_OBJECT, NULL}, 1637 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0, 1638 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 4, 1639 WINED3DFMT_FLAG_DEPTH, 1640 WINED3D_GL_EXT_NONE, x8_d24_unorm_upload, x8_d24_unorm_download}, 1641 {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, 1642 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 4, 1643 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1644 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, 1645 ARB_DEPTH_TEXTURE, x8_d24_unorm_upload, x8_d24_unorm_download}, 1646 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, 1647 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 1648 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, 1649 ARB_DEPTH_TEXTURE, NULL}, 1650 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0, 1651 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4, 1652 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, 1653 EXT_PACKED_DEPTH_STENCIL, convert_s4x4_uint_d24_unorm}, 1654 {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, 1655 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4, 1656 WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, 1657 ARB_FRAMEBUFFER_OBJECT, convert_s4x4_uint_d24_unorm}, 1658 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0, 1659 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, 1660 WINED3DFMT_FLAG_DEPTH, 1661 WINED3D_GL_EXT_NONE, NULL}, 1662 {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, 0, 1663 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, 1664 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1665 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, 1666 ARB_DEPTH_TEXTURE, NULL}, 1667 {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0, 1668 GL_DEPTH_COMPONENT, GL_FLOAT, 0, 1669 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, 1670 ARB_DEPTH_BUFFER_FLOAT, NULL}, 1671 {WINED3DFMT_D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0, 1672 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 0, 1673 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, 1674 ARB_DEPTH_BUFFER_FLOAT, NULL}, 1675 {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0, 1676 GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, 1677 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, 1678 ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float}, 1679 {WINED3DFMT_R32G32B32A32_UINT, GL_RGBA32UI, GL_RGBA32UI, 0, 1680 GL_RGBA_INTEGER, GL_UNSIGNED_INT, 0, 1681 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1682 EXT_TEXTURE_INTEGER, NULL}, 1683 {WINED3DFMT_R32G32B32A32_SINT, GL_RGBA32I, GL_RGBA32I, 0, 1684 GL_RGBA_INTEGER, GL_INT, 0, 1685 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, 1686 EXT_TEXTURE_INTEGER, NULL}, 1687 {WINED3DFMT_R24_UNORM_X8_TYPELESS, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, 1688 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8, 0, 1689 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH, 1690 ARB_DEPTH_TEXTURE, NULL}, 1691 /* Vendor-specific formats */ 1692 {WINED3DFMT_ATI1N, GL_COMPRESSED_RED_RGTC1, GL_COMPRESSED_RED_RGTC1, 0, 1693 GL_RED, GL_UNSIGNED_BYTE, 0, 1694 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1695 | WINED3DFMT_FLAG_COMPRESSED, 1696 ARB_TEXTURE_COMPRESSION_RGTC, NULL}, 1697 {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0, 1698 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, 1699 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1700 | WINED3DFMT_FLAG_COMPRESSED, 1701 ATI_TEXTURE_COMPRESSION_3DC, NULL}, 1702 {WINED3DFMT_ATI2N, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0, 1703 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, 1704 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1705 | WINED3DFMT_FLAG_COMPRESSED, 1706 EXT_TEXTURE_COMPRESSION_RGTC, NULL}, 1707 {WINED3DFMT_ATI2N, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0, 1708 GL_RG, GL_UNSIGNED_BYTE, 0, 1709 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1710 | WINED3DFMT_FLAG_COMPRESSED, 1711 ARB_TEXTURE_COMPRESSION_RGTC, NULL}, 1712 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0, 1713 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0, 1714 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1715 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, 1716 EXT_PACKED_DEPTH_STENCIL, NULL}, 1717 {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, 1718 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0, 1719 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING 1720 | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, 1721 ARB_FRAMEBUFFER_OBJECT, NULL}, 1722 {WINED3DFMT_NULL, 0, 0, 0, 1723 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, 1724 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FBO_ATTACHABLE, 1725 ARB_FRAMEBUFFER_OBJECT, NULL}, 1726 /* DirectX 10 HDR formats */ 1727 {WINED3DFMT_R9G9B9E5_SHAREDEXP, GL_RGB9_E5_EXT, GL_RGB9_E5_EXT, 0, 1728 GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV_EXT, 0, 1729 WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, 1730 EXT_TEXTURE_SHARED_EXPONENT, NULL}, 1731 }; 1732 1733 struct wined3d_format_srgb_info 1734 { 1735 enum wined3d_format_id srgb_format_id; 1736 enum wined3d_format_id base_format_id; 1737 }; 1738 1739 static const struct wined3d_format_srgb_info format_srgb_info[] = 1740 { 1741 {WINED3DFMT_R8G8B8A8_UNORM_SRGB, WINED3DFMT_R8G8B8A8_UNORM}, 1742 {WINED3DFMT_BC1_UNORM_SRGB, WINED3DFMT_BC1_UNORM}, 1743 {WINED3DFMT_BC2_UNORM_SRGB, WINED3DFMT_BC2_UNORM}, 1744 {WINED3DFMT_BC3_UNORM_SRGB, WINED3DFMT_BC3_UNORM}, 1745 {WINED3DFMT_B8G8R8A8_UNORM_SRGB, WINED3DFMT_B8G8R8A8_UNORM}, 1746 {WINED3DFMT_B8G8R8X8_UNORM_SRGB, WINED3DFMT_B8G8R8X8_UNORM}, 1747 {WINED3DFMT_BC7_UNORM_SRGB, WINED3DFMT_BC7_UNORM}, 1748 }; 1749 1750 static inline int get_format_idx(enum wined3d_format_id format_id) 1751 { 1752 unsigned int i; 1753 1754 if (format_id < WINED3D_FORMAT_FOURCC_BASE) 1755 return format_id; 1756 1757 for (i = 0; i < ARRAY_SIZE(format_index_remap); ++i) 1758 { 1759 if (format_index_remap[i].id == format_id) 1760 return format_index_remap[i].idx; 1761 } 1762 1763 return -1; 1764 } 1765 1766 static struct wined3d_format *get_format_internal(struct wined3d_gl_info *gl_info, 1767 enum wined3d_format_id format_id) 1768 { 1769 int fmt_idx; 1770 1771 if ((fmt_idx = get_format_idx(format_id)) == -1) 1772 { 1773 ERR("Format %s (%#x) not found.\n", debug_d3dformat(format_id), format_id); 1774 return NULL; 1775 } 1776 1777 return &gl_info->formats[fmt_idx]; 1778 } 1779 1780 static void copy_format(struct wined3d_format *dst_format, const struct wined3d_format *src_format) 1781 { 1782 enum wined3d_format_id id = dst_format->id; 1783 *dst_format = *src_format; 1784 dst_format->id = id; 1785 } 1786 1787 static void format_set_flag(struct wined3d_format *format, unsigned int flag) 1788 { 1789 unsigned int i; 1790 1791 for (i = 0; i < ARRAY_SIZE(format->flags); ++i) 1792 format->flags[i] |= flag; 1793 } 1794 1795 static void format_clear_flag(struct wined3d_format *format, unsigned int flag) 1796 { 1797 unsigned int i; 1798 1799 for (i = 0; i < ARRAY_SIZE(format->flags); ++i) 1800 format->flags[i] &= ~flag; 1801 } 1802 1803 static enum wined3d_channel_type map_channel_type(char t) 1804 { 1805 switch (t) 1806 { 1807 case 'u': 1808 return WINED3D_CHANNEL_TYPE_UNORM; 1809 case 'i': 1810 return WINED3D_CHANNEL_TYPE_SNORM; 1811 case 'U': 1812 return WINED3D_CHANNEL_TYPE_UINT; 1813 case 'I': 1814 return WINED3D_CHANNEL_TYPE_SINT; 1815 case 'F': 1816 return WINED3D_CHANNEL_TYPE_FLOAT; 1817 case 'D': 1818 return WINED3D_CHANNEL_TYPE_DEPTH; 1819 case 'S': 1820 return WINED3D_CHANNEL_TYPE_STENCIL; 1821 case 'X': 1822 return WINED3D_CHANNEL_TYPE_UNUSED; 1823 default: 1824 ERR("Invalid channel type '%c'.\n", t); 1825 return WINED3D_CHANNEL_TYPE_NONE; 1826 } 1827 } 1828 1829 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info) 1830 { 1831 struct wined3d_format *format; 1832 unsigned int i, j; 1833 1834 gl_info->format_count = WINED3D_FORMAT_COUNT; 1835 if (!(gl_info->formats = heap_calloc(gl_info->format_count 1836 + ARRAY_SIZE(typeless_depth_stencil_formats), sizeof(*gl_info->formats)))) 1837 { 1838 ERR("Failed to allocate memory.\n"); 1839 return FALSE; 1840 } 1841 1842 for (i = 0; i < ARRAY_SIZE(formats); ++i) 1843 { 1844 if (!(format = get_format_internal(gl_info, formats[i].id))) 1845 goto fail; 1846 1847 format->id = formats[i].id; 1848 format->red_size = formats[i].red_size; 1849 format->green_size = formats[i].green_size; 1850 format->blue_size = formats[i].blue_size; 1851 format->alpha_size = formats[i].alpha_size; 1852 format->red_offset = formats[i].red_offset; 1853 format->green_offset = formats[i].green_offset; 1854 format->blue_offset = formats[i].blue_offset; 1855 format->alpha_offset = formats[i].alpha_offset; 1856 format->byte_count = formats[i].bpp; 1857 format->depth_size = formats[i].depth_size; 1858 format->stencil_size = formats[i].stencil_size; 1859 format->block_width = 1; 1860 format->block_height = 1; 1861 format->block_byte_count = formats[i].bpp; 1862 } 1863 1864 for (i = 0; i < ARRAY_SIZE(typed_formats); ++i) 1865 { 1866 const struct wined3d_format *typeless_format; 1867 DWORD flags = 0; 1868 1869 if (!(format = get_format_internal(gl_info, typed_formats[i].id))) 1870 goto fail; 1871 1872 if (!(typeless_format = get_format_internal(gl_info, typed_formats[i].typeless_id))) 1873 goto fail; 1874 1875 format->id = typed_formats[i].id; 1876 format->red_size = typeless_format->red_size; 1877 format->green_size = typeless_format->green_size; 1878 format->blue_size = typeless_format->blue_size; 1879 format->alpha_size = typeless_format->alpha_size; 1880 format->red_offset = typeless_format->red_offset; 1881 format->green_offset = typeless_format->green_offset; 1882 format->blue_offset = typeless_format->blue_offset; 1883 format->alpha_offset = typeless_format->alpha_offset; 1884 format->byte_count = typeless_format->byte_count; 1885 format->depth_size = typeless_format->depth_size; 1886 format->stencil_size = typeless_format->stencil_size; 1887 format->block_width = typeless_format->block_width; 1888 format->block_height = typeless_format->block_height; 1889 format->block_byte_count = typeless_format->block_byte_count; 1890 format->typeless_id = typeless_format->id; 1891 1892 for (j = 0; j < strlen(typed_formats[i].channels); ++j) 1893 { 1894 enum wined3d_channel_type channel_type = map_channel_type(typed_formats[i].channels[j]); 1895 if (channel_type == WINED3D_CHANNEL_TYPE_UINT || channel_type == WINED3D_CHANNEL_TYPE_SINT) 1896 flags |= WINED3DFMT_FLAG_INTEGER; 1897 if (channel_type == WINED3D_CHANNEL_TYPE_FLOAT) 1898 flags |= WINED3DFMT_FLAG_FLOAT; 1899 1900 if (channel_type == WINED3D_CHANNEL_TYPE_DEPTH && !format->depth_size) 1901 { 1902 format->depth_size = format->red_size; 1903 format->red_size = format->red_offset = 0; 1904 } 1905 } 1906 1907 format_set_flag(format, flags); 1908 } 1909 1910 for (i = 0; i < ARRAY_SIZE(ddi_formats); ++i) 1911 { 1912 if (!(format = get_format_internal(gl_info, ddi_formats[i].id))) 1913 goto fail; 1914 1915 format->ddi_format = ddi_formats[i].ddi_format; 1916 } 1917 1918 for (i = 0; i < ARRAY_SIZE(format_base_flags); ++i) 1919 { 1920 if (!(format = get_format_internal(gl_info, format_base_flags[i].id))) 1921 goto fail; 1922 1923 format_set_flag(format, format_base_flags[i].flags); 1924 } 1925 1926 return TRUE; 1927 1928 fail: 1929 heap_free(gl_info->formats); 1930 return FALSE; 1931 } 1932 1933 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info) 1934 { 1935 struct wined3d_format *format; 1936 unsigned int i; 1937 1938 for (i = 0; i < ARRAY_SIZE(format_block_info); ++i) 1939 { 1940 if (!(format = get_format_internal(gl_info, format_block_info[i].id))) 1941 return FALSE; 1942 1943 format->block_width = format_block_info[i].block_width; 1944 format->block_height = format_block_info[i].block_height; 1945 format->block_byte_count = format_block_info[i].block_byte_count; 1946 format_set_flag(format, WINED3DFMT_FLAG_BLOCKS); 1947 if (!format_block_info[i].verify) 1948 format_set_flag(format, WINED3DFMT_FLAG_BLOCKS_NO_VERIFY); 1949 } 1950 1951 return TRUE; 1952 } 1953 1954 static GLenum wined3d_gl_type_to_enum(enum wined3d_gl_resource_type type) 1955 { 1956 switch (type) 1957 { 1958 case WINED3D_GL_RES_TYPE_TEX_1D: 1959 return GL_TEXTURE_1D; 1960 case WINED3D_GL_RES_TYPE_TEX_2D: 1961 return GL_TEXTURE_2D; 1962 case WINED3D_GL_RES_TYPE_TEX_3D: 1963 return GL_TEXTURE_3D; 1964 case WINED3D_GL_RES_TYPE_TEX_CUBE: 1965 return GL_TEXTURE_CUBE_MAP_ARB; 1966 case WINED3D_GL_RES_TYPE_TEX_RECT: 1967 return GL_TEXTURE_RECTANGLE_ARB; 1968 case WINED3D_GL_RES_TYPE_BUFFER: 1969 return GL_TEXTURE_2D; /* TODO: GL_TEXTURE_BUFFER. */ 1970 case WINED3D_GL_RES_TYPE_RB: 1971 return GL_RENDERBUFFER; 1972 case WINED3D_GL_RES_TYPE_COUNT: 1973 break; 1974 } 1975 ERR("Unexpected GL resource type %u.\n", type); 1976 return 0; 1977 } 1978 1979 static void delete_fbo_attachment(const struct wined3d_gl_info *gl_info, 1980 enum wined3d_gl_resource_type d3d_type, GLuint object) 1981 { 1982 switch (d3d_type) 1983 { 1984 case WINED3D_GL_RES_TYPE_TEX_1D: 1985 case WINED3D_GL_RES_TYPE_TEX_2D: 1986 case WINED3D_GL_RES_TYPE_TEX_RECT: 1987 case WINED3D_GL_RES_TYPE_TEX_3D: 1988 case WINED3D_GL_RES_TYPE_TEX_CUBE: 1989 gl_info->gl_ops.gl.p_glDeleteTextures(1, &object); 1990 break; 1991 1992 case WINED3D_GL_RES_TYPE_RB: 1993 gl_info->fbo_ops.glDeleteRenderbuffers(1, &object); 1994 break; 1995 1996 case WINED3D_GL_RES_TYPE_BUFFER: 1997 case WINED3D_GL_RES_TYPE_COUNT: 1998 break; 1999 } 2000 } 2001 2002 /* Context activation is done by the caller. */ 2003 static void create_and_bind_fbo_attachment(const struct wined3d_gl_info *gl_info, unsigned int flags, 2004 enum wined3d_gl_resource_type d3d_type, GLuint *object, GLenum internal, GLenum format, GLenum type) 2005 { 2006 GLenum attach_type = flags & WINED3DFMT_FLAG_DEPTH ? 2007 GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0; 2008 2009 switch (d3d_type) 2010 { 2011 case WINED3D_GL_RES_TYPE_TEX_1D: 2012 gl_info->gl_ops.gl.p_glGenTextures(1, object); 2013 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, *object); 2014 gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, internal, 16, 0, format, type, NULL); 2015 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2016 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2017 2018 gl_info->fbo_ops.glFramebufferTexture1D(GL_FRAMEBUFFER, attach_type, GL_TEXTURE_1D, 2019 *object, 0); 2020 if (flags & WINED3DFMT_FLAG_STENCIL) 2021 gl_info->fbo_ops.glFramebufferTexture1D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_1D, 2022 *object, 0); 2023 break; 2024 2025 case WINED3D_GL_RES_TYPE_TEX_2D: 2026 case WINED3D_GL_RES_TYPE_TEX_RECT: 2027 gl_info->gl_ops.gl.p_glGenTextures(1, object); 2028 gl_info->gl_ops.gl.p_glBindTexture(wined3d_gl_type_to_enum(d3d_type), *object); 2029 gl_info->gl_ops.gl.p_glTexImage2D(wined3d_gl_type_to_enum(d3d_type), 0, internal, 16, 16, 0, 2030 format, type, NULL); 2031 gl_info->gl_ops.gl.p_glTexParameteri(wined3d_gl_type_to_enum(d3d_type), GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2032 gl_info->gl_ops.gl.p_glTexParameteri(wined3d_gl_type_to_enum(d3d_type), GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2033 2034 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, attach_type, 2035 wined3d_gl_type_to_enum(d3d_type), *object, 0); 2036 if (flags & WINED3DFMT_FLAG_STENCIL) 2037 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, 2038 wined3d_gl_type_to_enum(d3d_type), *object, 0); 2039 break; 2040 2041 case WINED3D_GL_RES_TYPE_TEX_3D: 2042 gl_info->gl_ops.gl.p_glGenTextures(1, object); 2043 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, *object); 2044 GL_EXTCALL(glTexImage3D(GL_TEXTURE_3D, 0, internal, 16, 16, 16, 0, format, type, NULL)); 2045 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2046 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2047 2048 gl_info->fbo_ops.glFramebufferTexture3D(GL_FRAMEBUFFER, attach_type, 2049 GL_TEXTURE_3D, *object, 0, 0); 2050 if (flags & WINED3DFMT_FLAG_STENCIL) 2051 gl_info->fbo_ops.glFramebufferTexture3D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, 2052 GL_TEXTURE_3D, *object, 0, 0); 2053 break; 2054 2055 case WINED3D_GL_RES_TYPE_TEX_CUBE: 2056 gl_info->gl_ops.gl.p_glGenTextures(1, object); 2057 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, *object); 2058 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, internal, 16, 16, 0, 2059 format, type, NULL); 2060 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 0, internal, 16, 16, 0, 2061 format, type, NULL); 2062 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0, internal, 16, 16, 0, 2063 format, type, NULL); 2064 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 0, internal, 16, 16, 0, 2065 format, type, NULL); 2066 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 0, internal, 16, 16, 0, 2067 format, type, NULL); 2068 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 0, internal, 16, 16, 0, 2069 format, type, NULL); 2070 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2071 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2072 2073 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, attach_type, 2074 GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, *object, 0); 2075 if (flags & WINED3DFMT_FLAG_STENCIL) 2076 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, 2077 GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, *object, 0); 2078 break; 2079 2080 case WINED3D_GL_RES_TYPE_RB: 2081 gl_info->fbo_ops.glGenRenderbuffers(1, object); 2082 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, *object); 2083 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, internal, 16, 16); 2084 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, attach_type, GL_RENDERBUFFER, 2085 *object); 2086 if (flags & WINED3DFMT_FLAG_STENCIL) 2087 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 2088 *object); 2089 break; 2090 2091 case WINED3D_GL_RES_TYPE_BUFFER: 2092 case WINED3D_GL_RES_TYPE_COUNT: 2093 break; 2094 } 2095 2096 /* Ideally we'd skip all formats already known not to work on textures 2097 * by checking for WINED3DFMT_FLAG_TEXTURE here. However, we want to 2098 * know if we can attach WINED3DFMT_P8_UINT textures to FBOs, and this 2099 * format never has WINED3DFMT_FLAG_TEXTURE set. Instead, swallow GL 2100 * errors generated by invalid formats. */ 2101 while (gl_info->gl_ops.gl.p_glGetError()); 2102 } 2103 2104 static void draw_test_quad(struct wined3d_caps_gl_ctx *ctx, const struct wined3d_vec3 *geometry, 2105 const struct wined3d_color *color) 2106 { 2107 const struct wined3d_gl_info *gl_info = ctx->gl_info; 2108 static const struct wined3d_vec3 default_geometry[] = 2109 { 2110 {-1.0f, -1.0f, 0.0f}, 2111 { 1.0f, -1.0f, 0.0f}, 2112 {-1.0f, 1.0f, 0.0f}, 2113 { 1.0f, 1.0f, 0.0f}, 2114 }; 2115 static const char vs_core_header[] = 2116 "#version 150\n" 2117 "in vec4 pos;\n" 2118 "in vec4 color;\n" 2119 "out vec4 out_color;\n" 2120 "\n"; 2121 static const char vs_legacy_header[] = 2122 "#version 120\n" 2123 "attribute vec4 pos;\n" 2124 "attribute vec4 color;\n" 2125 "varying vec4 out_color;\n" 2126 "\n"; 2127 static const char vs_body[] = 2128 "void main()\n" 2129 "{\n" 2130 " gl_Position = pos;\n" 2131 " out_color = color;\n" 2132 "}\n"; 2133 static const char fs_core[] = 2134 "#version 150\n" 2135 "in vec4 out_color;\n" 2136 "out vec4 fragment_color;\n" 2137 "\n" 2138 "void main()\n" 2139 "{\n" 2140 " fragment_color = out_color;\n" 2141 "}\n"; 2142 static const char fs_legacy[] = 2143 "#version 120\n" 2144 "varying vec4 out_color;\n" 2145 "\n" 2146 "void main()\n" 2147 "{\n" 2148 " gl_FragData[0] = out_color;\n" 2149 "}\n"; 2150 const char *source[2]; 2151 GLuint vs_id, fs_id; 2152 unsigned int i; 2153 2154 if (!geometry) 2155 geometry = default_geometry; 2156 2157 if (!gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] || !gl_info->supported[ARB_VERTEX_SHADER] 2158 || !gl_info->supported[ARB_FRAGMENT_SHADER]) 2159 { 2160 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING); 2161 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW); 2162 gl_info->gl_ops.gl.p_glLoadIdentity(); 2163 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION); 2164 gl_info->gl_ops.gl.p_glLoadIdentity(); 2165 2166 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP); 2167 gl_info->gl_ops.gl.p_glColor4f(color->r, color->g, color->b, color->a); 2168 for (i = 0; i < 4; ++i) 2169 gl_info->gl_ops.gl.p_glVertex3fv(&geometry[i].x); 2170 gl_info->gl_ops.gl.p_glEnd(); 2171 checkGLcall("draw quad"); 2172 return; 2173 } 2174 2175 if (!ctx->test_vbo) 2176 GL_EXTCALL(glGenBuffers(1, &ctx->test_vbo)); 2177 GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, ctx->test_vbo)); 2178 GL_EXTCALL(glBufferData(GL_ARRAY_BUFFER, sizeof(struct wined3d_vec3) * 4, geometry, GL_STREAM_DRAW)); 2179 GL_EXTCALL(glVertexAttribPointer(0, 3, GL_FLOAT, FALSE, 0, NULL)); 2180 GL_EXTCALL(glVertexAttrib4f(1, color->r, color->g, color->b, color->a)); 2181 GL_EXTCALL(glEnableVertexAttribArray(0)); 2182 GL_EXTCALL(glDisableVertexAttribArray(1)); 2183 2184 if (!ctx->test_program_id) 2185 { 2186 #ifdef __REACTOS__ 2187 /* workaround CORE-15408 crash for many 3D applications. 2188 VBoxDisp with enabled 3D acceleration only supports OpenGL 2.1 (GLSL 120). 2189 Wine must not use shaders for OpenGL 3.2 (GLSL 150). */ 2190 BOOL use_glsl_150 = FALSE; 2191 #else 2192 BOOL use_glsl_150 = gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50); 2193 #endif 2194 2195 ctx->test_program_id = GL_EXTCALL(glCreateProgram()); 2196 2197 vs_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER)); 2198 source[0] = use_glsl_150 ? vs_core_header : vs_legacy_header; 2199 source[1] = vs_body; 2200 GL_EXTCALL(glShaderSource(vs_id, 2, source, NULL)); 2201 GL_EXTCALL(glAttachShader(ctx->test_program_id, vs_id)); 2202 GL_EXTCALL(glDeleteShader(vs_id)); 2203 2204 fs_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER)); 2205 source[0] = use_glsl_150 ? fs_core : fs_legacy; 2206 GL_EXTCALL(glShaderSource(fs_id, 1, source, NULL)); 2207 GL_EXTCALL(glAttachShader(ctx->test_program_id, fs_id)); 2208 GL_EXTCALL(glDeleteShader(fs_id)); 2209 2210 GL_EXTCALL(glBindAttribLocation(ctx->test_program_id, 0, "pos")); 2211 GL_EXTCALL(glBindAttribLocation(ctx->test_program_id, 1, "color")); 2212 2213 if (use_glsl_150) 2214 GL_EXTCALL(glBindFragDataLocation(ctx->test_program_id, 0, "fragment_color")); 2215 2216 GL_EXTCALL(glCompileShader(vs_id)); 2217 print_glsl_info_log(gl_info, vs_id, FALSE); 2218 GL_EXTCALL(glCompileShader(fs_id)); 2219 print_glsl_info_log(gl_info, fs_id, FALSE); 2220 GL_EXTCALL(glLinkProgram(ctx->test_program_id)); 2221 shader_glsl_validate_link(gl_info, ctx->test_program_id); 2222 } 2223 GL_EXTCALL(glUseProgram(ctx->test_program_id)); 2224 2225 gl_info->gl_ops.gl.p_glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 2226 2227 GL_EXTCALL(glUseProgram(0)); 2228 GL_EXTCALL(glDisableVertexAttribArray(0)); 2229 GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, 0)); 2230 checkGLcall("draw quad"); 2231 } 2232 2233 /* Context activation is done by the caller. */ 2234 static void check_fbo_compat(struct wined3d_caps_gl_ctx *ctx, struct wined3d_format *format) 2235 { 2236 /* Check if the default internal format is supported as a frame buffer 2237 * target, otherwise fall back to the render target internal. 2238 * 2239 * Try to stick to the standard format if possible, this limits precision differences. */ 2240 static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 1.0f}; 2241 static const struct wined3d_color half_transparent_red = {1.0f, 0.0f, 0.0f, 0.5f}; 2242 const struct wined3d_gl_info *gl_info = ctx->gl_info; 2243 GLenum status, rt_internal = format->rtInternal; 2244 GLuint object, color_rb; 2245 enum wined3d_gl_resource_type type; 2246 BOOL fallback_fmt_used = FALSE, regular_fmt_used = FALSE; 2247 2248 gl_info->gl_ops.gl.p_glDisable(GL_BLEND); 2249 2250 for (type = 0; type < ARRAY_SIZE(format->flags); ++type) 2251 { 2252 const char *type_string = "color"; 2253 2254 if (type == WINED3D_GL_RES_TYPE_BUFFER) 2255 continue; 2256 2257 create_and_bind_fbo_attachment(gl_info, format->flags[type], type, &object, format->glInternal, 2258 format->glFormat, format->glType); 2259 2260 if (format->flags[type] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) 2261 { 2262 gl_info->fbo_ops.glGenRenderbuffers(1, &color_rb); 2263 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, color_rb); 2264 if (type == WINED3D_GL_RES_TYPE_TEX_1D) 2265 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 1); 2266 else 2267 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16); 2268 2269 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, 2270 GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color_rb); 2271 checkGLcall("Create and attach color rb attachment"); 2272 type_string = "depth / stencil"; 2273 } 2274 2275 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); 2276 checkGLcall("Framebuffer format check"); 2277 2278 if (status == GL_FRAMEBUFFER_COMPLETE) 2279 { 2280 TRACE("Format %s is supported as FBO %s attachment, type %u.\n", 2281 debug_d3dformat(format->id), type_string, type); 2282 format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE; 2283 format->rtInternal = format->glInternal; 2284 regular_fmt_used = TRUE; 2285 } 2286 else 2287 { 2288 if (!rt_internal) 2289 { 2290 if (format->flags[type] & WINED3DFMT_FLAG_RENDERTARGET) 2291 { 2292 WARN("Format %s with rendertarget flag is not supported as FBO color attachment (type %u)," 2293 " and no fallback specified.\n", debug_d3dformat(format->id), type); 2294 format->flags[type] &= ~WINED3DFMT_FLAG_RENDERTARGET; 2295 } 2296 else 2297 { 2298 TRACE("Format %s is not supported as FBO %s attachment, type %u.\n", 2299 debug_d3dformat(format->id), type_string, type); 2300 } 2301 format->rtInternal = format->glInternal; 2302 } 2303 else 2304 { 2305 TRACE("Format %s is not supported as FBO %s attachment (type %u)," 2306 " trying rtInternal format as fallback.\n", 2307 debug_d3dformat(format->id), type_string, type); 2308 2309 while (gl_info->gl_ops.gl.p_glGetError()); 2310 2311 delete_fbo_attachment(gl_info, type, object); 2312 create_and_bind_fbo_attachment(gl_info, format->flags[type], type, &object, format->rtInternal, 2313 format->glFormat, format->glType); 2314 2315 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); 2316 checkGLcall("Framebuffer format check"); 2317 2318 if (status == GL_FRAMEBUFFER_COMPLETE) 2319 { 2320 TRACE("Format %s rtInternal format is supported as FBO %s attachment, type %u.\n", 2321 debug_d3dformat(format->id), type_string, type); 2322 fallback_fmt_used = TRUE; 2323 } 2324 else 2325 { 2326 WARN("Format %s rtInternal format is not supported as FBO %s attachment, type %u.\n", 2327 debug_d3dformat(format->id), type_string, type); 2328 format->flags[type] &= ~WINED3DFMT_FLAG_RENDERTARGET; 2329 } 2330 } 2331 } 2332 2333 if (status == GL_FRAMEBUFFER_COMPLETE 2334 && ((format->flags[type] & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) 2335 || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING)) 2336 && !(format->flags[type] & WINED3DFMT_FLAG_INTEGER) 2337 && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT 2338 && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA 2339 && (format->red_size || format->alpha_size)) 2340 { 2341 DWORD readback[16 * 16 * 16], color, r_range, a_range; 2342 BYTE r, a; 2343 BOOL match = TRUE; 2344 GLuint rb; 2345 2346 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] 2347 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL]) 2348 { 2349 gl_info->fbo_ops.glGenRenderbuffers(1, &rb); 2350 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb); 2351 if (type == WINED3D_GL_RES_TYPE_TEX_1D) 2352 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 1); 2353 else 2354 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16); 2355 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb); 2356 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb); 2357 checkGLcall("RB attachment"); 2358 } 2359 2360 gl_info->gl_ops.gl.p_glEnable(GL_BLEND); 2361 gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 2362 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT); 2363 if (gl_info->gl_ops.gl.p_glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION) 2364 { 2365 while (gl_info->gl_ops.gl.p_glGetError()); 2366 TRACE("Format %s doesn't support post-pixelshader blending, type %u.\n", 2367 debug_d3dformat(format->id), type); 2368 format->flags[type] &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; 2369 } 2370 else 2371 { 2372 gl_info->gl_ops.gl.p_glDisable(GL_BLEND); 2373 if (type == WINED3D_GL_RES_TYPE_TEX_1D) 2374 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1); 2375 else 2376 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16); 2377 gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2378 2379 draw_test_quad(ctx, NULL, &black); 2380 2381 gl_info->gl_ops.gl.p_glEnable(GL_BLEND); 2382 2383 draw_test_quad(ctx, NULL, &half_transparent_red); 2384 2385 gl_info->gl_ops.gl.p_glDisable(GL_BLEND); 2386 2387 switch (type) 2388 { 2389 case WINED3D_GL_RES_TYPE_TEX_1D: 2390 /* Rebinding texture to workaround a fglrx bug. */ 2391 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, object); 2392 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_1D, 0, GL_BGRA, 2393 GL_UNSIGNED_INT_8_8_8_8_REV, readback); 2394 color = readback[7]; 2395 break; 2396 2397 case WINED3D_GL_RES_TYPE_TEX_2D: 2398 case WINED3D_GL_RES_TYPE_TEX_3D: 2399 case WINED3D_GL_RES_TYPE_TEX_RECT: 2400 /* Rebinding texture to workaround a fglrx bug. */ 2401 gl_info->gl_ops.gl.p_glBindTexture(wined3d_gl_type_to_enum(type), object); 2402 gl_info->gl_ops.gl.p_glGetTexImage(wined3d_gl_type_to_enum(type), 0, GL_BGRA, 2403 GL_UNSIGNED_INT_8_8_8_8_REV, readback); 2404 color = readback[7 * 16 + 7]; 2405 break; 2406 2407 case WINED3D_GL_RES_TYPE_TEX_CUBE: 2408 /* Rebinding texture to workaround a fglrx bug. */ 2409 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, object); 2410 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_BGRA, 2411 GL_UNSIGNED_INT_8_8_8_8_REV, readback); 2412 color = readback[7 * 16 + 7]; 2413 break; 2414 2415 case WINED3D_GL_RES_TYPE_RB: 2416 gl_info->gl_ops.gl.p_glReadPixels(0, 0, 16, 16, 2417 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback); 2418 color = readback[7 * 16 + 7]; 2419 break; 2420 2421 case WINED3D_GL_RES_TYPE_BUFFER: 2422 case WINED3D_GL_RES_TYPE_COUNT: 2423 color = 0; 2424 break; 2425 } 2426 checkGLcall("Post-pixelshader blending check"); 2427 2428 a = color >> 24; 2429 r = (color & 0x00ff0000u) >> 16; 2430 2431 r_range = format->red_size < 8 ? 1u << (8 - format->red_size) : 1; 2432 a_range = format->alpha_size < 8 ? 1u << (8 - format->alpha_size) : 1; 2433 if (format->red_size && (r < 0x7f - r_range || r > 0x7f + r_range)) 2434 match = FALSE; 2435 else if (format->alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range)) 2436 match = FALSE; 2437 if (!match) 2438 { 2439 TRACE("Format %s doesn't support post-pixelshader blending, type %u.\n", 2440 debug_d3dformat(format->id), type); 2441 TRACE("Color output: %#x\n", color); 2442 format->flags[type] &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; 2443 } 2444 else 2445 { 2446 TRACE("Format %s supports post-pixelshader blending, type %u.\n", 2447 debug_d3dformat(format->id), type); 2448 TRACE("Color output: %#x\n", color); 2449 format->flags[type] |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; 2450 } 2451 } 2452 2453 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] 2454 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL]) 2455 { 2456 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); 2457 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); 2458 gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb); 2459 checkGLcall("RB cleanup"); 2460 } 2461 } 2462 2463 if (format->glInternal != format->glGammaInternal) 2464 { 2465 delete_fbo_attachment(gl_info, type, object); 2466 create_and_bind_fbo_attachment(gl_info, format->flags[type], type, &object, format->glGammaInternal, 2467 format->glFormat, format->glType); 2468 2469 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); 2470 checkGLcall("Framebuffer format check"); 2471 2472 if (status == GL_FRAMEBUFFER_COMPLETE) 2473 { 2474 TRACE("Format %s's sRGB format is FBO attachable, type %u.\n", 2475 debug_d3dformat(format->id), type); 2476 format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; 2477 if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) 2478 format->glInternal = format->glGammaInternal; 2479 } 2480 else 2481 { 2482 WARN("Format %s's sRGB format is not FBO attachable, type %u.\n", 2483 debug_d3dformat(format->id), type); 2484 format_clear_flag(format, WINED3DFMT_FLAG_SRGB_WRITE); 2485 } 2486 } 2487 else if (status == GL_FRAMEBUFFER_COMPLETE) 2488 format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; 2489 2490 if (format->flags[type] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) 2491 { 2492 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0); 2493 gl_info->fbo_ops.glDeleteRenderbuffers(1, &color_rb); 2494 } 2495 2496 delete_fbo_attachment(gl_info, type, object); 2497 checkGLcall("Framebuffer format check cleanup"); 2498 } 2499 2500 if (fallback_fmt_used && regular_fmt_used) 2501 { 2502 FIXME("Format %s needs different render target formats for different resource types.\n", 2503 debug_d3dformat(format->id)); 2504 format_clear_flag(format, WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FBO_ATTACHABLE 2505 | WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING); 2506 } 2507 } 2508 2509 static void query_format_flag(struct wined3d_gl_info *gl_info, struct wined3d_format *format, 2510 GLint internal, GLenum pname, DWORD flag, const char *string) 2511 { 2512 GLint value; 2513 enum wined3d_gl_resource_type type; 2514 2515 for (type = 0; type < ARRAY_SIZE(format->flags); ++type) 2516 { 2517 gl_info->gl_ops.ext.p_glGetInternalformativ(wined3d_gl_type_to_enum(type), internal, pname, 1, &value); 2518 if (value == GL_FULL_SUPPORT) 2519 { 2520 TRACE("Format %s supports %s, resource type %u.\n", debug_d3dformat(format->id), string, type); 2521 format->flags[type] |= flag; 2522 } 2523 else 2524 { 2525 TRACE("Format %s doesn't support %s, resource type %u.\n", debug_d3dformat(format->id), string, type); 2526 format->flags[type] &= ~flag; 2527 } 2528 } 2529 } 2530 2531 /* Context activation is done by the caller. */ 2532 static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx) 2533 { 2534 const struct wined3d_gl_info *gl_info = ctx->gl_info; 2535 unsigned int i, type; 2536 GLuint fbo; 2537 2538 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2]) 2539 { 2540 for (i = 0; i < gl_info->format_count; ++i) 2541 { 2542 GLint value; 2543 struct wined3d_format *format = &gl_info->formats[i]; 2544 BOOL fallback_fmt_used = FALSE, regular_fmt_used = FALSE; 2545 GLenum rt_internal = format->rtInternal; 2546 2547 if (!format->glInternal) 2548 continue; 2549 2550 for (type = 0; type < ARRAY_SIZE(format->flags); ++type) 2551 { 2552 gl_info->gl_ops.ext.p_glGetInternalformativ(wined3d_gl_type_to_enum(type), 2553 format->glInternal, GL_FRAMEBUFFER_RENDERABLE, 1, &value); 2554 if (value == GL_FULL_SUPPORT) 2555 { 2556 TRACE("Format %s is supported as FBO color attachment, resource type %u.\n", 2557 debug_d3dformat(format->id), type); 2558 format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE; 2559 format->rtInternal = format->glInternal; 2560 regular_fmt_used = TRUE; 2561 2562 gl_info->gl_ops.ext.p_glGetInternalformativ(wined3d_gl_type_to_enum(type), 2563 format->glInternal, GL_FRAMEBUFFER_BLEND, 1, &value); 2564 if (value == GL_FULL_SUPPORT) 2565 { 2566 TRACE("Format %s supports post-pixelshader blending, resource type %u.\n", 2567 debug_d3dformat(format->id), type); 2568 format->flags[type] |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; 2569 } 2570 else 2571 { 2572 TRACE("Format %s doesn't support post-pixelshader blending, resource typed %u.\n", 2573 debug_d3dformat(format->id), type); 2574 format->flags[type] &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; 2575 } 2576 } 2577 else 2578 { 2579 if (!rt_internal) 2580 { 2581 if (format->flags[type] & WINED3DFMT_FLAG_RENDERTARGET) 2582 { 2583 WARN("Format %s with rendertarget flag is not supported as FBO color attachment" 2584 " and no fallback specified, resource type %u.\n", 2585 debug_d3dformat(format->id), type); 2586 format->flags[type] &= ~WINED3DFMT_FLAG_RENDERTARGET; 2587 } 2588 else 2589 TRACE("Format %s is not supported as FBO color attachment," 2590 " resource type %u.\n", debug_d3dformat(format->id), type); 2591 format->rtInternal = format->glInternal; 2592 } 2593 else 2594 { 2595 gl_info->gl_ops.ext.p_glGetInternalformativ(wined3d_gl_type_to_enum(type), 2596 rt_internal, GL_FRAMEBUFFER_RENDERABLE, 1, &value); 2597 if (value == GL_FULL_SUPPORT) 2598 { 2599 TRACE("Format %s rtInternal format is supported as FBO color attachment," 2600 " resource type %u.\n", debug_d3dformat(format->id), type); 2601 fallback_fmt_used = TRUE; 2602 } 2603 else 2604 { 2605 WARN("Format %s rtInternal format is not supported as FBO color attachment," 2606 " resource type %u.\n", debug_d3dformat(format->id), type); 2607 format->flags[type] &= ~WINED3DFMT_FLAG_RENDERTARGET; 2608 } 2609 } 2610 } 2611 2612 if (format->glInternal != format->glGammaInternal) 2613 { 2614 gl_info->gl_ops.ext.p_glGetInternalformativ(wined3d_gl_type_to_enum(type), 2615 format->glGammaInternal, GL_FRAMEBUFFER_RENDERABLE, 1, &value); 2616 if (value == GL_FULL_SUPPORT) 2617 { 2618 TRACE("Format %s's sRGB format is FBO attachable, resource type %u.\n", 2619 debug_d3dformat(format->id), type); 2620 format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; 2621 if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) 2622 format->glInternal = format->glGammaInternal; 2623 } 2624 else 2625 { 2626 WARN("Format %s's sRGB format is not FBO attachable, resource type %u.\n", 2627 debug_d3dformat(format->id), type); 2628 format_clear_flag(format, WINED3DFMT_FLAG_SRGB_WRITE); 2629 } 2630 } 2631 else if (format->flags[type] & WINED3DFMT_FLAG_FBO_ATTACHABLE) 2632 format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; 2633 } 2634 2635 if (fallback_fmt_used && regular_fmt_used) 2636 { 2637 FIXME("Format %s needs different render target formats for different resource types.\n", 2638 debug_d3dformat(format->id)); 2639 format_clear_flag(format, WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FBO_ATTACHABLE 2640 | WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING); 2641 } 2642 } 2643 return; 2644 } 2645 2646 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) 2647 { 2648 gl_info->fbo_ops.glGenFramebuffers(1, &fbo); 2649 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); 2650 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0); 2651 gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0); 2652 } 2653 2654 for (i = 0; i < gl_info->format_count; ++i) 2655 { 2656 struct wined3d_format *format = &gl_info->formats[i]; 2657 2658 if (!format->glInternal) continue; 2659 2660 if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) 2661 { 2662 TRACE("Skipping format %s because it's a compressed format.\n", 2663 debug_d3dformat(format->id)); 2664 continue; 2665 } 2666 2667 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) 2668 { 2669 TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id)); 2670 check_fbo_compat(ctx, format); 2671 } 2672 else 2673 { 2674 format->rtInternal = format->glInternal; 2675 } 2676 } 2677 2678 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) 2679 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); 2680 } 2681 2682 static GLenum lookup_gl_view_class(GLenum internal_format) 2683 { 2684 static const struct 2685 { 2686 GLenum internal_format; 2687 GLenum view_class; 2688 } 2689 view_classes[] = 2690 { 2691 /* 128-bit */ 2692 {GL_RGBA32F, GL_VIEW_CLASS_128_BITS}, 2693 {GL_RGBA32UI, GL_VIEW_CLASS_128_BITS}, 2694 {GL_RGBA32I, GL_VIEW_CLASS_128_BITS}, 2695 /* 96-bit */ 2696 {GL_RGB32F, GL_VIEW_CLASS_96_BITS}, 2697 {GL_RGB32UI, GL_VIEW_CLASS_96_BITS}, 2698 {GL_RGB32I, GL_VIEW_CLASS_96_BITS}, 2699 /* 64-bit */ 2700 {GL_RGBA16F, GL_VIEW_CLASS_64_BITS}, 2701 {GL_RG32F, GL_VIEW_CLASS_64_BITS}, 2702 {GL_RGBA16UI, GL_VIEW_CLASS_64_BITS}, 2703 {GL_RG32UI, GL_VIEW_CLASS_64_BITS}, 2704 {GL_RGBA16I, GL_VIEW_CLASS_64_BITS}, 2705 {GL_RG32I, GL_VIEW_CLASS_64_BITS}, 2706 {GL_RGBA16, GL_VIEW_CLASS_64_BITS}, 2707 {GL_RGBA16_SNORM, GL_VIEW_CLASS_64_BITS}, 2708 /* 48-bit */ 2709 {GL_RGB16, GL_VIEW_CLASS_48_BITS}, 2710 {GL_RGB16_SNORM, GL_VIEW_CLASS_48_BITS}, 2711 {GL_RGB16F, GL_VIEW_CLASS_48_BITS}, 2712 {GL_RGB16UI, GL_VIEW_CLASS_48_BITS}, 2713 {GL_RGB16I, GL_VIEW_CLASS_48_BITS}, 2714 /* 32-bit */ 2715 {GL_RG16F, GL_VIEW_CLASS_32_BITS}, 2716 {GL_R11F_G11F_B10F, GL_VIEW_CLASS_32_BITS}, 2717 {GL_R32F, GL_VIEW_CLASS_32_BITS}, 2718 {GL_RGB10_A2UI, GL_VIEW_CLASS_32_BITS}, 2719 {GL_RGBA8UI, GL_VIEW_CLASS_32_BITS}, 2720 {GL_RG16UI, GL_VIEW_CLASS_32_BITS}, 2721 {GL_R32UI, GL_VIEW_CLASS_32_BITS}, 2722 {GL_RGBA8I, GL_VIEW_CLASS_32_BITS}, 2723 {GL_RG16I, GL_VIEW_CLASS_32_BITS}, 2724 {GL_R32I, GL_VIEW_CLASS_32_BITS}, 2725 {GL_RGB10_A2, GL_VIEW_CLASS_32_BITS}, 2726 {GL_RGBA8, GL_VIEW_CLASS_32_BITS}, 2727 {GL_RG16, GL_VIEW_CLASS_32_BITS}, 2728 {GL_RGBA8_SNORM, GL_VIEW_CLASS_32_BITS}, 2729 {GL_RG16_SNORM, GL_VIEW_CLASS_32_BITS}, 2730 {GL_SRGB8_ALPHA8, GL_VIEW_CLASS_32_BITS}, 2731 {GL_RGB9_E5, GL_VIEW_CLASS_32_BITS}, 2732 /* 24-bit */ 2733 {GL_RGB8, GL_VIEW_CLASS_24_BITS}, 2734 {GL_RGB8_SNORM, GL_VIEW_CLASS_24_BITS}, 2735 {GL_SRGB8, GL_VIEW_CLASS_24_BITS}, 2736 {GL_RGB8UI, GL_VIEW_CLASS_24_BITS}, 2737 {GL_RGB8I, GL_VIEW_CLASS_24_BITS}, 2738 /* 16-bit */ 2739 {GL_R16F, GL_VIEW_CLASS_16_BITS}, 2740 {GL_RG8UI, GL_VIEW_CLASS_16_BITS}, 2741 {GL_R16UI, GL_VIEW_CLASS_16_BITS}, 2742 {GL_RG8I, GL_VIEW_CLASS_16_BITS}, 2743 {GL_R16I, GL_VIEW_CLASS_16_BITS}, 2744 {GL_RG8, GL_VIEW_CLASS_16_BITS}, 2745 {GL_R16, GL_VIEW_CLASS_16_BITS}, 2746 {GL_RG8_SNORM, GL_VIEW_CLASS_16_BITS}, 2747 {GL_R16_SNORM, GL_VIEW_CLASS_16_BITS}, 2748 /* 8-bit */ 2749 {GL_R8UI, GL_VIEW_CLASS_8_BITS}, 2750 {GL_R8I, GL_VIEW_CLASS_8_BITS}, 2751 {GL_R8, GL_VIEW_CLASS_8_BITS}, 2752 {GL_R8_SNORM, GL_VIEW_CLASS_8_BITS}, 2753 2754 /* RGTC1 */ 2755 {GL_COMPRESSED_RED_RGTC1, GL_VIEW_CLASS_RGTC1_RED}, 2756 {GL_COMPRESSED_SIGNED_RED_RGTC1, GL_VIEW_CLASS_RGTC1_RED}, 2757 /* RGTC2 */ 2758 {GL_COMPRESSED_RG_RGTC2, GL_VIEW_CLASS_RGTC2_RG}, 2759 {GL_COMPRESSED_SIGNED_RG_RGTC2, GL_VIEW_CLASS_RGTC2_RG}, 2760 2761 /* BPTC unorm */ 2762 {GL_COMPRESSED_RGBA_BPTC_UNORM, GL_VIEW_CLASS_BPTC_UNORM}, 2763 {GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, GL_VIEW_CLASS_BPTC_UNORM}, 2764 /* BPTC float */ 2765 {GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL_VIEW_CLASS_BPTC_FLOAT}, 2766 {GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL_VIEW_CLASS_BPTC_FLOAT}, 2767 2768 /* DXT1 RGB */ 2769 {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_VIEW_CLASS_S3TC_DXT1_RGB}, 2770 {GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_VIEW_CLASS_S3TC_DXT1_RGB}, 2771 /* DXT1 RGBA */ 2772 {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_VIEW_CLASS_S3TC_DXT1_RGBA}, 2773 {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_VIEW_CLASS_S3TC_DXT1_RGBA}, 2774 /* DXT3 */ 2775 {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_VIEW_CLASS_S3TC_DXT3_RGBA}, 2776 {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_VIEW_CLASS_S3TC_DXT3_RGBA}, 2777 /* DXT5 */ 2778 {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_VIEW_CLASS_S3TC_DXT5_RGBA}, 2779 {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_VIEW_CLASS_S3TC_DXT5_RGBA}, 2780 }; 2781 2782 unsigned int i; 2783 2784 for (i = 0; i < ARRAY_SIZE(view_classes); ++i) 2785 { 2786 if (view_classes[i].internal_format == internal_format) 2787 return view_classes[i].view_class; 2788 } 2789 2790 return GL_NONE; 2791 } 2792 2793 static void query_view_class(struct wined3d_format *format) 2794 { 2795 GLenum internal_view_class, gamma_view_class, rt_view_class; 2796 2797 internal_view_class = lookup_gl_view_class(format->glInternal); 2798 gamma_view_class = lookup_gl_view_class(format->glGammaInternal); 2799 rt_view_class = lookup_gl_view_class(format->rtInternal); 2800 2801 if (internal_view_class == gamma_view_class || gamma_view_class == rt_view_class) 2802 { 2803 format->gl_view_class = internal_view_class; 2804 TRACE("Format %s is member of GL view class %#x.\n", 2805 debug_d3dformat(format->id), format->gl_view_class); 2806 } 2807 else 2808 { 2809 format->gl_view_class = GL_NONE; 2810 } 2811 } 2812 2813 static void query_internal_format(struct wined3d_adapter *adapter, 2814 struct wined3d_format *format, const struct wined3d_format_texture_info *texture_info, 2815 struct wined3d_gl_info *gl_info, BOOL srgb_write_supported, BOOL srgb_format) 2816 { 2817 GLint count, multisample_types[MAX_MULTISAMPLE_TYPES]; 2818 unsigned int i, max_log2; 2819 GLenum target; 2820 2821 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2]) 2822 { 2823 query_format_flag(gl_info, format, format->glInternal, GL_VERTEX_TEXTURE, 2824 WINED3DFMT_FLAG_VTF, "vertex texture usage"); 2825 query_format_flag(gl_info, format, format->glInternal, GL_FILTER, 2826 WINED3DFMT_FLAG_FILTERING, "filtering"); 2827 2828 if (srgb_format || format->glGammaInternal != format->glInternal) 2829 { 2830 query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_READ, 2831 WINED3DFMT_FLAG_SRGB_READ, "sRGB read"); 2832 2833 if (srgb_write_supported) 2834 query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_WRITE, 2835 WINED3DFMT_FLAG_SRGB_WRITE, "sRGB write"); 2836 else 2837 format_clear_flag(format, WINED3DFMT_FLAG_SRGB_WRITE); 2838 2839 if (!(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE))) 2840 format->glGammaInternal = format->glInternal; 2841 else if (wined3d_settings.offscreen_rendering_mode != ORM_FBO 2842 && gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) 2843 format->glInternal = format->glGammaInternal; 2844 } 2845 } 2846 else 2847 { 2848 if (!gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX]) 2849 format_clear_flag(format, WINED3DFMT_FLAG_VTF); 2850 2851 if (!(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING)) 2852 format_set_flag(format, WINED3DFMT_FLAG_FILTERING); 2853 else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT) 2854 format_clear_flag(format, WINED3DFMT_FLAG_VTF); 2855 2856 if (srgb_format || format->glGammaInternal != format->glInternal) 2857 { 2858 /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */ 2859 if (!gl_info->supported[EXT_TEXTURE_SRGB]) 2860 { 2861 format->glGammaInternal = format->glInternal; 2862 format_clear_flag(format, WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE); 2863 } 2864 else if (wined3d_settings.offscreen_rendering_mode != ORM_FBO 2865 && gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) 2866 { 2867 format->glInternal = format->glGammaInternal; 2868 } 2869 } 2870 2871 if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write_supported) 2872 format_clear_flag(format, WINED3DFMT_FLAG_SRGB_WRITE); 2873 2874 if (!gl_info->supported[ARB_DEPTH_TEXTURE] 2875 && texture_info->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) 2876 { 2877 format->flags[WINED3D_GL_RES_TYPE_TEX_1D] &= ~WINED3DFMT_FLAG_TEXTURE; 2878 format->flags[WINED3D_GL_RES_TYPE_TEX_2D] &= ~WINED3DFMT_FLAG_TEXTURE; 2879 format->flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 2880 format->flags[WINED3D_GL_RES_TYPE_TEX_CUBE] &= ~WINED3DFMT_FLAG_TEXTURE; 2881 format->flags[WINED3D_GL_RES_TYPE_TEX_RECT] &= ~WINED3DFMT_FLAG_TEXTURE; 2882 } 2883 } 2884 2885 query_view_class(format); 2886 2887 if (format->glInternal && format->flags[WINED3D_GL_RES_TYPE_RB] 2888 & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) 2889 { 2890 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY]) 2891 { 2892 target = gl_info->supported[ARB_TEXTURE_MULTISAMPLE] ? GL_TEXTURE_2D_MULTISAMPLE : GL_RENDERBUFFER; 2893 count = 0; 2894 GL_EXTCALL(glGetInternalformativ(target, format->glInternal, 2895 GL_NUM_SAMPLE_COUNTS, 1, &count)); 2896 count = min(count, MAX_MULTISAMPLE_TYPES); 2897 GL_EXTCALL(glGetInternalformativ(target, format->glInternal, 2898 GL_SAMPLES, count, multisample_types)); 2899 checkGLcall("query sample counts"); 2900 for (i = 0; i < count; ++i) 2901 { 2902 if (multisample_types[i] > sizeof(format->multisample_types) * CHAR_BIT) 2903 continue; 2904 format->multisample_types |= 1u << (multisample_types[i] - 1); 2905 } 2906 } 2907 else 2908 { 2909 #ifdef __REACTOS__ 2910 if (gl_info->limits.samples) { 2911 #endif 2912 max_log2 = wined3d_log2i(min(gl_info->limits.samples, 2913 sizeof(format->multisample_types) * CHAR_BIT)); 2914 for (i = 1; i <= max_log2; ++i) 2915 format->multisample_types |= 1u << ((1u << i) - 1); 2916 #ifdef __REACTOS__ 2917 } 2918 #endif 2919 } 2920 } 2921 } 2922 2923 static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info) 2924 { 2925 struct wined3d_format *format, *srgb_format; 2926 struct fragment_caps fragment_caps; 2927 struct shader_caps shader_caps; 2928 unsigned int i, j; 2929 BOOL srgb_write; 2930 2931 adapter->fragment_pipe->get_caps(gl_info, &fragment_caps); 2932 adapter->shader_backend->shader_get_caps(gl_info, &shader_caps); 2933 srgb_write = (fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_SRGB_WRITE) 2934 && (shader_caps.wined3d_caps & WINED3D_SHADER_CAP_SRGB_WRITE); 2935 2936 for (i = 0; i < ARRAY_SIZE(format_texture_info); ++i) 2937 { 2938 if (!(format = get_format_internal(gl_info, format_texture_info[i].id))) 2939 return FALSE; 2940 2941 if (!gl_info->supported[format_texture_info[i].extension]) 2942 continue; 2943 2944 /* ARB_texture_rg defines floating point formats, but only if 2945 * ARB_texture_float is also supported. */ 2946 if (!gl_info->supported[ARB_TEXTURE_FLOAT] 2947 && (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT)) 2948 continue; 2949 2950 /* ARB_texture_rg defines integer formats if EXT_texture_integer is also supported. */ 2951 if (!gl_info->supported[EXT_TEXTURE_INTEGER] 2952 && (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_INTEGER)) 2953 continue; 2954 2955 format->glInternal = format_texture_info[i].gl_internal; 2956 format->glGammaInternal = format_texture_info[i].gl_srgb_internal; 2957 format->rtInternal = format_texture_info[i].gl_rt_internal; 2958 format->glFormat = format_texture_info[i].gl_format; 2959 format->glType = format_texture_info[i].gl_type; 2960 format->color_fixup = COLOR_FIXUP_IDENTITY; 2961 format->height_scale.numerator = 1; 2962 format->height_scale.denominator = 1; 2963 2964 format->flags[WINED3D_GL_RES_TYPE_TEX_1D] |= format_texture_info[i].flags; 2965 format->flags[WINED3D_GL_RES_TYPE_TEX_2D] |= format_texture_info[i].flags; 2966 format->flags[WINED3D_GL_RES_TYPE_BUFFER] |= format_texture_info[i].flags; 2967 2968 /* GL_ARB_depth_texture does not support 3D textures. It also says "cube textures are 2969 * problematic", but doesn't explicitly mandate that an error is generated. */ 2970 if (gl_info->supported[EXT_TEXTURE3D] 2971 && !(format_texture_info[i].flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) 2972 format->flags[WINED3D_GL_RES_TYPE_TEX_3D] |= format_texture_info[i].flags; 2973 2974 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) 2975 format->flags[WINED3D_GL_RES_TYPE_TEX_CUBE] |= format_texture_info[i].flags; 2976 2977 if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) 2978 format->flags[WINED3D_GL_RES_TYPE_TEX_RECT] |= format_texture_info[i].flags; 2979 2980 format->flags[WINED3D_GL_RES_TYPE_RB] |= format_texture_info[i].flags; 2981 format->flags[WINED3D_GL_RES_TYPE_RB] &= ~WINED3DFMT_FLAG_TEXTURE; 2982 2983 if (format->glGammaInternal != format->glInternal 2984 && !(adapter->d3d_info.wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL)) 2985 { 2986 format->glGammaInternal = format->glInternal; 2987 format_clear_flag(format, WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE); 2988 } 2989 2990 query_internal_format(adapter, format, &format_texture_info[i], gl_info, srgb_write, FALSE); 2991 2992 /* Texture conversion stuff */ 2993 format->conv_byte_count = format_texture_info[i].conv_byte_count; 2994 format->upload = format_texture_info[i].upload; 2995 format->download = format_texture_info[i].download; 2996 2997 srgb_format = NULL; 2998 for (j = 0; j < ARRAY_SIZE(format_srgb_info); ++j) 2999 { 3000 if (format_srgb_info[j].base_format_id == format->id) 3001 { 3002 if (!(srgb_format = get_format_internal(gl_info, format_srgb_info[j].srgb_format_id))) 3003 return FALSE; 3004 break; 3005 } 3006 } 3007 if (!srgb_format) 3008 continue; 3009 3010 copy_format(srgb_format, format); 3011 3012 if (gl_info->supported[EXT_TEXTURE_SRGB] 3013 && !(adapter->d3d_info.wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL)) 3014 { 3015 srgb_format->glInternal = format_texture_info[i].gl_srgb_internal; 3016 srgb_format->glGammaInternal = format_texture_info[i].gl_srgb_internal; 3017 format_set_flag(srgb_format, WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE); 3018 query_internal_format(adapter, srgb_format, &format_texture_info[i], gl_info, srgb_write, TRUE); 3019 } 3020 } 3021 3022 return TRUE; 3023 } 3024 3025 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff) 3026 { 3027 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE; 3028 c1 >>= 8; c2 >>= 8; 3029 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE; 3030 c1 >>= 8; c2 >>= 8; 3031 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE; 3032 c1 >>= 8; c2 >>= 8; 3033 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE; 3034 return TRUE; 3035 } 3036 3037 /* A context is provided by the caller */ 3038 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal) 3039 { 3040 static const DWORD data[] = {0x00000000, 0xffffffff}; 3041 GLuint tex, fbo, buffer; 3042 DWORD readback[16 * 1]; 3043 BOOL ret = FALSE; 3044 3045 /* Render a filtered texture and see what happens. This is intended to detect the lack of 3046 * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of 3047 * falling back to software. If this changes in the future this code will get fooled and 3048 * apps might hit the software path due to incorrectly advertised caps. 3049 * 3050 * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter 3051 * disable fallback, if Apple or ATI ever change the driver behavior they will break more 3052 * than Wine. The Linux binary <= r500 driver is not maintained any more anyway 3053 */ 3054 3055 while (gl_info->gl_ops.gl.p_glGetError()); 3056 3057 gl_info->gl_ops.gl.p_glGenTextures(1, &buffer); 3058 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer); 3059 memset(readback, 0x7e, sizeof(readback)); 3060 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, 3061 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback); 3062 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3063 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3064 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 3065 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 3066 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 3067 3068 gl_info->gl_ops.gl.p_glGenTextures(1, &tex); 3069 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex); 3070 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, 3071 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); 3072 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 3073 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 3074 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 3075 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 3076 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 3077 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D); 3078 3079 gl_info->fbo_ops.glGenFramebuffers(1, &fbo); 3080 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); 3081 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0); 3082 gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0); 3083 3084 gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1); 3085 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING); 3086 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW); 3087 gl_info->gl_ops.gl.p_glLoadIdentity(); 3088 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION); 3089 gl_info->gl_ops.gl.p_glLoadIdentity(); 3090 3091 gl_info->gl_ops.gl.p_glClearColor(0, 1, 0, 0); 3092 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT); 3093 3094 gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP); 3095 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 0.0); 3096 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, -1.0f); 3097 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 0.0); 3098 gl_info->gl_ops.gl.p_glVertex2f(1.0f, -1.0f); 3099 gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 1.0); 3100 gl_info->gl_ops.gl.p_glVertex2f(-1.0f, 1.0f); 3101 gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 1.0); 3102 gl_info->gl_ops.gl.p_glVertex2f(1.0f, 1.0f); 3103 gl_info->gl_ops.gl.p_glEnd(); 3104 3105 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer); 3106 memset(readback, 0x7f, sizeof(readback)); 3107 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback); 3108 if (color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) 3109 || color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5)) 3110 { 3111 TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, assuming no filtering\n", 3112 readback[6], readback[9]); 3113 ret = FALSE; 3114 } 3115 else 3116 { 3117 TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n", 3118 readback[6], readback[9]); 3119 ret = TRUE; 3120 } 3121 3122 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0); 3123 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); 3124 gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex); 3125 gl_info->gl_ops.gl.p_glDeleteTextures(1, &buffer); 3126 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); 3127 3128 if (gl_info->gl_ops.gl.p_glGetError()) 3129 { 3130 FIXME("Error during filtering test for format %x, returning no filtering\n", internal); 3131 ret = FALSE; 3132 } 3133 3134 return ret; 3135 } 3136 3137 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor) 3138 { 3139 struct wined3d_format *format; 3140 unsigned int fmt_idx, i; 3141 static const enum wined3d_format_id fmts16[] = 3142 { 3143 WINED3DFMT_R16_FLOAT, 3144 WINED3DFMT_R16G16_FLOAT, 3145 WINED3DFMT_R16G16B16A16_FLOAT, 3146 }; 3147 BOOL filtered; 3148 3149 if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2]) 3150 /* This was already handled by init_format_texture_info(). */ 3151 return; 3152 3153 if (wined3d_settings.offscreen_rendering_mode != ORM_FBO 3154 || !gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) 3155 { 3156 WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n"); 3157 if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT]) 3158 { 3159 TRACE("Nvidia card with texture_float support: Assuming float16 blending\n"); 3160 filtered = TRUE; 3161 } 3162 else if (gl_info->limits.glsl_varyings > 44) 3163 { 3164 TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n"); 3165 filtered = TRUE; 3166 } 3167 else 3168 { 3169 TRACE("Assuming no float16 blending\n"); 3170 filtered = FALSE; 3171 } 3172 3173 if (filtered) 3174 { 3175 for (i = 0; i < ARRAY_SIZE(fmts16); ++i) 3176 { 3177 fmt_idx = get_format_idx(fmts16[i]); 3178 format_set_flag(&gl_info->formats[fmt_idx], WINED3DFMT_FLAG_FILTERING); 3179 } 3180 } 3181 return; 3182 } 3183 3184 for (i = 0; i < ARRAY_SIZE(fmts16); ++i) 3185 { 3186 fmt_idx = get_format_idx(fmts16[i]); 3187 format = &gl_info->formats[fmt_idx]; 3188 if (!format->glInternal) continue; /* Not supported by GL */ 3189 3190 filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal); 3191 if (filtered) 3192 { 3193 TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i])); 3194 format_set_flag(format, WINED3DFMT_FLAG_FILTERING); 3195 } 3196 else 3197 { 3198 TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i])); 3199 } 3200 } 3201 } 3202 3203 static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info) 3204 { 3205 unsigned int i; 3206 int idx; 3207 3208 idx = get_format_idx(WINED3DFMT_R16_FLOAT); 3209 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3210 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W); 3211 3212 idx = get_format_idx(WINED3DFMT_R32_FLOAT); 3213 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3214 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W); 3215 3216 idx = get_format_idx(WINED3DFMT_R16G16_UNORM); 3217 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3218 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W); 3219 3220 idx = get_format_idx(WINED3DFMT_R16G16_FLOAT); 3221 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3222 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W); 3223 3224 idx = get_format_idx(WINED3DFMT_R32G32_FLOAT); 3225 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3226 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W); 3227 3228 /* GL_ATI_envmap_bumpmap in theory supports R8G8_SNORM but is no longer supported by 3229 * any driver. */ 3230 if (gl_info->supported[NV_TEXTURE_SHADER] || gl_info->supported[EXT_TEXTURE_SNORM]) 3231 { 3232 /* R8G8_SNORM and R16G16_SNORM need a fixup of the undefined blue channel. OpenGL 3233 * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader 3234 * conversion for this format. */ 3235 idx = get_format_idx(WINED3DFMT_R8G8_SNORM); 3236 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3237 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); 3238 idx = get_format_idx(WINED3DFMT_R16G16_SNORM); 3239 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3240 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); 3241 } 3242 else 3243 { 3244 /* Emulate using unsigned formats. This requires load-time conversion in addition to the 3245 * fixups here. */ 3246 idx = get_format_idx(WINED3DFMT_R8G8_SNORM); 3247 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3248 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); 3249 idx = get_format_idx(WINED3DFMT_R16G16_SNORM); 3250 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3251 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); 3252 idx = get_format_idx(WINED3DFMT_R8G8B8A8_SNORM); 3253 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3254 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W); 3255 idx = get_format_idx(WINED3DFMT_R5G5_SNORM_L6_UNORM); 3256 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3257 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE); 3258 } 3259 3260 if (!gl_info->supported[NV_TEXTURE_SHADER]) 3261 { 3262 idx = get_format_idx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM); 3263 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3264 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W); 3265 } 3266 3267 if (gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] || gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC]) 3268 { 3269 idx = get_format_idx(WINED3DFMT_ATI1N); 3270 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3271 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X); 3272 3273 idx = get_format_idx(WINED3DFMT_ATI2N); 3274 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3275 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); 3276 } 3277 else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC]) 3278 { 3279 idx = get_format_idx(WINED3DFMT_ATI2N); 3280 gl_info->formats[idx].color_fixup= create_color_fixup_desc( 3281 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); 3282 } 3283 3284 if (!gl_info->supported[APPLE_YCBCR_422] && gl_info->supported[ARB_FRAGMENT_PROGRAM] 3285 && gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) 3286 { 3287 idx = get_format_idx(WINED3DFMT_YUY2); 3288 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2); 3289 3290 idx = get_format_idx(WINED3DFMT_UYVY); 3291 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY); 3292 } 3293 else if (!gl_info->supported[APPLE_YCBCR_422] && (!gl_info->supported[ARB_FRAGMENT_PROGRAM] 3294 || !gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])) 3295 { 3296 idx = get_format_idx(WINED3DFMT_YUY2); 3297 gl_info->formats[idx].glInternal = 0; 3298 3299 idx = get_format_idx(WINED3DFMT_UYVY); 3300 gl_info->formats[idx].glInternal = 0; 3301 } 3302 3303 if (gl_info->supported[ARB_FRAGMENT_PROGRAM] && gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) 3304 { 3305 idx = get_format_idx(WINED3DFMT_YV12); 3306 format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_HEIGHT_SCALE); 3307 gl_info->formats[idx].height_scale.numerator = 3; 3308 gl_info->formats[idx].height_scale.denominator = 2; 3309 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12); 3310 3311 idx = get_format_idx(WINED3DFMT_NV12); 3312 format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_HEIGHT_SCALE); 3313 gl_info->formats[idx].height_scale.numerator = 3; 3314 gl_info->formats[idx].height_scale.denominator = 2; 3315 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_NV12); 3316 } 3317 else 3318 { 3319 idx = get_format_idx(WINED3DFMT_YV12); 3320 gl_info->formats[idx].glInternal = 0; 3321 3322 idx = get_format_idx(WINED3DFMT_NV12); 3323 gl_info->formats[idx].glInternal = 0; 3324 } 3325 3326 if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) 3327 { 3328 idx = get_format_idx(WINED3DFMT_A8_UNORM); 3329 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3330 0, CHANNEL_SOURCE_ZERO, 0, CHANNEL_SOURCE_ZERO, 0, CHANNEL_SOURCE_ZERO, 0, CHANNEL_SOURCE_X); 3331 idx = get_format_idx(WINED3DFMT_L8A8_UNORM); 3332 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3333 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y); 3334 idx = get_format_idx(WINED3DFMT_L4A4_UNORM); 3335 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3336 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y); 3337 idx = get_format_idx(WINED3DFMT_L16_UNORM); 3338 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3339 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE); 3340 idx = get_format_idx(WINED3DFMT_INTZ); 3341 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3342 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X); 3343 } 3344 3345 if (gl_info->supported[ARB_TEXTURE_RG]) 3346 { 3347 idx = get_format_idx(WINED3DFMT_L8_UNORM); 3348 gl_info->formats[idx].color_fixup = create_color_fixup_desc( 3349 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE); 3350 } 3351 3352 if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) 3353 { 3354 idx = get_format_idx(WINED3DFMT_P8_UINT); 3355 gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8); 3356 } 3357 3358 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) 3359 { 3360 idx = get_format_idx(WINED3DFMT_B8G8R8A8_UNORM); 3361 gl_info->formats[idx].gl_vtx_format = GL_BGRA; 3362 } 3363 3364 if (!gl_info->supported[ARB_HALF_FLOAT_VERTEX]) 3365 { 3366 /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though. 3367 * It is the job of the vertex buffer code to make sure that the vbos have the right format */ 3368 idx = get_format_idx(WINED3DFMT_R16G16_FLOAT); 3369 gl_info->formats[idx].gl_vtx_type = GL_FLOAT; 3370 3371 idx = get_format_idx(WINED3DFMT_R16G16B16A16_FLOAT); 3372 gl_info->formats[idx].gl_vtx_type = GL_FLOAT; 3373 } 3374 3375 if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL]) 3376 { 3377 idx = get_format_idx(WINED3DFMT_R16_FLOAT); 3378 format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE); 3379 3380 idx = get_format_idx(WINED3DFMT_R16G16_FLOAT); 3381 format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE); 3382 3383 idx = get_format_idx(WINED3DFMT_R16G16B16A16_FLOAT); 3384 format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE); 3385 } 3386 3387 if (gl_info->quirks & WINED3D_QUIRK_BROKEN_RGBA16) 3388 { 3389 idx = get_format_idx(WINED3DFMT_R16G16B16A16_UNORM); 3390 format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE); 3391 } 3392 3393 /* ATI instancing hack: Although ATI cards do not support Shader Model 3394 * 3.0, they support instancing. To query if the card supports instancing 3395 * CheckDeviceFormat() with the special format MAKEFOURCC('I','N','S','T') 3396 * is used. Should an application check for this, provide a proper return 3397 * value. We can do instancing with all shader versions, but we need 3398 * vertex shaders. 3399 * 3400 * Additionally applications have to set the D3DRS_POINTSIZE render state 3401 * to MAKEFOURCC('I','N','S','T') once to enable instancing. Wined3d 3402 * doesn't need that and just ignores it. 3403 * 3404 * With Shader Model 3.0 capable cards Instancing 'just works' in Windows. */ 3405 /* FIXME: This should just check the shader backend caps. */ 3406 if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER]) 3407 { 3408 idx = get_format_idx(WINED3DFMT_INST); 3409 format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE); 3410 } 3411 3412 /* Depth bound test. To query if the card supports it CheckDeviceFormat() 3413 * with the special format MAKEFOURCC('N','V','D','B') is used. It is 3414 * enabled by setting D3DRS_ADAPTIVETESS_X render state to 3415 * MAKEFOURCC('N','V','D','B') and then controlled by setting 3416 * D3DRS_ADAPTIVETESS_Z (zMin) and D3DRS_ADAPTIVETESS_W (zMax) to test 3417 * value. */ 3418 if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST]) 3419 { 3420 idx = get_format_idx(WINED3DFMT_NVDB); 3421 format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE); 3422 } 3423 3424 /* RESZ aka AMD DX9-level hack for multisampled depth buffer resolve. You query for RESZ 3425 * support by checking for availability of MAKEFOURCC('R','E','S','Z') surfaces with 3426 * RENDERTARGET usage. */ 3427 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]) 3428 { 3429 idx = get_format_idx(WINED3DFMT_RESZ); 3430 format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET); 3431 } 3432 3433 for (i = 0; i < gl_info->format_count; ++i) 3434 { 3435 struct wined3d_format *format = &gl_info->formats[i]; 3436 3437 if (!(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE)) 3438 continue; 3439 3440 if (is_identity_fixup(format->color_fixup)) 3441 continue; 3442 3443 TRACE("Checking support for fixup:\n"); 3444 dump_color_fixup_desc(format->color_fixup); 3445 if (!adapter->shader_backend->shader_color_fixup_supported(format->color_fixup) 3446 || !adapter->fragment_pipe->color_fixup_supported(format->color_fixup)) 3447 { 3448 TRACE("[FAILED]\n"); 3449 format_clear_flag(format, WINED3DFMT_FLAG_TEXTURE); 3450 } 3451 else 3452 { 3453 TRACE("[OK]\n"); 3454 } 3455 } 3456 3457 /* GL_EXT_texture_compression_s3tc does not support 3D textures. Some Windows drivers 3458 * for dx9 GPUs support it, some do not, so not supporting DXTn volumes is OK for d3d9. 3459 * 3460 * Note that GL_NV_texture_compression_vtc adds this functionality to OpenGL, but the 3461 * block layout is not compatible with the one used by d3d. See volume_dxt5_test. */ 3462 idx = get_format_idx(WINED3DFMT_DXT1); 3463 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3464 idx = get_format_idx(WINED3DFMT_DXT2); 3465 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3466 idx = get_format_idx(WINED3DFMT_DXT3); 3467 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3468 idx = get_format_idx(WINED3DFMT_DXT4); 3469 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3470 idx = get_format_idx(WINED3DFMT_DXT5); 3471 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3472 idx = get_format_idx(WINED3DFMT_BC1_UNORM); 3473 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3474 idx = get_format_idx(WINED3DFMT_BC1_UNORM_SRGB); 3475 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3476 idx = get_format_idx(WINED3DFMT_BC2_UNORM); 3477 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3478 idx = get_format_idx(WINED3DFMT_BC2_UNORM_SRGB); 3479 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3480 idx = get_format_idx(WINED3DFMT_BC3_UNORM); 3481 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3482 idx = get_format_idx(WINED3DFMT_BC3_UNORM_SRGB); 3483 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3484 /* Similarly with ATI1N / ATI2N and GL_ARB_texture_compression_rgtc. */ 3485 idx = get_format_idx(WINED3DFMT_ATI1N); 3486 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3487 idx = get_format_idx(WINED3DFMT_ATI2N); 3488 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3489 idx = get_format_idx(WINED3DFMT_BC4_UNORM); 3490 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3491 idx = get_format_idx(WINED3DFMT_BC4_SNORM); 3492 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3493 idx = get_format_idx(WINED3DFMT_BC5_UNORM); 3494 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3495 idx = get_format_idx(WINED3DFMT_BC5_SNORM); 3496 gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; 3497 } 3498 3499 static unsigned int calculate_vertex_attribute_size(GLenum type, unsigned int component_count) 3500 { 3501 switch (type) 3502 { 3503 case GL_HALF_FLOAT: 3504 return component_count * sizeof(GLhalfNV); 3505 case GL_FLOAT: 3506 return component_count * sizeof(GLfloat); 3507 case GL_BYTE: 3508 return component_count * sizeof(GLbyte); 3509 case GL_UNSIGNED_BYTE: 3510 return component_count * sizeof(GLubyte); 3511 case GL_SHORT: 3512 return component_count * sizeof(GLshort); 3513 case GL_UNSIGNED_SHORT: 3514 return component_count * sizeof(GLushort); 3515 case GL_INT: 3516 return component_count * sizeof(GLint); 3517 case GL_UNSIGNED_INT: 3518 return component_count * sizeof(GLuint); 3519 case GL_UNSIGNED_INT_2_10_10_10_REV: 3520 return sizeof(GLuint); 3521 default: 3522 FIXME("Unhandled GL type %#x.\n", type); 3523 return 0; 3524 } 3525 } 3526 3527 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info) 3528 { 3529 struct wined3d_format *format; 3530 unsigned int i; 3531 3532 for (i = 0; i < ARRAY_SIZE(format_vertex_info); ++i) 3533 { 3534 if (!(format = get_format_internal(gl_info, format_vertex_info[i].id))) 3535 return FALSE; 3536 3537 if (!gl_info->supported[format_vertex_info[i].extension]) 3538 continue; 3539 3540 format->emit_idx = format_vertex_info[i].emit_idx; 3541 format->component_count = format_vertex_info[i].component_count; 3542 format->gl_vtx_type = format_vertex_info[i].gl_vtx_type; 3543 format->gl_vtx_format = format_vertex_info[i].component_count; 3544 format->gl_normalized = format_vertex_info[i].gl_normalized; 3545 if (!(format->attribute_size = calculate_vertex_attribute_size(format->gl_vtx_type, 3546 format->component_count))) 3547 { 3548 ERR("Invalid attribute size for vertex format %s (%#x).\n", 3549 debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id); 3550 return FALSE; 3551 } 3552 } 3553 3554 return TRUE; 3555 } 3556 3557 static BOOL init_typeless_formats(struct wined3d_gl_info *gl_info) 3558 { 3559 unsigned int flags[WINED3D_GL_RES_TYPE_COUNT]; 3560 unsigned int i, j; 3561 3562 for (i = 0; i < ARRAY_SIZE(typed_formats); ++i) 3563 { 3564 struct wined3d_format *format, *typeless_format; 3565 3566 if (!(format = get_format_internal(gl_info, typed_formats[i].id))) 3567 return FALSE; 3568 if (!(typeless_format = get_format_internal(gl_info, typed_formats[i].typeless_id))) 3569 return FALSE; 3570 3571 memcpy(flags, typeless_format->flags, sizeof(flags)); 3572 copy_format(typeless_format, format); 3573 for (j = 0; j < ARRAY_SIZE(typeless_format->flags); ++j) 3574 typeless_format->flags[j] |= flags[j]; 3575 } 3576 3577 for (i = 0; i < ARRAY_SIZE(typeless_depth_stencil_formats); ++i) 3578 { 3579 struct wined3d_format *typeless_format, *typeless_ds_format, *ds_format; 3580 struct wined3d_format *depth_view_format, *stencil_view_format; 3581 enum wined3d_format_id format_id; 3582 3583 if (!(typeless_format = get_format_internal(gl_info, typeless_depth_stencil_formats[i].typeless_id))) 3584 return FALSE; 3585 if (!(ds_format = get_format_internal(gl_info, typeless_depth_stencil_formats[i].depth_stencil_id))) 3586 return FALSE; 3587 3588 typeless_ds_format = &gl_info->formats[WINED3D_FORMAT_COUNT + i]; 3589 typeless_ds_format->id = typeless_depth_stencil_formats[i].typeless_id; 3590 copy_format(typeless_ds_format, ds_format); 3591 for (j = 0; j < ARRAY_SIZE(typeless_ds_format->flags); ++j) 3592 { 3593 typeless_ds_format->flags[j] = typeless_format->flags[j]; 3594 typeless_format->flags[j] &= ~(WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); 3595 } 3596 3597 if ((format_id = typeless_depth_stencil_formats[i].depth_view_id) 3598 && typeless_depth_stencil_formats[i].separate_depth_view_format) 3599 { 3600 if (!(depth_view_format = get_format_internal(gl_info, format_id))) 3601 return FALSE; 3602 copy_format(depth_view_format, ds_format); 3603 } 3604 if ((format_id = typeless_depth_stencil_formats[i].stencil_view_id)) 3605 { 3606 if (!(stencil_view_format = get_format_internal(gl_info, format_id))) 3607 return FALSE; 3608 copy_format(stencil_view_format, ds_format); 3609 } 3610 } 3611 3612 return TRUE; 3613 } 3614 3615 static void init_format_gen_mipmap_info(struct wined3d_gl_info *gl_info) 3616 { 3617 unsigned int i, j; 3618 3619 if (!gl_info->fbo_ops.glGenerateMipmap) 3620 return; 3621 3622 for (i = 0; i < gl_info->format_count; ++i) 3623 { 3624 struct wined3d_format *format = &gl_info->formats[i]; 3625 3626 for (j = 0; j < ARRAY_SIZE(format->flags); ++j) 3627 if (!(~format->flags[j] & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING))) 3628 format->flags[j] |= WINED3DFMT_FLAG_GEN_MIPMAP; 3629 } 3630 } 3631 3632 BOOL wined3d_caps_gl_ctx_test_viewport_subpixel_bits(struct wined3d_caps_gl_ctx *ctx) 3633 { 3634 static const struct wined3d_color red = {1.0f, 0.0f, 0.0f, 1.0f}; 3635 const struct wined3d_gl_info *gl_info = ctx->gl_info; 3636 static const float offset = -63.0f / 128.0f; 3637 GLuint texture, fbo; 3638 DWORD readback[4]; 3639 unsigned int i; 3640 3641 gl_info->gl_ops.gl.p_glGenTextures(1, &texture); 3642 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, texture); 3643 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); 3644 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ARRAY_SIZE(readback), 1, 0, 3645 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); 3646 gl_info->fbo_ops.glGenFramebuffers(1, &fbo); 3647 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); 3648 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 3649 GL_TEXTURE_2D, texture, 0); 3650 checkGLcall("create resources"); 3651 3652 gl_info->gl_ops.gl.p_glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 3653 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT); 3654 GL_EXTCALL(glViewportIndexedf(0, offset, offset, 4.0f, 1.0f)); 3655 draw_test_quad(ctx, NULL, &red); 3656 checkGLcall("draw"); 3657 3658 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, texture); 3659 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, 3660 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback); 3661 checkGLcall("readback"); 3662 3663 TRACE("Readback colors are 0x%08x, 0x%08x, 0x%08x, 0x%08x.\n", 3664 readback[0], readback[1], readback[2], readback[3]); 3665 3666 gl_info->gl_ops.gl.p_glDeleteTextures(1, &texture); 3667 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); 3668 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0); 3669 checkGLcall("delete resources"); 3670 3671 for (i = 0; i < ARRAY_SIZE(readback); ++i) 3672 { 3673 if (readback[i] != 0xffff0000) 3674 return FALSE; 3675 } 3676 return TRUE; 3677 } 3678 3679 static float wined3d_adapter_find_polyoffset_scale(struct wined3d_caps_gl_ctx *ctx, GLenum format) 3680 { 3681 const struct wined3d_gl_info *gl_info = ctx->gl_info; 3682 static const struct wined3d_color blue = {0.0f, 0.0f, 1.0f, 1.0f}; 3683 GLuint fbo, color, depth; 3684 unsigned int low = 0, high = 32, cur; 3685 DWORD readback[256]; 3686 static const struct wined3d_vec3 geometry[] = 3687 { 3688 {-1.0f, -1.0f, -1.0f}, 3689 { 1.0f, -1.0f, 0.0f}, 3690 {-1.0f, 1.0f, -1.0f}, 3691 { 1.0f, 1.0f, 0.0f}, 3692 }; 3693 3694 /* Most drivers want 2^23 for fixed point depth buffers, including r300g, r600g, 3695 * Nvidia. Use this as a fallback if the detection fails. */ 3696 unsigned int fallback = 23; 3697 3698 if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) 3699 { 3700 FIXME("No FBOs, assuming polyoffset scale of 2^%u.\n", fallback); 3701 return (float)(1u << fallback); 3702 } 3703 3704 gl_info->gl_ops.gl.p_glGenTextures(1, &color); 3705 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, color); 3706 gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); 3707 gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0); 3708 3709 gl_info->fbo_ops.glGenRenderbuffers(1, &depth); 3710 gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, depth); 3711 gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, format, 256, 1); 3712 3713 gl_info->fbo_ops.glGenFramebuffers(1, &fbo); 3714 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); 3715 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0); 3716 gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth); 3717 checkGLcall("Setup framebuffer"); 3718 3719 gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.5f, 0.0f); 3720 gl_info->gl_ops.gl.p_glClearDepth(0.5f); 3721 gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_TEST); 3722 gl_info->gl_ops.gl.p_glEnable(GL_POLYGON_OFFSET_FILL); 3723 gl_info->gl_ops.gl.p_glViewport(0, 0, 256, 1); 3724 checkGLcall("Misc parameters"); 3725 3726 for (;;) 3727 { 3728 if (high - low <= 1) 3729 { 3730 ERR("PolygonOffset scale factor detection failed, using fallback value 2^%u.\n", fallback); 3731 cur = fallback; 3732 break; 3733 } 3734 cur = (low + high) / 2; 3735 3736 gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 3737 /* The post viewport transform Z of the geometry runs from 0.0 to 0.5. We want to push it another 3738 * 0.25 so that the Z buffer content (0.5) cuts the quad off at half the screen. */ 3739 gl_info->gl_ops.gl.p_glPolygonOffset(0.0f, (float)(1u << cur) * 0.25f); 3740 draw_test_quad(ctx, geometry, &blue); 3741 checkGLcall("Test draw"); 3742 3743 /* Rebinding texture to workaround a fglrx bug. */ 3744 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, color); 3745 gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback); 3746 checkGLcall("readback"); 3747 3748 TRACE("low %02u, high %02u, cur %2u, 0=0x%08x, 125=0x%08x, 131=0x%08x, 255=0x%08x\n", 3749 low, high, cur, readback[0], readback[125], readback[131], readback[255]); 3750 3751 if ((readback[125] & 0xff) < 0xa0) 3752 high = cur; 3753 else if ((readback[131] & 0xff) > 0xa0) 3754 low = cur; 3755 else 3756 { 3757 TRACE("Found scale factor 2^%u for format %x.\n", cur, format); 3758 break; 3759 } 3760 } 3761 3762 gl_info->gl_ops.gl.p_glDeleteTextures(1, &color); 3763 gl_info->fbo_ops.glDeleteRenderbuffers(1, &depth); 3764 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); 3765 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0); 3766 checkGLcall("Delete framebuffer"); 3767 3768 gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST); 3769 gl_info->gl_ops.gl.p_glDisable(GL_POLYGON_OFFSET_FILL); 3770 return (float)(1u << cur); 3771 } 3772 3773 static void init_format_depth_bias_scale(struct wined3d_caps_gl_ctx *ctx, 3774 const struct wined3d_d3d_info *d3d_info) 3775 { 3776 const struct wined3d_gl_info *gl_info = ctx->gl_info; 3777 unsigned int i; 3778 3779 for (i = 0; i < gl_info->format_count; ++i) 3780 { 3781 struct wined3d_format *format = &gl_info->formats[i]; 3782 3783 if (format->flags[WINED3D_GL_RES_TYPE_RB] & WINED3DFMT_FLAG_DEPTH) 3784 { 3785 TRACE("Testing depth bias scale for format %s.\n", debug_d3dformat(format->id)); 3786 format->depth_bias_scale = wined3d_adapter_find_polyoffset_scale(ctx, format->glInternal); 3787 3788 if (!(d3d_info->wined3d_creation_flags & WINED3D_NORMALIZED_DEPTH_BIAS)) 3789 { 3790 /* The single-precision binary floating-point format has 3791 * a significand precision of 24 bits. 3792 */ 3793 if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT) 3794 format->depth_bias_scale /= 1u << 24; 3795 else 3796 format->depth_bias_scale /= 1u << format->depth_size; 3797 } 3798 } 3799 } 3800 } 3801 3802 /* Context activation is done by the caller. */ 3803 BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter, struct wined3d_caps_gl_ctx *ctx) 3804 { 3805 struct wined3d_gl_info *gl_info = &adapter->gl_info; 3806 3807 if (!init_format_base_info(gl_info)) return FALSE; 3808 if (!init_format_block_info(gl_info)) goto fail; 3809 3810 if (!ctx) /* WINED3D_NO3D */ 3811 return TRUE; 3812 3813 if (!init_format_texture_info(adapter, gl_info)) goto fail; 3814 if (!init_format_vertex_info(gl_info)) goto fail; 3815 3816 apply_format_fixups(adapter, gl_info); 3817 init_format_fbo_compat_info(ctx); 3818 init_format_filter_info(gl_info, adapter->driver_info.vendor); 3819 if (!init_typeless_formats(gl_info)) goto fail; 3820 init_format_gen_mipmap_info(gl_info); 3821 init_format_depth_bias_scale(ctx, &adapter->d3d_info); 3822 3823 return TRUE; 3824 3825 fail: 3826 heap_free(gl_info->formats); 3827 gl_info->formats = NULL; 3828 return FALSE; 3829 } 3830 3831 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info, 3832 enum wined3d_format_id format_id, unsigned int resource_usage) 3833 { 3834 const struct wined3d_format *format; 3835 int idx = get_format_idx(format_id); 3836 unsigned int i; 3837 3838 if (idx == -1) 3839 { 3840 FIXME("Can't find format %s (%#x) in the format lookup table.\n", 3841 debug_d3dformat(format_id), format_id); 3842 return &gl_info->formats[get_format_idx(WINED3DFMT_UNKNOWN)]; 3843 } 3844 3845 format = &gl_info->formats[idx]; 3846 3847 if (resource_usage & WINED3DUSAGE_DEPTHSTENCIL && wined3d_format_is_typeless(format)) 3848 { 3849 for (i = 0; i < ARRAY_SIZE(typeless_depth_stencil_formats); ++i) 3850 { 3851 if (typeless_depth_stencil_formats[i].typeless_id == format_id) 3852 return &gl_info->formats[WINED3D_FORMAT_COUNT + i]; 3853 } 3854 3855 FIXME("Cannot find depth/stencil typeless format %s (%#x).\n", 3856 debug_d3dformat(format_id), format_id); 3857 return &gl_info->formats[get_format_idx(WINED3DFMT_UNKNOWN)]; 3858 } 3859 3860 return format; 3861 } 3862 3863 BOOL wined3d_format_is_depth_view(enum wined3d_format_id resource_format_id, 3864 enum wined3d_format_id view_format_id) 3865 { 3866 unsigned int i; 3867 3868 for (i = 0; i < ARRAY_SIZE(typeless_depth_stencil_formats); ++i) 3869 { 3870 if (typeless_depth_stencil_formats[i].typeless_id == resource_format_id) 3871 return typeless_depth_stencil_formats[i].depth_view_id == view_format_id; 3872 } 3873 return FALSE; 3874 } 3875 3876 void wined3d_format_calculate_pitch(const struct wined3d_format *format, unsigned int alignment, 3877 unsigned int width, unsigned int height, unsigned int *row_pitch, unsigned int *slice_pitch) 3878 { 3879 /* For block based formats, pitch means the amount of bytes to the next 3880 * row of blocks rather than the next row of pixels. */ 3881 if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_BLOCKS) 3882 { 3883 unsigned int row_block_count = (width + format->block_width - 1) / format->block_width; 3884 unsigned int slice_block_count = (height + format->block_height - 1) / format->block_height; 3885 *row_pitch = row_block_count * format->block_byte_count; 3886 *row_pitch = (*row_pitch + alignment - 1) & ~(alignment - 1); 3887 *slice_pitch = *row_pitch * slice_block_count; 3888 } 3889 else 3890 { 3891 *row_pitch = format->byte_count * width; /* Bytes / row */ 3892 *row_pitch = (*row_pitch + alignment - 1) & ~(alignment - 1); 3893 *slice_pitch = *row_pitch * height; 3894 } 3895 3896 if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_HEIGHT_SCALE) 3897 { 3898 /* The D3D format requirements make sure that the resulting format is an integer again */ 3899 *slice_pitch *= format->height_scale.numerator; 3900 *slice_pitch /= format->height_scale.denominator; 3901 } 3902 3903 TRACE("Returning row pitch %u, slice pitch %u.\n", *row_pitch, *slice_pitch); 3904 } 3905 3906 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, 3907 UINT width, UINT height, UINT depth) 3908 { 3909 unsigned int row_pitch, slice_pitch; 3910 3911 if (format->id == WINED3DFMT_UNKNOWN) 3912 return 0; 3913 3914 if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_BROKEN_PITCH) 3915 return width * height * depth * format->byte_count; 3916 3917 wined3d_format_calculate_pitch(format, alignment, width, height, &row_pitch, &slice_pitch); 3918 3919 return slice_pitch * depth; 3920 } 3921 3922 BOOL wined3d_formats_are_srgb_variants(enum wined3d_format_id format1, enum wined3d_format_id format2) 3923 { 3924 unsigned int i; 3925 3926 for (i = 0; i < ARRAY_SIZE(format_srgb_info); ++i) 3927 { 3928 if (format1 == format_srgb_info[i].srgb_format_id) 3929 return format2 == format_srgb_info[i].base_format_id; 3930 if (format1 == format_srgb_info[i].base_format_id) 3931 return format2 == format_srgb_info[i].srgb_format_id; 3932 } 3933 return FALSE; 3934 } 3935 3936 /***************************************************************************** 3937 * Trace formatting of useful values 3938 */ 3939 const char *debug_box(const struct wined3d_box *box) 3940 { 3941 if (!box) 3942 return "(null)"; 3943 return wine_dbg_sprintf("(%u, %u, %u)-(%u, %u, %u)", 3944 box->left, box->top, box->front, 3945 box->right, box->bottom, box->back); 3946 } 3947 3948 const char *debug_color(const struct wined3d_color *color) 3949 { 3950 if (!color) 3951 return "(null)"; 3952 return wine_dbg_sprintf("{%.8e, %.8e, %.8e, %.8e}", 3953 color->r, color->g, color->b, color->a); 3954 } 3955 3956 const char *debug_ivec4(const struct wined3d_ivec4 *v) 3957 { 3958 if (!v) 3959 return "(null)"; 3960 return wine_dbg_sprintf("{%d, %d, %d, %d}", 3961 v->x, v->y, v->z, v->w); 3962 } 3963 3964 const char *debug_uvec4(const struct wined3d_uvec4 *v) 3965 { 3966 if (!v) 3967 return "(null)"; 3968 return wine_dbg_sprintf("{%u, %u, %u, %u}", 3969 v->x, v->y, v->z, v->w); 3970 } 3971 3972 const char *debug_vec4(const struct wined3d_vec4 *v) 3973 { 3974 if (!v) 3975 return "(null)"; 3976 return wine_dbg_sprintf("{%.8e, %.8e, %.8e, %.8e}", 3977 v->x, v->y, v->z, v->w); 3978 } 3979 3980 const char *debug_d3dformat(enum wined3d_format_id format_id) 3981 { 3982 switch (format_id) 3983 { 3984 #define FMT_TO_STR(format_id) case format_id: return #format_id 3985 FMT_TO_STR(WINED3DFMT_UNKNOWN); 3986 FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM); 3987 FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM); 3988 FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM); 3989 FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM); 3990 FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM); 3991 FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM); 3992 FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM); 3993 FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM); 3994 FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM); 3995 FMT_TO_STR(WINED3DFMT_P8_UINT); 3996 FMT_TO_STR(WINED3DFMT_L8_UNORM); 3997 FMT_TO_STR(WINED3DFMT_L8A8_UNORM); 3998 FMT_TO_STR(WINED3DFMT_L4A4_UNORM); 3999 FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM); 4000 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM); 4001 FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM); 4002 FMT_TO_STR(WINED3DFMT_R10G10B10X2_UINT); 4003 FMT_TO_STR(WINED3DFMT_R10G10B10X2_SNORM); 4004 FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM); 4005 FMT_TO_STR(WINED3DFMT_UYVY); 4006 FMT_TO_STR(WINED3DFMT_YUY2); 4007 FMT_TO_STR(WINED3DFMT_YV12); 4008 FMT_TO_STR(WINED3DFMT_NV12); 4009 FMT_TO_STR(WINED3DFMT_DXT1); 4010 FMT_TO_STR(WINED3DFMT_DXT2); 4011 FMT_TO_STR(WINED3DFMT_DXT3); 4012 FMT_TO_STR(WINED3DFMT_DXT4); 4013 FMT_TO_STR(WINED3DFMT_DXT5); 4014 FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8); 4015 FMT_TO_STR(WINED3DFMT_G8R8_G8B8); 4016 FMT_TO_STR(WINED3DFMT_R8G8_B8G8); 4017 FMT_TO_STR(WINED3DFMT_D16_LOCKABLE); 4018 FMT_TO_STR(WINED3DFMT_D32_UNORM); 4019 FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM); 4020 FMT_TO_STR(WINED3DFMT_X8D24_UNORM); 4021 FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM); 4022 FMT_TO_STR(WINED3DFMT_L16_UNORM); 4023 FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT); 4024 FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx); 4025 FMT_TO_STR(WINED3DFMT_ATI1N); 4026 FMT_TO_STR(WINED3DFMT_ATI2N); 4027 FMT_TO_STR(WINED3DFMT_NVDB); 4028 FMT_TO_STR(WINED3DFMT_NVHU); 4029 FMT_TO_STR(WINED3DFMT_NVHS); 4030 FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS); 4031 FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT); 4032 FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT); 4033 FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT); 4034 FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS); 4035 FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT); 4036 FMT_TO_STR(WINED3DFMT_R32G32B32_UINT); 4037 FMT_TO_STR(WINED3DFMT_R32G32B32_SINT); 4038 FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS); 4039 FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT); 4040 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM); 4041 FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT); 4042 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM); 4043 FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT); 4044 FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS); 4045 FMT_TO_STR(WINED3DFMT_R32G32_FLOAT); 4046 FMT_TO_STR(WINED3DFMT_R32G32_UINT); 4047 FMT_TO_STR(WINED3DFMT_R32G32_SINT); 4048 FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS); 4049 FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT); 4050 FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS); 4051 FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT); 4052 FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS); 4053 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM); 4054 FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT); 4055 FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM); 4056 FMT_TO_STR(WINED3DFMT_R10G10B10_XR_BIAS_A2_UNORM); 4057 FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT); 4058 FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS); 4059 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM); 4060 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB); 4061 FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT); 4062 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM); 4063 FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT); 4064 FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS); 4065 FMT_TO_STR(WINED3DFMT_R16G16_FLOAT); 4066 FMT_TO_STR(WINED3DFMT_R16G16_UNORM); 4067 FMT_TO_STR(WINED3DFMT_R16G16_UINT); 4068 FMT_TO_STR(WINED3DFMT_R16G16_SNORM); 4069 FMT_TO_STR(WINED3DFMT_R16G16_SINT); 4070 FMT_TO_STR(WINED3DFMT_R32_TYPELESS); 4071 FMT_TO_STR(WINED3DFMT_D32_FLOAT); 4072 FMT_TO_STR(WINED3DFMT_R32_FLOAT); 4073 FMT_TO_STR(WINED3DFMT_R32_UINT); 4074 FMT_TO_STR(WINED3DFMT_R32_SINT); 4075 FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS); 4076 FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT); 4077 FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS); 4078 FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT); 4079 FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS); 4080 FMT_TO_STR(WINED3DFMT_R8G8_UNORM); 4081 FMT_TO_STR(WINED3DFMT_R8G8_UINT); 4082 FMT_TO_STR(WINED3DFMT_R8G8_SNORM); 4083 FMT_TO_STR(WINED3DFMT_R8G8_SINT); 4084 FMT_TO_STR(WINED3DFMT_R16_TYPELESS); 4085 FMT_TO_STR(WINED3DFMT_R16_FLOAT); 4086 FMT_TO_STR(WINED3DFMT_D16_UNORM); 4087 FMT_TO_STR(WINED3DFMT_R16_UNORM); 4088 FMT_TO_STR(WINED3DFMT_R16_UINT); 4089 FMT_TO_STR(WINED3DFMT_R16_SNORM); 4090 FMT_TO_STR(WINED3DFMT_R16_SINT); 4091 FMT_TO_STR(WINED3DFMT_R8_TYPELESS); 4092 FMT_TO_STR(WINED3DFMT_R8_UNORM); 4093 FMT_TO_STR(WINED3DFMT_R8_UINT); 4094 FMT_TO_STR(WINED3DFMT_R8_SNORM); 4095 FMT_TO_STR(WINED3DFMT_R8_SINT); 4096 FMT_TO_STR(WINED3DFMT_A8_UNORM); 4097 FMT_TO_STR(WINED3DFMT_R1_UNORM); 4098 FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP); 4099 FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM); 4100 FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM); 4101 FMT_TO_STR(WINED3DFMT_BC1_TYPELESS); 4102 FMT_TO_STR(WINED3DFMT_BC1_UNORM); 4103 FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB); 4104 FMT_TO_STR(WINED3DFMT_BC2_TYPELESS); 4105 FMT_TO_STR(WINED3DFMT_BC2_UNORM); 4106 FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB); 4107 FMT_TO_STR(WINED3DFMT_BC3_TYPELESS); 4108 FMT_TO_STR(WINED3DFMT_BC3_UNORM); 4109 FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB); 4110 FMT_TO_STR(WINED3DFMT_BC4_TYPELESS); 4111 FMT_TO_STR(WINED3DFMT_BC4_UNORM); 4112 FMT_TO_STR(WINED3DFMT_BC4_SNORM); 4113 FMT_TO_STR(WINED3DFMT_BC5_TYPELESS); 4114 FMT_TO_STR(WINED3DFMT_BC5_UNORM); 4115 FMT_TO_STR(WINED3DFMT_BC5_SNORM); 4116 FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM); 4117 FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM); 4118 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM); 4119 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM); 4120 FMT_TO_STR(WINED3DFMT_B8G8R8A8_TYPELESS); 4121 FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM_SRGB); 4122 FMT_TO_STR(WINED3DFMT_B8G8R8X8_TYPELESS); 4123 FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM_SRGB); 4124 FMT_TO_STR(WINED3DFMT_BC6H_TYPELESS); 4125 FMT_TO_STR(WINED3DFMT_BC6H_UF16); 4126 FMT_TO_STR(WINED3DFMT_BC6H_SF16); 4127 FMT_TO_STR(WINED3DFMT_BC7_TYPELESS); 4128 FMT_TO_STR(WINED3DFMT_BC7_UNORM); 4129 FMT_TO_STR(WINED3DFMT_BC7_UNORM_SRGB); 4130 FMT_TO_STR(WINED3DFMT_INTZ); 4131 FMT_TO_STR(WINED3DFMT_RESZ); 4132 FMT_TO_STR(WINED3DFMT_NULL); 4133 FMT_TO_STR(WINED3DFMT_R16); 4134 FMT_TO_STR(WINED3DFMT_AL16); 4135 #undef FMT_TO_STR 4136 default: 4137 { 4138 char fourcc[5]; 4139 fourcc[0] = (char)(format_id); 4140 fourcc[1] = (char)(format_id >> 8); 4141 fourcc[2] = (char)(format_id >> 16); 4142 fourcc[3] = (char)(format_id >> 24); 4143 fourcc[4] = 0; 4144 if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3])) 4145 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc); 4146 else 4147 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id); 4148 } 4149 return "unrecognized"; 4150 } 4151 } 4152 4153 const char *debug_d3ddevicetype(enum wined3d_device_type device_type) 4154 { 4155 switch (device_type) 4156 { 4157 #define DEVTYPE_TO_STR(dev) case dev: return #dev 4158 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_HAL); 4159 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_REF); 4160 DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_SW); 4161 #undef DEVTYPE_TO_STR 4162 default: 4163 FIXME("Unrecognized device type %#x.\n", device_type); 4164 return "unrecognized"; 4165 } 4166 } 4167 4168 struct debug_buffer 4169 { 4170 char str[200]; /* wine_dbg_sprintf() limits string size to 200 */ 4171 char *ptr; 4172 int size; 4173 }; 4174 4175 static void init_debug_buffer(struct debug_buffer *buffer, const char *default_string) 4176 { 4177 strcpy(buffer->str, default_string); 4178 buffer->ptr = buffer->str; 4179 buffer->size = ARRAY_SIZE(buffer->str); 4180 } 4181 4182 static void debug_append(struct debug_buffer *buffer, const char *str, const char *separator) 4183 { 4184 int size; 4185 4186 if (!separator || buffer->ptr == buffer->str) 4187 separator = ""; 4188 size = snprintf(buffer->ptr, buffer->size, "%s%s", separator, str); 4189 if (size == -1 || size >= buffer->size) 4190 { 4191 buffer->size = 0; 4192 strcpy(&buffer->str[ARRAY_SIZE(buffer->str) - 4], "..."); 4193 return; 4194 } 4195 4196 buffer->ptr += size; 4197 buffer->size -= size; 4198 } 4199 4200 const char *wined3d_debug_resource_access(DWORD access) 4201 { 4202 struct debug_buffer buffer; 4203 4204 init_debug_buffer(&buffer, "0"); 4205 #define ACCESS_TO_STR(x) if (access & x) { debug_append(&buffer, #x, " | "); access &= ~x; } 4206 ACCESS_TO_STR(WINED3D_RESOURCE_ACCESS_GPU); 4207 ACCESS_TO_STR(WINED3D_RESOURCE_ACCESS_CPU); 4208 ACCESS_TO_STR(WINED3D_RESOURCE_ACCESS_MAP_R); 4209 ACCESS_TO_STR(WINED3D_RESOURCE_ACCESS_MAP_W); 4210 #undef ACCESS_TO_STR 4211 if (access) 4212 FIXME("Unrecognised access flag(s) %#x.\n", access); 4213 4214 return wine_dbg_sprintf("%s", buffer.str); 4215 } 4216 4217 const char *debug_d3dusage(DWORD usage) 4218 { 4219 struct debug_buffer buffer; 4220 4221 init_debug_buffer(&buffer, "0"); 4222 #define WINED3DUSAGE_TO_STR(x) if (usage & x) { debug_append(&buffer, #x, " | "); usage &= ~x; } 4223 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET); 4224 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL); 4225 WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY); 4226 WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING); 4227 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP); 4228 WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS); 4229 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES); 4230 WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES); 4231 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC); 4232 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICTED_CONTENT); 4233 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER); 4234 WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICT_SHARED_RESOURCE); 4235 WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP); 4236 WINED3DUSAGE_TO_STR(WINED3DUSAGE_TEXTAPI); 4237 WINED3DUSAGE_TO_STR(WINED3DUSAGE_LEGACY_CUBEMAP); 4238 WINED3DUSAGE_TO_STR(WINED3DUSAGE_TEXTURE); 4239 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OWNDC); 4240 WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL); 4241 WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY); 4242 #undef WINED3DUSAGE_TO_STR 4243 if (usage) 4244 FIXME("Unrecognized usage flag(s) %#x.\n", usage); 4245 4246 return wine_dbg_sprintf("%s", buffer.str); 4247 } 4248 4249 const char *debug_d3dusagequery(DWORD usage) 4250 { 4251 struct debug_buffer buffer; 4252 4253 init_debug_buffer(&buffer, "0"); 4254 #define WINED3DUSAGEQUERY_TO_STR(x) if (usage & x) { debug_append(&buffer, #x, " | "); usage &= ~x; } 4255 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER); 4256 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_GENMIPMAP); 4257 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP); 4258 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING); 4259 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD); 4260 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE); 4261 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE); 4262 WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP); 4263 #undef WINED3DUSAGEQUERY_TO_STR 4264 if (usage) 4265 FIXME("Unrecognized usage query flag(s) %#x.\n", usage); 4266 4267 return wine_dbg_sprintf("%s", buffer.str); 4268 } 4269 4270 const char *debug_d3ddeclmethod(enum wined3d_decl_method method) 4271 { 4272 switch (method) 4273 { 4274 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u 4275 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_DEFAULT); 4276 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_U); 4277 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_V); 4278 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_CROSS_UV); 4279 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_UV); 4280 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP); 4281 WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP_PRESAMPLED); 4282 #undef WINED3DDECLMETHOD_TO_STR 4283 default: 4284 FIXME("Unrecognized declaration method %#x.\n", method); 4285 return "unrecognized"; 4286 } 4287 } 4288 4289 const char *debug_d3ddeclusage(enum wined3d_decl_usage usage) 4290 { 4291 switch (usage) 4292 { 4293 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u 4294 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITION); 4295 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_WEIGHT); 4296 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_INDICES); 4297 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_NORMAL); 4298 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_PSIZE); 4299 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TEXCOORD); 4300 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TANGENT); 4301 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BINORMAL); 4302 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TESS_FACTOR); 4303 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITIONT); 4304 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_COLOR); 4305 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_FOG); 4306 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_DEPTH); 4307 WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_SAMPLE); 4308 #undef WINED3DDECLUSAGE_TO_STR 4309 default: 4310 FIXME("Unrecognized %u declaration usage!\n", usage); 4311 return "unrecognized"; 4312 } 4313 } 4314 4315 const char *debug_d3dinput_classification(enum wined3d_input_classification classification) 4316 { 4317 switch (classification) 4318 { 4319 #define WINED3D_TO_STR(x) case x: return #x 4320 WINED3D_TO_STR(WINED3D_INPUT_PER_VERTEX_DATA); 4321 WINED3D_TO_STR(WINED3D_INPUT_PER_INSTANCE_DATA); 4322 #undef WINED3D_TO_STR 4323 default: 4324 FIXME("Unrecognized input classification %#x.\n", classification); 4325 return "unrecognized"; 4326 } 4327 } 4328 4329 const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type) 4330 { 4331 switch (resource_type) 4332 { 4333 #define WINED3D_TO_STR(x) case x: return #x 4334 WINED3D_TO_STR(WINED3D_RTYPE_NONE); 4335 WINED3D_TO_STR(WINED3D_RTYPE_BUFFER); 4336 WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_1D); 4337 WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_2D); 4338 WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_3D); 4339 #undef WINED3D_TO_STR 4340 default: 4341 FIXME("Unrecognized resource type %#x.\n", resource_type); 4342 return "unrecognized"; 4343 } 4344 } 4345 4346 const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type) 4347 { 4348 switch (primitive_type) 4349 { 4350 #define PRIM_TO_STR(prim) case prim: return #prim 4351 PRIM_TO_STR(WINED3D_PT_UNDEFINED); 4352 PRIM_TO_STR(WINED3D_PT_POINTLIST); 4353 PRIM_TO_STR(WINED3D_PT_LINELIST); 4354 PRIM_TO_STR(WINED3D_PT_LINESTRIP); 4355 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST); 4356 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP); 4357 PRIM_TO_STR(WINED3D_PT_TRIANGLEFAN); 4358 PRIM_TO_STR(WINED3D_PT_LINELIST_ADJ); 4359 PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ); 4360 PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ); 4361 PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ); 4362 PRIM_TO_STR(WINED3D_PT_PATCH); 4363 #undef PRIM_TO_STR 4364 default: 4365 FIXME("Unrecognized primitive type %#x.\n", primitive_type); 4366 return "unrecognized"; 4367 } 4368 } 4369 4370 const char *debug_d3drenderstate(enum wined3d_render_state state) 4371 { 4372 switch (state) 4373 { 4374 #define D3DSTATE_TO_STR(u) case u: return #u 4375 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIAS); 4376 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREPERSPECTIVE); 4377 D3DSTATE_TO_STR(WINED3D_RS_WRAPU); 4378 D3DSTATE_TO_STR(WINED3D_RS_WRAPV); 4379 D3DSTATE_TO_STR(WINED3D_RS_ZENABLE); 4380 D3DSTATE_TO_STR(WINED3D_RS_FILLMODE); 4381 D3DSTATE_TO_STR(WINED3D_RS_SHADEMODE); 4382 D3DSTATE_TO_STR(WINED3D_RS_LINEPATTERN); 4383 D3DSTATE_TO_STR(WINED3D_RS_MONOENABLE); 4384 D3DSTATE_TO_STR(WINED3D_RS_ROP2); 4385 D3DSTATE_TO_STR(WINED3D_RS_PLANEMASK); 4386 D3DSTATE_TO_STR(WINED3D_RS_ZWRITEENABLE); 4387 D3DSTATE_TO_STR(WINED3D_RS_ALPHATESTENABLE); 4388 D3DSTATE_TO_STR(WINED3D_RS_LASTPIXEL); 4389 D3DSTATE_TO_STR(WINED3D_RS_SRCBLEND); 4390 D3DSTATE_TO_STR(WINED3D_RS_DESTBLEND); 4391 D3DSTATE_TO_STR(WINED3D_RS_CULLMODE); 4392 D3DSTATE_TO_STR(WINED3D_RS_ZFUNC); 4393 D3DSTATE_TO_STR(WINED3D_RS_ALPHAREF); 4394 D3DSTATE_TO_STR(WINED3D_RS_ALPHAFUNC); 4395 D3DSTATE_TO_STR(WINED3D_RS_DITHERENABLE); 4396 D3DSTATE_TO_STR(WINED3D_RS_ALPHABLENDENABLE); 4397 D3DSTATE_TO_STR(WINED3D_RS_FOGENABLE); 4398 D3DSTATE_TO_STR(WINED3D_RS_SPECULARENABLE); 4399 D3DSTATE_TO_STR(WINED3D_RS_ZVISIBLE); 4400 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXEL); 4401 D3DSTATE_TO_STR(WINED3D_RS_SUBPIXELX); 4402 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEDALPHA); 4403 D3DSTATE_TO_STR(WINED3D_RS_FOGCOLOR); 4404 D3DSTATE_TO_STR(WINED3D_RS_FOGTABLEMODE); 4405 D3DSTATE_TO_STR(WINED3D_RS_FOGSTART); 4406 D3DSTATE_TO_STR(WINED3D_RS_FOGEND); 4407 D3DSTATE_TO_STR(WINED3D_RS_FOGDENSITY); 4408 D3DSTATE_TO_STR(WINED3D_RS_STIPPLEENABLE); 4409 D3DSTATE_TO_STR(WINED3D_RS_EDGEANTIALIAS); 4410 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYENABLE); 4411 D3DSTATE_TO_STR(WINED3D_RS_MIPMAPLODBIAS); 4412 D3DSTATE_TO_STR(WINED3D_RS_RANGEFOGENABLE); 4413 D3DSTATE_TO_STR(WINED3D_RS_ANISOTROPY); 4414 D3DSTATE_TO_STR(WINED3D_RS_FLUSHBATCH); 4415 D3DSTATE_TO_STR(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT); 4416 D3DSTATE_TO_STR(WINED3D_RS_STENCILENABLE); 4417 D3DSTATE_TO_STR(WINED3D_RS_STENCILFAIL); 4418 D3DSTATE_TO_STR(WINED3D_RS_STENCILZFAIL); 4419 D3DSTATE_TO_STR(WINED3D_RS_STENCILPASS); 4420 D3DSTATE_TO_STR(WINED3D_RS_STENCILFUNC); 4421 D3DSTATE_TO_STR(WINED3D_RS_STENCILREF); 4422 D3DSTATE_TO_STR(WINED3D_RS_STENCILMASK); 4423 D3DSTATE_TO_STR(WINED3D_RS_STENCILWRITEMASK); 4424 D3DSTATE_TO_STR(WINED3D_RS_TEXTUREFACTOR); 4425 D3DSTATE_TO_STR(WINED3D_RS_WRAP0); 4426 D3DSTATE_TO_STR(WINED3D_RS_WRAP1); 4427 D3DSTATE_TO_STR(WINED3D_RS_WRAP2); 4428 D3DSTATE_TO_STR(WINED3D_RS_WRAP3); 4429 D3DSTATE_TO_STR(WINED3D_RS_WRAP4); 4430 D3DSTATE_TO_STR(WINED3D_RS_WRAP5); 4431 D3DSTATE_TO_STR(WINED3D_RS_WRAP6); 4432 D3DSTATE_TO_STR(WINED3D_RS_WRAP7); 4433 D3DSTATE_TO_STR(WINED3D_RS_CLIPPING); 4434 D3DSTATE_TO_STR(WINED3D_RS_LIGHTING); 4435 D3DSTATE_TO_STR(WINED3D_RS_EXTENTS); 4436 D3DSTATE_TO_STR(WINED3D_RS_AMBIENT); 4437 D3DSTATE_TO_STR(WINED3D_RS_FOGVERTEXMODE); 4438 D3DSTATE_TO_STR(WINED3D_RS_COLORVERTEX); 4439 D3DSTATE_TO_STR(WINED3D_RS_LOCALVIEWER); 4440 D3DSTATE_TO_STR(WINED3D_RS_NORMALIZENORMALS); 4441 D3DSTATE_TO_STR(WINED3D_RS_COLORKEYBLENDENABLE); 4442 D3DSTATE_TO_STR(WINED3D_RS_DIFFUSEMATERIALSOURCE); 4443 D3DSTATE_TO_STR(WINED3D_RS_SPECULARMATERIALSOURCE); 4444 D3DSTATE_TO_STR(WINED3D_RS_AMBIENTMATERIALSOURCE); 4445 D3DSTATE_TO_STR(WINED3D_RS_EMISSIVEMATERIALSOURCE); 4446 D3DSTATE_TO_STR(WINED3D_RS_VERTEXBLEND); 4447 D3DSTATE_TO_STR(WINED3D_RS_CLIPPLANEENABLE); 4448 D3DSTATE_TO_STR(WINED3D_RS_SOFTWAREVERTEXPROCESSING); 4449 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE); 4450 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MIN); 4451 D3DSTATE_TO_STR(WINED3D_RS_POINTSPRITEENABLE); 4452 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALEENABLE); 4453 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_A); 4454 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_B); 4455 D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_C); 4456 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEANTIALIAS); 4457 D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEMASK); 4458 D3DSTATE_TO_STR(WINED3D_RS_PATCHEDGESTYLE); 4459 D3DSTATE_TO_STR(WINED3D_RS_PATCHSEGMENTS); 4460 D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN); 4461 D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX); 4462 D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE); 4463 D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR); 4464 D3DSTATE_TO_STR(WINED3D_RS_BLENDOP); 4465 D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE); 4466 D3DSTATE_TO_STR(WINED3D_RS_NORMALDEGREE); 4467 D3DSTATE_TO_STR(WINED3D_RS_SCISSORTESTENABLE); 4468 D3DSTATE_TO_STR(WINED3D_RS_SLOPESCALEDEPTHBIAS); 4469 D3DSTATE_TO_STR(WINED3D_RS_ANTIALIASEDLINEENABLE); 4470 D3DSTATE_TO_STR(WINED3D_RS_MINTESSELLATIONLEVEL); 4471 D3DSTATE_TO_STR(WINED3D_RS_MAXTESSELLATIONLEVEL); 4472 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_X); 4473 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Y); 4474 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Z); 4475 D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_W); 4476 D3DSTATE_TO_STR(WINED3D_RS_ENABLEADAPTIVETESSELLATION); 4477 D3DSTATE_TO_STR(WINED3D_RS_TWOSIDEDSTENCILMODE); 4478 D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILFAIL); 4479 D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILZFAIL); 4480 D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILPASS); 4481 D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILFUNC); 4482 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE); 4483 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1); 4484 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2); 4485 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3); 4486 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE4); 4487 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE5); 4488 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE6); 4489 D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE7); 4490 D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR); 4491 D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE); 4492 D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS); 4493 D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIASCLAMP); 4494 D3DSTATE_TO_STR(WINED3D_RS_WRAP8); 4495 D3DSTATE_TO_STR(WINED3D_RS_WRAP9); 4496 D3DSTATE_TO_STR(WINED3D_RS_WRAP10); 4497 D3DSTATE_TO_STR(WINED3D_RS_WRAP11); 4498 D3DSTATE_TO_STR(WINED3D_RS_WRAP12); 4499 D3DSTATE_TO_STR(WINED3D_RS_WRAP13); 4500 D3DSTATE_TO_STR(WINED3D_RS_WRAP14); 4501 D3DSTATE_TO_STR(WINED3D_RS_WRAP15); 4502 D3DSTATE_TO_STR(WINED3D_RS_SEPARATEALPHABLENDENABLE); 4503 D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA); 4504 D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA); 4505 D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA); 4506 D3DSTATE_TO_STR(WINED3D_RS_DEPTHCLIP); 4507 #undef D3DSTATE_TO_STR 4508 default: 4509 FIXME("Unrecognized %u render state!\n", state); 4510 return "unrecognized"; 4511 } 4512 } 4513 4514 const char *debug_d3dsamplerstate(enum wined3d_sampler_state state) 4515 { 4516 switch (state) 4517 { 4518 #define D3DSTATE_TO_STR(u) case u: return #u 4519 D3DSTATE_TO_STR(WINED3D_SAMP_BORDER_COLOR); 4520 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_U); 4521 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_V); 4522 D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_W); 4523 D3DSTATE_TO_STR(WINED3D_SAMP_MAG_FILTER); 4524 D3DSTATE_TO_STR(WINED3D_SAMP_MIN_FILTER); 4525 D3DSTATE_TO_STR(WINED3D_SAMP_MIP_FILTER); 4526 D3DSTATE_TO_STR(WINED3D_SAMP_MIPMAP_LOD_BIAS); 4527 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_MIP_LEVEL); 4528 D3DSTATE_TO_STR(WINED3D_SAMP_MAX_ANISOTROPY); 4529 D3DSTATE_TO_STR(WINED3D_SAMP_SRGB_TEXTURE); 4530 D3DSTATE_TO_STR(WINED3D_SAMP_ELEMENT_INDEX); 4531 D3DSTATE_TO_STR(WINED3D_SAMP_DMAP_OFFSET); 4532 #undef D3DSTATE_TO_STR 4533 default: 4534 FIXME("Unrecognized %u sampler state!\n", state); 4535 return "unrecognized"; 4536 } 4537 } 4538 4539 const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type) 4540 { 4541 switch (filter_type) 4542 { 4543 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u 4544 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_NONE); 4545 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_POINT); 4546 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_LINEAR); 4547 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_ANISOTROPIC); 4548 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_FLAT_CUBIC); 4549 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_CUBIC); 4550 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_PYRAMIDAL_QUAD); 4551 D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_QUAD); 4552 #undef D3DTEXTUREFILTERTYPE_TO_STR 4553 default: 4554 FIXME("Unrecognized texture filter type 0x%08x.\n", filter_type); 4555 return "unrecognized"; 4556 } 4557 } 4558 4559 const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state) 4560 { 4561 switch (state) 4562 { 4563 #define D3DSTATE_TO_STR(u) case u: return #u 4564 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_OP); 4565 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG1); 4566 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG2); 4567 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_OP); 4568 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG1); 4569 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG2); 4570 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT00); 4571 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT01); 4572 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT10); 4573 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT11); 4574 D3DSTATE_TO_STR(WINED3D_TSS_TEXCOORD_INDEX); 4575 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LSCALE); 4576 D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LOFFSET); 4577 D3DSTATE_TO_STR(WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS); 4578 D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG0); 4579 D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG0); 4580 D3DSTATE_TO_STR(WINED3D_TSS_RESULT_ARG); 4581 D3DSTATE_TO_STR(WINED3D_TSS_CONSTANT); 4582 #undef D3DSTATE_TO_STR 4583 default: 4584 FIXME("Unrecognized %u texture state!\n", state); 4585 return "unrecognized"; 4586 } 4587 } 4588 4589 const char *debug_d3dtop(enum wined3d_texture_op d3dtop) 4590 { 4591 switch (d3dtop) 4592 { 4593 #define D3DTOP_TO_STR(u) case u: return #u 4594 D3DTOP_TO_STR(WINED3D_TOP_DISABLE); 4595 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG1); 4596 D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG2); 4597 D3DTOP_TO_STR(WINED3D_TOP_MODULATE); 4598 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_2X); 4599 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_4X); 4600 D3DTOP_TO_STR(WINED3D_TOP_ADD); 4601 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED); 4602 D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED_2X); 4603 D3DTOP_TO_STR(WINED3D_TOP_SUBTRACT); 4604 D3DTOP_TO_STR(WINED3D_TOP_ADD_SMOOTH); 4605 D3DTOP_TO_STR(WINED3D_TOP_BLEND_DIFFUSE_ALPHA); 4606 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA); 4607 D3DTOP_TO_STR(WINED3D_TOP_BLEND_FACTOR_ALPHA); 4608 D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM); 4609 D3DTOP_TO_STR(WINED3D_TOP_BLEND_CURRENT_ALPHA); 4610 D3DTOP_TO_STR(WINED3D_TOP_PREMODULATE); 4611 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR); 4612 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA); 4613 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR); 4614 D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA); 4615 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP); 4616 D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP_LUMINANCE); 4617 D3DTOP_TO_STR(WINED3D_TOP_DOTPRODUCT3); 4618 D3DTOP_TO_STR(WINED3D_TOP_MULTIPLY_ADD); 4619 D3DTOP_TO_STR(WINED3D_TOP_LERP); 4620 #undef D3DTOP_TO_STR 4621 default: 4622 FIXME("Unrecognized texture op %#x.\n", d3dtop); 4623 return "unrecognized"; 4624 } 4625 } 4626 4627 const char *debug_d3dtstype(enum wined3d_transform_state tstype) 4628 { 4629 switch (tstype) 4630 { 4631 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype 4632 TSTYPE_TO_STR(WINED3D_TS_VIEW); 4633 TSTYPE_TO_STR(WINED3D_TS_PROJECTION); 4634 TSTYPE_TO_STR(WINED3D_TS_TEXTURE0); 4635 TSTYPE_TO_STR(WINED3D_TS_TEXTURE1); 4636 TSTYPE_TO_STR(WINED3D_TS_TEXTURE2); 4637 TSTYPE_TO_STR(WINED3D_TS_TEXTURE3); 4638 TSTYPE_TO_STR(WINED3D_TS_TEXTURE4); 4639 TSTYPE_TO_STR(WINED3D_TS_TEXTURE5); 4640 TSTYPE_TO_STR(WINED3D_TS_TEXTURE6); 4641 TSTYPE_TO_STR(WINED3D_TS_TEXTURE7); 4642 TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(0)); 4643 TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(1)); 4644 TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(2)); 4645 TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(3)); 4646 #undef TSTYPE_TO_STR 4647 default: 4648 if (tstype > 256 && tstype < 512) 4649 { 4650 FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype); 4651 return ("WINED3D_TS_WORLD_MATRIX > 0"); 4652 } 4653 FIXME("Unrecognized transform state %#x.\n", tstype); 4654 return "unrecognized"; 4655 } 4656 } 4657 4658 const char *debug_shader_type(enum wined3d_shader_type type) 4659 { 4660 switch(type) 4661 { 4662 #define WINED3D_TO_STR(type) case type: return #type 4663 WINED3D_TO_STR(WINED3D_SHADER_TYPE_PIXEL); 4664 WINED3D_TO_STR(WINED3D_SHADER_TYPE_VERTEX); 4665 WINED3D_TO_STR(WINED3D_SHADER_TYPE_GEOMETRY); 4666 WINED3D_TO_STR(WINED3D_SHADER_TYPE_HULL); 4667 WINED3D_TO_STR(WINED3D_SHADER_TYPE_DOMAIN); 4668 WINED3D_TO_STR(WINED3D_SHADER_TYPE_COMPUTE); 4669 #undef WINED3D_TO_STR 4670 default: 4671 FIXME("Unrecognized shader type %#x.\n", type); 4672 return "unrecognized"; 4673 } 4674 } 4675 4676 const char *debug_d3dstate(DWORD state) 4677 { 4678 if (STATE_IS_RENDER(state)) 4679 return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0))); 4680 if (STATE_IS_TEXTURESTAGE(state)) 4681 { 4682 DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); 4683 DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0); 4684 return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)", 4685 texture_stage, debug_d3dtexturestate(texture_state)); 4686 } 4687 if (STATE_IS_SAMPLER(state)) 4688 return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0)); 4689 if (STATE_IS_COMPUTE_SHADER(state)) 4690 return wine_dbg_sprintf("STATE_SHADER(%s)", debug_shader_type(WINED3D_SHADER_TYPE_COMPUTE)); 4691 if (STATE_IS_GRAPHICS_SHADER(state)) 4692 return wine_dbg_sprintf("STATE_SHADER(%s)", debug_shader_type(state - STATE_SHADER(0))); 4693 if (STATE_IS_COMPUTE_CONSTANT_BUFFER(state)) 4694 return wine_dbg_sprintf("STATE_CONSTANT_BUFFER(%s)", debug_shader_type(WINED3D_SHADER_TYPE_COMPUTE)); 4695 if (STATE_IS_GRAPHICS_CONSTANT_BUFFER(state)) 4696 return wine_dbg_sprintf("STATE_CONSTANT_BUFFER(%s)", debug_shader_type(state - STATE_CONSTANT_BUFFER(0))); 4697 if (STATE_IS_COMPUTE_SHADER_RESOURCE_BINDING(state)) 4698 return "STATE_COMPUTE_SHADER_RESOURCE_BINDING"; 4699 if (STATE_IS_GRAPHICS_SHADER_RESOURCE_BINDING(state)) 4700 return "STATE_GRAPHICS_SHADER_RESOURCE_BINDING"; 4701 if (STATE_IS_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING(state)) 4702 return "STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING"; 4703 if (STATE_IS_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING(state)) 4704 return "STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING"; 4705 if (STATE_IS_TRANSFORM(state)) 4706 return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0))); 4707 if (STATE_IS_STREAMSRC(state)) 4708 return "STATE_STREAMSRC"; 4709 if (STATE_IS_INDEXBUFFER(state)) 4710 return "STATE_INDEXBUFFER"; 4711 if (STATE_IS_VDECL(state)) 4712 return "STATE_VDECL"; 4713 if (STATE_IS_VIEWPORT(state)) 4714 return "STATE_VIEWPORT"; 4715 if (STATE_IS_LIGHT_TYPE(state)) 4716 return "STATE_LIGHT_TYPE"; 4717 if (STATE_IS_ACTIVELIGHT(state)) 4718 return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0)); 4719 if (STATE_IS_SCISSORRECT(state)) 4720 return "STATE_SCISSORRECT"; 4721 if (STATE_IS_CLIPPLANE(state)) 4722 return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0)); 4723 if (STATE_IS_MATERIAL(state)) 4724 return "STATE_MATERIAL"; 4725 if (STATE_IS_FRONTFACE(state)) 4726 return "STATE_FRONTFACE"; 4727 if (STATE_IS_POINTSPRITECOORDORIGIN(state)) 4728 return "STATE_POINTSPRITECOORDORIGIN"; 4729 if (STATE_IS_BASEVERTEXINDEX(state)) 4730 return "STATE_BASEVERTEXINDEX"; 4731 if (STATE_IS_FRAMEBUFFER(state)) 4732 return "STATE_FRAMEBUFFER"; 4733 if (STATE_IS_POINT_ENABLE(state)) 4734 return "STATE_POINT_ENABLE"; 4735 if (STATE_IS_COLOR_KEY(state)) 4736 return "STATE_COLOR_KEY"; 4737 if (STATE_IS_STREAM_OUTPUT(state)) 4738 return "STATE_STREAM_OUTPUT"; 4739 if (STATE_IS_BLEND(state)) 4740 return "STATE_BLEND"; 4741 4742 return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state); 4743 } 4744 4745 const char *debug_fboattachment(GLenum attachment) 4746 { 4747 switch(attachment) 4748 { 4749 #define WINED3D_TO_STR(x) case x: return #x 4750 WINED3D_TO_STR(GL_COLOR_ATTACHMENT0); 4751 WINED3D_TO_STR(GL_COLOR_ATTACHMENT1); 4752 WINED3D_TO_STR(GL_COLOR_ATTACHMENT2); 4753 WINED3D_TO_STR(GL_COLOR_ATTACHMENT3); 4754 WINED3D_TO_STR(GL_COLOR_ATTACHMENT4); 4755 WINED3D_TO_STR(GL_COLOR_ATTACHMENT5); 4756 WINED3D_TO_STR(GL_COLOR_ATTACHMENT6); 4757 WINED3D_TO_STR(GL_COLOR_ATTACHMENT7); 4758 WINED3D_TO_STR(GL_COLOR_ATTACHMENT8); 4759 WINED3D_TO_STR(GL_COLOR_ATTACHMENT9); 4760 WINED3D_TO_STR(GL_COLOR_ATTACHMENT10); 4761 WINED3D_TO_STR(GL_COLOR_ATTACHMENT11); 4762 WINED3D_TO_STR(GL_COLOR_ATTACHMENT12); 4763 WINED3D_TO_STR(GL_COLOR_ATTACHMENT13); 4764 WINED3D_TO_STR(GL_COLOR_ATTACHMENT14); 4765 WINED3D_TO_STR(GL_COLOR_ATTACHMENT15); 4766 WINED3D_TO_STR(GL_DEPTH_ATTACHMENT); 4767 WINED3D_TO_STR(GL_STENCIL_ATTACHMENT); 4768 #undef WINED3D_TO_STR 4769 default: 4770 return wine_dbg_sprintf("Unknown FBO attachment %#x", attachment); 4771 } 4772 } 4773 4774 const char *debug_fbostatus(GLenum status) { 4775 switch(status) { 4776 #define FBOSTATUS_TO_STR(u) case u: return #u 4777 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE); 4778 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT); 4779 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT); 4780 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT); 4781 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT); 4782 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER); 4783 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER); 4784 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE); 4785 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS); 4786 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB); 4787 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED); 4788 FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED); 4789 #undef FBOSTATUS_TO_STR 4790 default: 4791 FIXME("Unrecognized FBO status 0x%08x.\n", status); 4792 return "unrecognized"; 4793 } 4794 } 4795 4796 const char *debug_glerror(GLenum error) { 4797 switch(error) { 4798 #define GLERROR_TO_STR(u) case u: return #u 4799 GLERROR_TO_STR(GL_NO_ERROR); 4800 GLERROR_TO_STR(GL_INVALID_ENUM); 4801 GLERROR_TO_STR(GL_INVALID_VALUE); 4802 GLERROR_TO_STR(GL_INVALID_OPERATION); 4803 GLERROR_TO_STR(GL_STACK_OVERFLOW); 4804 GLERROR_TO_STR(GL_STACK_UNDERFLOW); 4805 GLERROR_TO_STR(GL_OUT_OF_MEMORY); 4806 GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION); 4807 #undef GLERROR_TO_STR 4808 default: 4809 FIXME("Unrecognized GL error 0x%08x.\n", error); 4810 return "unrecognized"; 4811 } 4812 } 4813 4814 static const char *debug_fixup_channel_source(enum fixup_channel_source source) 4815 { 4816 switch(source) 4817 { 4818 #define WINED3D_TO_STR(x) case x: return #x 4819 WINED3D_TO_STR(CHANNEL_SOURCE_ZERO); 4820 WINED3D_TO_STR(CHANNEL_SOURCE_ONE); 4821 WINED3D_TO_STR(CHANNEL_SOURCE_X); 4822 WINED3D_TO_STR(CHANNEL_SOURCE_Y); 4823 WINED3D_TO_STR(CHANNEL_SOURCE_Z); 4824 WINED3D_TO_STR(CHANNEL_SOURCE_W); 4825 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0); 4826 WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1); 4827 #undef WINED3D_TO_STR 4828 default: 4829 FIXME("Unrecognized fixup_channel_source %#x\n", source); 4830 return "unrecognized"; 4831 } 4832 } 4833 4834 static const char *debug_complex_fixup(enum complex_fixup fixup) 4835 { 4836 switch(fixup) 4837 { 4838 #define WINED3D_TO_STR(x) case x: return #x 4839 WINED3D_TO_STR(COMPLEX_FIXUP_YUY2); 4840 WINED3D_TO_STR(COMPLEX_FIXUP_UYVY); 4841 WINED3D_TO_STR(COMPLEX_FIXUP_YV12); 4842 WINED3D_TO_STR(COMPLEX_FIXUP_NV12); 4843 WINED3D_TO_STR(COMPLEX_FIXUP_P8); 4844 #undef WINED3D_TO_STR 4845 default: 4846 FIXME("Unrecognized complex fixup %#x\n", fixup); 4847 return "unrecognized"; 4848 } 4849 } 4850 4851 void dump_color_fixup_desc(struct color_fixup_desc fixup) 4852 { 4853 if (is_complex_fixup(fixup)) 4854 { 4855 TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup))); 4856 return; 4857 } 4858 4859 TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : ""); 4860 TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : ""); 4861 TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : ""); 4862 TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : ""); 4863 } 4864 4865 BOOL is_invalid_op(const struct wined3d_state *state, int stage, 4866 enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3) 4867 { 4868 if (op == WINED3D_TOP_DISABLE) 4869 return FALSE; 4870 if (state->textures[stage]) 4871 return FALSE; 4872 4873 if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE 4874 && op != WINED3D_TOP_SELECT_ARG2) 4875 return TRUE; 4876 if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE 4877 && op != WINED3D_TOP_SELECT_ARG1) 4878 return TRUE; 4879 if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE 4880 && (op == WINED3D_TOP_MULTIPLY_ADD || op == WINED3D_TOP_LERP)) 4881 return TRUE; 4882 4883 return FALSE; 4884 } 4885 4886 void get_identity_matrix(struct wined3d_matrix *mat) 4887 { 4888 static const struct wined3d_matrix identity = 4889 { 4890 1.0f, 0.0f, 0.0f, 0.0f, 4891 0.0f, 1.0f, 0.0f, 0.0f, 4892 0.0f, 0.0f, 1.0f, 0.0f, 4893 0.0f, 0.0f, 0.0f, 1.0f, 4894 }; 4895 4896 *mat = identity; 4897 } 4898 4899 void get_modelview_matrix(const struct wined3d_context *context, const struct wined3d_state *state, 4900 unsigned int index, struct wined3d_matrix *mat) 4901 { 4902 if (context->last_was_rhw) 4903 get_identity_matrix(mat); 4904 else 4905 multiply_matrix(mat, &state->transforms[WINED3D_TS_VIEW], &state->transforms[WINED3D_TS_WORLD_MATRIX(index)]); 4906 } 4907 4908 void get_projection_matrix(const struct wined3d_context *context, const struct wined3d_state *state, 4909 struct wined3d_matrix *mat) 4910 { 4911 BOOL clip_control = context->gl_info->supported[ARB_CLIP_CONTROL]; 4912 BOOL flip = !clip_control && context->render_offscreen; 4913 float center_offset; 4914 4915 /* There are a couple of additional things we have to take into account 4916 * here besides the projection transformation itself: 4917 * - We need to flip along the y-axis in case of offscreen rendering. 4918 * - OpenGL Z range is {-Wc,...,Wc} while D3D Z range is {0,...,Wc}. 4919 * - <= D3D9 coordinates refer to pixel centers while GL coordinates 4920 * refer to pixel corners. 4921 * - D3D has a top-left filling convention. We need to maintain this 4922 * even after the y-flip mentioned above. 4923 * In order to handle the last two points, we translate by 4924 * (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to 4925 * translating slightly less than half a pixel. We want the difference to 4926 * be large enough that it doesn't get lost due to rounding inside the 4927 * driver, but small enough to prevent it from interfering with any 4928 * anti-aliasing. */ 4929 4930 if (!clip_control && context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) 4931 center_offset = 63.0f / 64.0f; 4932 else 4933 center_offset = -1.0f / 64.0f; 4934 4935 if (context->last_was_rhw) 4936 { 4937 /* Transform D3D RHW coordinates to OpenGL clip coordinates. */ 4938 float x = state->viewport.x; 4939 float y = state->viewport.y; 4940 float w = state->viewport.width; 4941 float h = state->viewport.height; 4942 float x_scale = 2.0f / w; 4943 float x_offset = (center_offset - (2.0f * x) - w) / w; 4944 float y_scale = flip ? 2.0f / h : 2.0f / -h; 4945 float y_offset = flip 4946 ? (center_offset - (2.0f * y) - h) / h 4947 : (center_offset - (2.0f * y) - h) / -h; 4948 enum wined3d_depth_buffer_type zenable = state->fb->depth_stencil ? 4949 state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE; 4950 float z_scale = zenable ? clip_control ? 1.0f : 2.0f : 0.0f; 4951 float z_offset = zenable ? clip_control ? 0.0f : -1.0f : 0.0f; 4952 const struct wined3d_matrix projection = 4953 { 4954 x_scale, 0.0f, 0.0f, 0.0f, 4955 0.0f, y_scale, 0.0f, 0.0f, 4956 0.0f, 0.0f, z_scale, 0.0f, 4957 x_offset, y_offset, z_offset, 1.0f, 4958 }; 4959 4960 *mat = projection; 4961 } 4962 else 4963 { 4964 float y_scale = flip ? -1.0f : 1.0f; 4965 float x_offset = center_offset / state->viewport.width; 4966 float y_offset = flip 4967 ? center_offset / state->viewport.height 4968 : -center_offset / state->viewport.height; 4969 float z_scale = clip_control ? 1.0f : 2.0f; 4970 float z_offset = clip_control ? 0.0f : -1.0f; 4971 const struct wined3d_matrix projection = 4972 { 4973 1.0f, 0.0f, 0.0f, 0.0f, 4974 0.0f, y_scale, 0.0f, 0.0f, 4975 0.0f, 0.0f, z_scale, 0.0f, 4976 x_offset, y_offset, z_offset, 1.0f, 4977 }; 4978 4979 multiply_matrix(mat, &projection, &state->transforms[WINED3D_TS_PROJECTION]); 4980 } 4981 } 4982 4983 /* Setup this textures matrix according to the texture flags. */ 4984 static void compute_texture_matrix(const struct wined3d_gl_info *gl_info, const struct wined3d_matrix *matrix, 4985 DWORD flags, BOOL calculated_coords, BOOL transformed, enum wined3d_format_id format_id, 4986 BOOL ffp_proj_control, struct wined3d_matrix *out_matrix) 4987 { 4988 struct wined3d_matrix mat; 4989 4990 if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed) 4991 { 4992 get_identity_matrix(out_matrix); 4993 return; 4994 } 4995 4996 if (flags == (WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED)) 4997 { 4998 ERR("Invalid texture transform flags: WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED.\n"); 4999 return; 5000 } 5001 5002 mat = *matrix; 5003 5004 if (flags & WINED3D_TTFF_PROJECTED) 5005 { 5006 if (!ffp_proj_control) 5007 { 5008 switch (flags & ~WINED3D_TTFF_PROJECTED) 5009 { 5010 case WINED3D_TTFF_COUNT2: 5011 mat._14 = mat._12; 5012 mat._24 = mat._22; 5013 mat._34 = mat._32; 5014 mat._44 = mat._42; 5015 mat._12 = mat._22 = mat._32 = mat._42 = 0.0f; 5016 break; 5017 case WINED3D_TTFF_COUNT3: 5018 mat._14 = mat._13; 5019 mat._24 = mat._23; 5020 mat._34 = mat._33; 5021 mat._44 = mat._43; 5022 mat._13 = mat._23 = mat._33 = mat._43 = 0.0f; 5023 break; 5024 } 5025 } 5026 } 5027 else 5028 { 5029 /* Under Direct3D the R/Z coord can be used for translation, under 5030 * OpenGL we use the Q coord instead. */ 5031 if (!calculated_coords) 5032 { 5033 switch (format_id) 5034 { 5035 /* Direct3D passes the default 1.0 in the 2nd coord, while GL 5036 * passes it in the 4th. Swap 2nd and 4th coord. No need to 5037 * store the value of mat._41 in mat._21 because the input 5038 * value to the transformation will be 0, so the matrix value 5039 * is irrelevant. */ 5040 case WINED3DFMT_R32_FLOAT: 5041 mat._41 = mat._21; 5042 mat._42 = mat._22; 5043 mat._43 = mat._23; 5044 mat._44 = mat._24; 5045 break; 5046 /* See above, just 3rd and 4th coord. */ 5047 case WINED3DFMT_R32G32_FLOAT: 5048 mat._41 = mat._31; 5049 mat._42 = mat._32; 5050 mat._43 = mat._33; 5051 mat._44 = mat._34; 5052 break; 5053 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */ 5054 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */ 5055 5056 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0 5057 * into a bad place. The division elimination below will apply to make sure the 5058 * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0 5059 */ 5060 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */ 5061 break; 5062 default: 5063 FIXME("Unexpected fixed function texture coord input\n"); 5064 } 5065 } 5066 if (!ffp_proj_control) 5067 { 5068 switch (flags & ~WINED3D_TTFF_PROJECTED) 5069 { 5070 /* case WINED3D_TTFF_COUNT1: Won't ever get here. */ 5071 case WINED3D_TTFF_COUNT2: 5072 mat._13 = mat._23 = mat._33 = mat._43 = 0.0f; 5073 /* OpenGL divides the first 3 vertex coordinates by the 4th by 5074 * default, which is essentially the same as D3DTTFF_PROJECTED. 5075 * Make sure that the 4th coordinate evaluates to 1.0 to 5076 * eliminate that. 5077 * 5078 * If the fixed function pipeline is used, the 4th value 5079 * remains unused, so there is no danger in doing this. With 5080 * vertex shaders we have a problem. Should an application hit 5081 * that problem, the code here would have to check for pixel 5082 * shaders, and the shader has to undo the default GL divide. 5083 * 5084 * A more serious problem occurs if the application passes 4 5085 * coordinates in, and the 4th is != 1.0 (OpenGL default). 5086 * This would have to be fixed with immediate mode draws. */ 5087 default: 5088 mat._14 = mat._24 = mat._34 = 0.0f; mat._44 = 1.0f; 5089 } 5090 } 5091 } 5092 5093 *out_matrix = mat; 5094 } 5095 5096 void get_texture_matrix(const struct wined3d_context *context, const struct wined3d_state *state, 5097 unsigned int tex, struct wined3d_matrix *mat) 5098 { 5099 const struct wined3d_device *device = context->device; 5100 const struct wined3d_gl_info *gl_info = context->gl_info; 5101 BOOL generated = (state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) 5102 != WINED3DTSS_TCI_PASSTHRU; 5103 unsigned int coord_idx = min(state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX & 0x0000ffff], 5104 MAX_TEXTURES - 1); 5105 5106 compute_texture_matrix(gl_info, &state->transforms[WINED3D_TS_TEXTURE0 + tex], 5107 state->texture_states[tex][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS], 5108 generated, context->last_was_rhw, 5109 context->stream_info.use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)) 5110 ? context->stream_info.elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->id 5111 : WINED3DFMT_UNKNOWN, 5112 device->shader_backend->shader_has_ffp_proj_control(device->shader_priv), mat); 5113 5114 if ((context->lastWasPow2Texture & (1u << tex)) && state->textures[tex]) 5115 { 5116 if (generated) 5117 FIXME("Non-power-of-two texture being used with generated texture coords.\n"); 5118 /* NP2 texcoord fixup is implemented for pixelshaders so only enable the 5119 * fixed-function-pipeline fixup via pow2Matrix when no PS is used. */ 5120 if (!use_ps(state)) 5121 { 5122 TRACE("Non-power-of-two texture matrix multiply fixup.\n"); 5123 multiply_matrix(mat, mat, (struct wined3d_matrix *)state->textures[tex]->pow2_matrix); 5124 } 5125 } 5126 } 5127 5128 void get_pointsize_minmax(const struct wined3d_context *context, const struct wined3d_state *state, 5129 float *out_min, float *out_max) 5130 { 5131 union 5132 { 5133 DWORD d; 5134 float f; 5135 } min, max; 5136 5137 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN]; 5138 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX]; 5139 5140 if (min.f > max.f) 5141 min.f = max.f; 5142 5143 *out_min = min.f; 5144 *out_max = max.f; 5145 } 5146 5147 void get_pointsize(const struct wined3d_context *context, const struct wined3d_state *state, 5148 float *out_pointsize, float *out_att) 5149 { 5150 /* POINTSCALEENABLE controls how point size value is treated. If set to 5151 * true, the point size is scaled with respect to height of viewport. 5152 * When set to false point size is in pixels. */ 5153 union 5154 { 5155 DWORD d; 5156 float f; 5157 } pointsize, a, b, c; 5158 5159 out_att[0] = 1.0f; 5160 out_att[1] = 0.0f; 5161 out_att[2] = 0.0f; 5162 5163 pointsize.d = state->render_states[WINED3D_RS_POINTSIZE]; 5164 a.d = state->render_states[WINED3D_RS_POINTSCALE_A]; 5165 b.d = state->render_states[WINED3D_RS_POINTSCALE_B]; 5166 c.d = state->render_states[WINED3D_RS_POINTSCALE_C]; 5167 5168 if (state->render_states[WINED3D_RS_POINTSCALEENABLE]) 5169 { 5170 float scale_factor = state->viewport.height * state->viewport.height; 5171 5172 out_att[0] = a.f / scale_factor; 5173 out_att[1] = b.f / scale_factor; 5174 out_att[2] = c.f / scale_factor; 5175 } 5176 *out_pointsize = pointsize.f; 5177 } 5178 5179 void get_fog_start_end(const struct wined3d_context *context, const struct wined3d_state *state, 5180 float *start, float *end) 5181 { 5182 union 5183 { 5184 DWORD d; 5185 float f; 5186 } tmpvalue; 5187 5188 switch (context->fog_source) 5189 { 5190 case FOGSOURCE_VS: 5191 *start = 1.0f; 5192 *end = 0.0f; 5193 break; 5194 5195 case FOGSOURCE_COORD: 5196 *start = 255.0f; 5197 *end = 0.0f; 5198 break; 5199 5200 case FOGSOURCE_FFP: 5201 tmpvalue.d = state->render_states[WINED3D_RS_FOGSTART]; 5202 *start = tmpvalue.f; 5203 tmpvalue.d = state->render_states[WINED3D_RS_FOGEND]; 5204 *end = tmpvalue.f; 5205 /* Special handling for fog_start == fog_end. In d3d with vertex 5206 * fog, everything is fogged. With table fog, everything with 5207 * fog_coord < fog_start is unfogged, and fog_coord > fog_start 5208 * is fogged. Windows drivers disagree when fog_coord == fog_start. */ 5209 if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE && *start == *end) 5210 { 5211 *start = -INFINITY; 5212 *end = 0.0f; 5213 } 5214 break; 5215 5216 default: 5217 /* This should not happen, context->fog_source is set in wined3d, not the app. */ 5218 ERR("Unexpected fog coordinate source.\n"); 5219 *start = 0.0f; 5220 *end = 0.0f; 5221 } 5222 } 5223 5224 /* Note: It's the caller's responsibility to ensure values can be expressed 5225 * in the requested format. UNORM formats for example can only express values 5226 * in the range 0.0f -> 1.0f. */ 5227 DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, const struct wined3d_color *color) 5228 { 5229 static const struct 5230 { 5231 enum wined3d_format_id format_id; 5232 struct wined3d_vec4 mul; 5233 struct wined3d_uvec4 shift; 5234 } 5235 float_conv[] = 5236 { 5237 {WINED3DFMT_B8G8R8A8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, {16, 8, 0, 24}}, 5238 {WINED3DFMT_B8G8R8X8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, {16, 8, 0, 24}}, 5239 {WINED3DFMT_B8G8R8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, {16, 8, 0, 24}}, 5240 {WINED3DFMT_B5G6R5_UNORM, { 31.0f, 63.0f, 31.0f, 0.0f}, {11, 5, 0, 0}}, 5241 {WINED3DFMT_B5G5R5A1_UNORM, { 31.0f, 31.0f, 31.0f, 1.0f}, {10, 5, 0, 15}}, 5242 {WINED3DFMT_B5G5R5X1_UNORM, { 31.0f, 31.0f, 31.0f, 1.0f}, {10, 5, 0, 15}}, 5243 {WINED3DFMT_R8_UNORM, { 255.0f, 0.0f, 0.0f, 0.0f}, { 0, 0, 0, 0}}, 5244 {WINED3DFMT_A8_UNORM, { 0.0f, 0.0f, 0.0f, 255.0f}, { 0, 0, 0, 0}}, 5245 {WINED3DFMT_B4G4R4A4_UNORM, { 15.0f, 15.0f, 15.0f, 15.0f}, { 8, 4, 0, 12}}, 5246 {WINED3DFMT_B4G4R4X4_UNORM, { 15.0f, 15.0f, 15.0f, 15.0f}, { 8, 4, 0, 12}}, 5247 {WINED3DFMT_B2G3R3_UNORM, { 7.0f, 7.0f, 3.0f, 0.0f}, { 5, 2, 0, 0}}, 5248 {WINED3DFMT_R8G8B8A8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, { 0, 8, 16, 24}}, 5249 {WINED3DFMT_R8G8B8X8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, { 0, 8, 16, 24}}, 5250 {WINED3DFMT_B10G10R10A2_UNORM, { 1023.0f, 1023.0f, 1023.0f, 3.0f}, {20, 10, 0, 30}}, 5251 {WINED3DFMT_R10G10B10A2_UNORM, { 1023.0f, 1023.0f, 1023.0f, 3.0f}, { 0, 10, 20, 30}}, 5252 {WINED3DFMT_P8_UINT, { 0.0f, 0.0f, 0.0f, 255.0f}, { 0, 0, 0, 0}}, 5253 {WINED3DFMT_S1_UINT_D15_UNORM, { 32767.0f, 0.0f, 0.0f, 0.0f}, { 0, 0, 0, 0}}, 5254 {WINED3DFMT_D16_UNORM, { 65535.0f, 0.0f, 0.0f, 0.0f}, { 0, 0, 0, 0}}, 5255 }; 5256 static const struct 5257 { 5258 enum wined3d_format_id format_id; 5259 struct wined3d_dvec4 mul; 5260 struct wined3d_uvec4 shift; 5261 } 5262 double_conv[] = 5263 { 5264 {WINED3DFMT_D24_UNORM_S8_UINT, { 16777215.0, 1.0, 0.0, 0.0}, {8, 0, 0, 0}}, 5265 {WINED3DFMT_X8D24_UNORM, { 16777215.0, 0.0, 0.0, 0.0}, {0, 0, 0, 0}}, 5266 {WINED3DFMT_D32_UNORM, {4294967295.0, 0.0, 0.0, 0.0}, {0, 0, 0, 0}}, 5267 }; 5268 unsigned int i; 5269 DWORD ret; 5270 5271 TRACE("Converting color %s to format %s.\n", debug_color(color), debug_d3dformat(format->id)); 5272 5273 for (i = 0; i < ARRAY_SIZE(float_conv); ++i) 5274 { 5275 if (format->id != float_conv[i].format_id) 5276 continue; 5277 5278 ret = ((DWORD)((color->r * float_conv[i].mul.x) + 0.5f)) << float_conv[i].shift.x; 5279 ret |= ((DWORD)((color->g * float_conv[i].mul.y) + 0.5f)) << float_conv[i].shift.y; 5280 ret |= ((DWORD)((color->b * float_conv[i].mul.z) + 0.5f)) << float_conv[i].shift.z; 5281 ret |= ((DWORD)((color->a * float_conv[i].mul.w) + 0.5f)) << float_conv[i].shift.w; 5282 5283 TRACE("Returning 0x%08x.\n", ret); 5284 5285 return ret; 5286 } 5287 5288 for (i = 0; i < ARRAY_SIZE(double_conv); ++i) 5289 { 5290 if (format->id != double_conv[i].format_id) 5291 continue; 5292 5293 ret = ((DWORD)((color->r * double_conv[i].mul.x) + 0.5)) << double_conv[i].shift.x; 5294 ret |= ((DWORD)((color->g * double_conv[i].mul.y) + 0.5)) << double_conv[i].shift.y; 5295 ret |= ((DWORD)((color->b * double_conv[i].mul.z) + 0.5)) << double_conv[i].shift.z; 5296 ret |= ((DWORD)((color->a * double_conv[i].mul.w) + 0.5)) << double_conv[i].shift.w; 5297 5298 TRACE("Returning 0x%08x.\n", ret); 5299 5300 return ret; 5301 } 5302 5303 FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id)); 5304 5305 return 0; 5306 } 5307 5308 static float color_to_float(DWORD color, DWORD size, DWORD offset) 5309 { 5310 DWORD mask = size < 32 ? (1u << size) - 1 : ~0u; 5311 5312 if (!size) 5313 return 1.0f; 5314 5315 color >>= offset; 5316 color &= mask; 5317 5318 return (float)color / (float)mask; 5319 } 5320 5321 void wined3d_format_get_float_color_key(const struct wined3d_format *format, 5322 const struct wined3d_color_key *key, struct wined3d_color *float_colors) 5323 { 5324 struct wined3d_color slop; 5325 5326 switch (format->id) 5327 { 5328 case WINED3DFMT_B8G8R8_UNORM: 5329 case WINED3DFMT_B8G8R8A8_UNORM: 5330 case WINED3DFMT_B8G8R8X8_UNORM: 5331 case WINED3DFMT_B5G6R5_UNORM: 5332 case WINED3DFMT_B5G5R5X1_UNORM: 5333 case WINED3DFMT_B5G5R5A1_UNORM: 5334 case WINED3DFMT_B4G4R4A4_UNORM: 5335 case WINED3DFMT_B2G3R3_UNORM: 5336 case WINED3DFMT_R8_UNORM: 5337 case WINED3DFMT_A8_UNORM: 5338 case WINED3DFMT_B2G3R3A8_UNORM: 5339 case WINED3DFMT_B4G4R4X4_UNORM: 5340 case WINED3DFMT_R10G10B10A2_UNORM: 5341 case WINED3DFMT_R10G10B10A2_SNORM: 5342 case WINED3DFMT_R8G8B8A8_UNORM: 5343 case WINED3DFMT_R8G8B8X8_UNORM: 5344 case WINED3DFMT_R16G16_UNORM: 5345 case WINED3DFMT_B10G10R10A2_UNORM: 5346 slop.r = 0.5f / ((1u << format->red_size) - 1); 5347 slop.g = 0.5f / ((1u << format->green_size) - 1); 5348 slop.b = 0.5f / ((1u << format->blue_size) - 1); 5349 slop.a = 0.5f / ((1u << format->alpha_size) - 1); 5350 5351 float_colors[0].r = color_to_float(key->color_space_low_value, format->red_size, format->red_offset) 5352 - slop.r; 5353 float_colors[0].g = color_to_float(key->color_space_low_value, format->green_size, format->green_offset) 5354 - slop.g; 5355 float_colors[0].b = color_to_float(key->color_space_low_value, format->blue_size, format->blue_offset) 5356 - slop.b; 5357 float_colors[0].a = color_to_float(key->color_space_low_value, format->alpha_size, format->alpha_offset) 5358 - slop.a; 5359 5360 float_colors[1].r = color_to_float(key->color_space_high_value, format->red_size, format->red_offset) 5361 + slop.r; 5362 float_colors[1].g = color_to_float(key->color_space_high_value, format->green_size, format->green_offset) 5363 + slop.g; 5364 float_colors[1].b = color_to_float(key->color_space_high_value, format->blue_size, format->blue_offset) 5365 + slop.b; 5366 float_colors[1].a = color_to_float(key->color_space_high_value, format->alpha_size, format->alpha_offset) 5367 + slop.a; 5368 break; 5369 5370 case WINED3DFMT_P8_UINT: 5371 float_colors[0].r = 0.0f; 5372 float_colors[0].g = 0.0f; 5373 float_colors[0].b = 0.0f; 5374 float_colors[0].a = (key->color_space_low_value - 0.5f) / 255.0f; 5375 5376 float_colors[1].r = 0.0f; 5377 float_colors[1].g = 0.0f; 5378 float_colors[1].b = 0.0f; 5379 float_colors[1].a = (key->color_space_high_value + 0.5f) / 255.0f; 5380 break; 5381 5382 default: 5383 ERR("Unhandled color key to float conversion for format %s.\n", debug_d3dformat(format->id)); 5384 } 5385 } 5386 5387 /* DirectDraw stuff */ 5388 enum wined3d_format_id pixelformat_for_depth(DWORD depth) 5389 { 5390 switch (depth) 5391 { 5392 case 8: return WINED3DFMT_P8_UINT; 5393 case 15: return WINED3DFMT_B5G5R5X1_UNORM; 5394 case 16: return WINED3DFMT_B5G6R5_UNORM; 5395 case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */ 5396 case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */ 5397 default: return WINED3DFMT_UNKNOWN; 5398 } 5399 } 5400 5401 void multiply_matrix(struct wined3d_matrix *dst, const struct wined3d_matrix *src1, const struct wined3d_matrix *src2) 5402 { 5403 struct wined3d_matrix tmp; 5404 5405 /* Now do the multiplication 'by hand'. 5406 I know that all this could be optimised, but this will be done later :-) */ 5407 tmp._11 = (src1->_11 * src2->_11) + (src1->_21 * src2->_12) + (src1->_31 * src2->_13) + (src1->_41 * src2->_14); 5408 tmp._21 = (src1->_11 * src2->_21) + (src1->_21 * src2->_22) + (src1->_31 * src2->_23) + (src1->_41 * src2->_24); 5409 tmp._31 = (src1->_11 * src2->_31) + (src1->_21 * src2->_32) + (src1->_31 * src2->_33) + (src1->_41 * src2->_34); 5410 tmp._41 = (src1->_11 * src2->_41) + (src1->_21 * src2->_42) + (src1->_31 * src2->_43) + (src1->_41 * src2->_44); 5411 5412 tmp._12 = (src1->_12 * src2->_11) + (src1->_22 * src2->_12) + (src1->_32 * src2->_13) + (src1->_42 * src2->_14); 5413 tmp._22 = (src1->_12 * src2->_21) + (src1->_22 * src2->_22) + (src1->_32 * src2->_23) + (src1->_42 * src2->_24); 5414 tmp._32 = (src1->_12 * src2->_31) + (src1->_22 * src2->_32) + (src1->_32 * src2->_33) + (src1->_42 * src2->_34); 5415 tmp._42 = (src1->_12 * src2->_41) + (src1->_22 * src2->_42) + (src1->_32 * src2->_43) + (src1->_42 * src2->_44); 5416 5417 tmp._13 = (src1->_13 * src2->_11) + (src1->_23 * src2->_12) + (src1->_33 * src2->_13) + (src1->_43 * src2->_14); 5418 tmp._23 = (src1->_13 * src2->_21) + (src1->_23 * src2->_22) + (src1->_33 * src2->_23) + (src1->_43 * src2->_24); 5419 tmp._33 = (src1->_13 * src2->_31) + (src1->_23 * src2->_32) + (src1->_33 * src2->_33) + (src1->_43 * src2->_34); 5420 tmp._43 = (src1->_13 * src2->_41) + (src1->_23 * src2->_42) + (src1->_33 * src2->_43) + (src1->_43 * src2->_44); 5421 5422 tmp._14 = (src1->_14 * src2->_11) + (src1->_24 * src2->_12) + (src1->_34 * src2->_13) + (src1->_44 * src2->_14); 5423 tmp._24 = (src1->_14 * src2->_21) + (src1->_24 * src2->_22) + (src1->_34 * src2->_23) + (src1->_44 * src2->_24); 5424 tmp._34 = (src1->_14 * src2->_31) + (src1->_24 * src2->_32) + (src1->_34 * src2->_33) + (src1->_44 * src2->_34); 5425 tmp._44 = (src1->_14 * src2->_41) + (src1->_24 * src2->_42) + (src1->_34 * src2->_43) + (src1->_44 * src2->_44); 5426 5427 *dst = tmp; 5428 } 5429 5430 /* Taken and adapted from Mesa. */ 5431 BOOL invert_matrix_3d(struct wined3d_matrix *out, const struct wined3d_matrix *in) 5432 { 5433 float pos, neg, t, det; 5434 struct wined3d_matrix temp; 5435 5436 /* Calculate the determinant of upper left 3x3 submatrix and 5437 * determine if the matrix is singular. */ 5438 pos = neg = 0.0f; 5439 t = in->_11 * in->_22 * in->_33; 5440 if (t >= 0.0f) 5441 pos += t; 5442 else 5443 neg += t; 5444 5445 t = in->_21 * in->_32 * in->_13; 5446 if (t >= 0.0f) 5447 pos += t; 5448 else 5449 neg += t; 5450 t = in->_31 * in->_12 * in->_23; 5451 if (t >= 0.0f) 5452 pos += t; 5453 else 5454 neg += t; 5455 5456 t = -in->_31 * in->_22 * in->_13; 5457 if (t >= 0.0f) 5458 pos += t; 5459 else 5460 neg += t; 5461 t = -in->_21 * in->_12 * in->_33; 5462 if (t >= 0.0f) 5463 pos += t; 5464 else 5465 neg += t; 5466 5467 t = -in->_11 * in->_32 * in->_23; 5468 if (t >= 0.0f) 5469 pos += t; 5470 else 5471 neg += t; 5472 5473 det = pos + neg; 5474 5475 if (fabsf(det) < 1e-25f) 5476 return FALSE; 5477 5478 det = 1.0f / det; 5479 temp._11 = (in->_22 * in->_33 - in->_32 * in->_23) * det; 5480 temp._12 = -(in->_12 * in->_33 - in->_32 * in->_13) * det; 5481 temp._13 = (in->_12 * in->_23 - in->_22 * in->_13) * det; 5482 temp._21 = -(in->_21 * in->_33 - in->_31 * in->_23) * det; 5483 temp._22 = (in->_11 * in->_33 - in->_31 * in->_13) * det; 5484 temp._23 = -(in->_11 * in->_23 - in->_21 * in->_13) * det; 5485 temp._31 = (in->_21 * in->_32 - in->_31 * in->_22) * det; 5486 temp._32 = -(in->_11 * in->_32 - in->_31 * in->_12) * det; 5487 temp._33 = (in->_11 * in->_22 - in->_21 * in->_12) * det; 5488 5489 *out = temp; 5490 return TRUE; 5491 } 5492 5493 static void swap_rows(float **a, float **b) 5494 { 5495 float *tmp = *a; 5496 5497 *a = *b; 5498 *b = tmp; 5499 } 5500 5501 BOOL invert_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m) 5502 { 5503 float wtmp[4][8]; 5504 float m0, m1, m2, m3, s; 5505 float *r0, *r1, *r2, *r3; 5506 5507 r0 = wtmp[0]; 5508 r1 = wtmp[1]; 5509 r2 = wtmp[2]; 5510 r3 = wtmp[3]; 5511 5512 r0[0] = m->_11; 5513 r0[1] = m->_12; 5514 r0[2] = m->_13; 5515 r0[3] = m->_14; 5516 r0[4] = 1.0f; 5517 r0[5] = r0[6] = r0[7] = 0.0f; 5518 5519 r1[0] = m->_21; 5520 r1[1] = m->_22; 5521 r1[2] = m->_23; 5522 r1[3] = m->_24; 5523 r1[5] = 1.0f; 5524 r1[4] = r1[6] = r1[7] = 0.0f; 5525 5526 r2[0] = m->_31; 5527 r2[1] = m->_32; 5528 r2[2] = m->_33; 5529 r2[3] = m->_34; 5530 r2[6] = 1.0f; 5531 r2[4] = r2[5] = r2[7] = 0.0f; 5532 5533 r3[0] = m->_41; 5534 r3[1] = m->_42; 5535 r3[2] = m->_43; 5536 r3[3] = m->_44; 5537 r3[7] = 1.0f; 5538 r3[4] = r3[5] = r3[6] = 0.0f; 5539 5540 /* Choose pivot - or die. */ 5541 if (fabsf(r3[0]) > fabsf(r2[0])) 5542 swap_rows(&r3, &r2); 5543 if (fabsf(r2[0]) > fabsf(r1[0])) 5544 swap_rows(&r2, &r1); 5545 if (fabsf(r1[0]) > fabsf(r0[0])) 5546 swap_rows(&r1, &r0); 5547 if (r0[0] == 0.0f) 5548 return FALSE; 5549 5550 /* Eliminate first variable. */ 5551 m1 = r1[0] / r0[0]; m2 = r2[0] / r0[0]; m3 = r3[0] / r0[0]; 5552 s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s; 5553 s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s; 5554 s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s; 5555 s = r0[4]; 5556 if (s != 0.0f) 5557 { 5558 r1[4] -= m1 * s; 5559 r2[4] -= m2 * s; 5560 r3[4] -= m3 * s; 5561 } 5562 s = r0[5]; 5563 if (s != 0.0f) 5564 { 5565 r1[5] -= m1 * s; 5566 r2[5] -= m2 * s; 5567 r3[5] -= m3 * s; 5568 } 5569 s = r0[6]; 5570 if (s != 0.0f) 5571 { 5572 r1[6] -= m1 * s; 5573 r2[6] -= m2 * s; 5574 r3[6] -= m3 * s; 5575 } 5576 s = r0[7]; 5577 if (s != 0.0f) 5578 { 5579 r1[7] -= m1 * s; 5580 r2[7] -= m2 * s; 5581 r3[7] -= m3 * s; 5582 } 5583 5584 /* Choose pivot - or die. */ 5585 if (fabsf(r3[1]) > fabsf(r2[1])) 5586 swap_rows(&r3, &r2); 5587 if (fabsf(r2[1]) > fabsf(r1[1])) 5588 swap_rows(&r2, &r1); 5589 if (r1[1] == 0.0f) 5590 return FALSE; 5591 5592 /* Eliminate second variable. */ 5593 m2 = r2[1] / r1[1]; m3 = r3[1] / r1[1]; 5594 r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2]; 5595 r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3]; 5596 s = r1[4]; 5597 if (s != 0.0f) 5598 { 5599 r2[4] -= m2 * s; 5600 r3[4] -= m3 * s; 5601 } 5602 s = r1[5]; 5603 if (s != 0.0f) 5604 { 5605 r2[5] -= m2 * s; 5606 r3[5] -= m3 * s; 5607 } 5608 s = r1[6]; 5609 if (s != 0.0f) 5610 { 5611 r2[6] -= m2 * s; 5612 r3[6] -= m3 * s; 5613 } 5614 s = r1[7]; 5615 if (s != 0.0f) 5616 { 5617 r2[7] -= m2 * s; 5618 r3[7] -= m3 * s; 5619 } 5620 5621 /* Choose pivot - or die. */ 5622 if (fabsf(r3[2]) > fabsf(r2[2])) 5623 swap_rows(&r3, &r2); 5624 if (r2[2] == 0.0f) 5625 return FALSE; 5626 5627 /* Eliminate third variable. */ 5628 m3 = r3[2] / r2[2]; 5629 r3[3] -= m3 * r2[3]; 5630 r3[4] -= m3 * r2[4]; 5631 r3[5] -= m3 * r2[5]; 5632 r3[6] -= m3 * r2[6]; 5633 r3[7] -= m3 * r2[7]; 5634 5635 /* Last check. */ 5636 if (r3[3] == 0.0f) 5637 return FALSE; 5638 5639 /* Back substitute row 3. */ 5640 s = 1.0f / r3[3]; 5641 r3[4] *= s; 5642 r3[5] *= s; 5643 r3[6] *= s; 5644 r3[7] *= s; 5645 5646 /* Back substitute row 2. */ 5647 m2 = r2[3]; 5648 s = 1.0f / r2[2]; 5649 r2[4] = s * (r2[4] - r3[4] * m2); 5650 r2[5] = s * (r2[5] - r3[5] * m2); 5651 r2[6] = s * (r2[6] - r3[6] * m2); 5652 r2[7] = s * (r2[7] - r3[7] * m2); 5653 m1 = r1[3]; 5654 r1[4] -= r3[4] * m1; 5655 r1[5] -= r3[5] * m1; 5656 r1[6] -= r3[6] * m1; 5657 r1[7] -= r3[7] * m1; 5658 m0 = r0[3]; 5659 r0[4] -= r3[4] * m0; 5660 r0[5] -= r3[5] * m0; 5661 r0[6] -= r3[6] * m0; 5662 r0[7] -= r3[7] * m0; 5663 5664 /* Back substitute row 1. */ 5665 m1 = r1[2]; 5666 s = 1.0f / r1[1]; 5667 r1[4] = s * (r1[4] - r2[4] * m1); 5668 r1[5] = s * (r1[5] - r2[5] * m1); 5669 r1[6] = s * (r1[6] - r2[6] * m1); 5670 r1[7] = s * (r1[7] - r2[7] * m1); 5671 m0 = r0[2]; 5672 r0[4] -= r2[4] * m0; 5673 r0[5] -= r2[5] * m0; 5674 r0[6] -= r2[6] * m0; 5675 r0[7] -= r2[7] * m0; 5676 5677 /* Back substitute row 0. */ 5678 m0 = r0[1]; 5679 s = 1.0f / r0[0]; 5680 r0[4] = s * (r0[4] - r1[4] * m0); 5681 r0[5] = s * (r0[5] - r1[5] * m0); 5682 r0[6] = s * (r0[6] - r1[6] * m0); 5683 r0[7] = s * (r0[7] - r1[7] * m0); 5684 5685 out->_11 = r0[4]; 5686 out->_12 = r0[5]; 5687 out->_13 = r0[6]; 5688 out->_14 = r0[7]; 5689 out->_21 = r1[4]; 5690 out->_22 = r1[5]; 5691 out->_23 = r1[6]; 5692 out->_24 = r1[7]; 5693 out->_31 = r2[4]; 5694 out->_32 = r2[5]; 5695 out->_33 = r2[6]; 5696 out->_34 = r2[7]; 5697 out->_41 = r3[4]; 5698 out->_42 = r3[5]; 5699 out->_43 = r3[6]; 5700 out->_44 = r3[7]; 5701 5702 return TRUE; 5703 } 5704 5705 void transpose_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m) 5706 { 5707 struct wined3d_matrix temp; 5708 unsigned int i, j; 5709 5710 for (i = 0; i < 4; ++i) 5711 for (j = 0; j < 4; ++j) 5712 (&temp._11)[4 * j + i] = (&m->_11)[4 * i + j]; 5713 5714 *out = temp; 5715 } 5716 5717 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) { 5718 DWORD size = 0; 5719 int i; 5720 int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT; 5721 5722 if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float); 5723 if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD); 5724 if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD); 5725 if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD); 5726 switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) { 5727 case WINED3DFVF_XYZ: size += 3 * sizeof(float); break; 5728 case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break; 5729 case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break; 5730 case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break; 5731 case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break; 5732 case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break; 5733 case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break; 5734 case WINED3DFVF_XYZW: size += 4 * sizeof(float); break; 5735 default: ERR("Unexpected position mask\n"); 5736 } 5737 for (i = 0; i < numTextures; i++) { 5738 size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float); 5739 } 5740 5741 return size; 5742 } 5743 5744 unsigned int wined3d_max_compat_varyings(const struct wined3d_gl_info *gl_info) 5745 { 5746 /* On core profile we have to also count diffuse and specular colors and the 5747 * fog coordinate. */ 5748 return gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? MAX_TEXTURES * 4 : (MAX_TEXTURES + 2) * 4 + 1; 5749 } 5750 5751 void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d_state *state, 5752 struct ffp_frag_settings *settings, BOOL ignore_textype) 5753 { 5754 #define ARG1 0x01 5755 #define ARG2 0x02 5756 #define ARG0 0x04 5757 static const unsigned char args[WINED3D_TOP_LERP + 1] = 5758 { 5759 /* undefined */ 0, 5760 /* D3DTOP_DISABLE */ 0, 5761 /* D3DTOP_SELECTARG1 */ ARG1, 5762 /* D3DTOP_SELECTARG2 */ ARG2, 5763 /* D3DTOP_MODULATE */ ARG1 | ARG2, 5764 /* D3DTOP_MODULATE2X */ ARG1 | ARG2, 5765 /* D3DTOP_MODULATE4X */ ARG1 | ARG2, 5766 /* D3DTOP_ADD */ ARG1 | ARG2, 5767 /* D3DTOP_ADDSIGNED */ ARG1 | ARG2, 5768 /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2, 5769 /* D3DTOP_SUBTRACT */ ARG1 | ARG2, 5770 /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2, 5771 /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2, 5772 /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2, 5773 /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2, 5774 /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2, 5775 /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2, 5776 /* D3DTOP_PREMODULATE */ ARG1 | ARG2, 5777 /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2, 5778 /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2, 5779 /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2, 5780 /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2, 5781 /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2, 5782 /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2, 5783 /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2, 5784 /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0, 5785 /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0 5786 }; 5787 unsigned int i; 5788 DWORD ttff; 5789 DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2; 5790 const struct wined3d_gl_info *gl_info = context->gl_info; 5791 const struct wined3d_d3d_info *d3d_info = context->d3d_info; 5792 5793 settings->padding = 0; 5794 5795 for (i = 0; i < d3d_info->limits.ffp_blend_stages; ++i) 5796 { 5797 const struct wined3d_texture *texture; 5798 5799 settings->op[i].padding = 0; 5800 if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE) 5801 { 5802 settings->op[i].cop = WINED3D_TOP_DISABLE; 5803 settings->op[i].aop = WINED3D_TOP_DISABLE; 5804 settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED; 5805 settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED; 5806 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY; 5807 settings->op[i].dst = resultreg; 5808 settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_1D; 5809 settings->op[i].projected = proj_none; 5810 i++; 5811 break; 5812 } 5813 5814 if ((texture = state->textures[i])) 5815 { 5816 if (can_use_texture_swizzle(gl_info, texture->resource.format)) 5817 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY; 5818 else 5819 settings->op[i].color_fixup = texture->resource.format->color_fixup; 5820 if (ignore_textype) 5821 { 5822 settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_1D; 5823 } 5824 else 5825 { 5826 switch (texture->target) 5827 { 5828 case GL_TEXTURE_1D: 5829 settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_1D; 5830 break; 5831 case GL_TEXTURE_2D: 5832 settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_2D; 5833 break; 5834 case GL_TEXTURE_3D: 5835 settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_3D; 5836 break; 5837 case GL_TEXTURE_CUBE_MAP_ARB: 5838 settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; 5839 break; 5840 case GL_TEXTURE_RECTANGLE_ARB: 5841 settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_RECT; 5842 break; 5843 } 5844 } 5845 } else { 5846 settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY; 5847 settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_1D; 5848 } 5849 5850 cop = state->texture_states[i][WINED3D_TSS_COLOR_OP]; 5851 aop = state->texture_states[i][WINED3D_TSS_ALPHA_OP]; 5852 5853 carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG1] : ARG_UNUSED; 5854 carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG2] : ARG_UNUSED; 5855 carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG0] : ARG_UNUSED; 5856 5857 if (is_invalid_op(state, i, cop, carg1, carg2, carg0)) 5858 { 5859 carg0 = ARG_UNUSED; 5860 carg2 = ARG_UNUSED; 5861 carg1 = WINED3DTA_CURRENT; 5862 cop = WINED3D_TOP_SELECT_ARG1; 5863 } 5864 5865 if (cop == WINED3D_TOP_DOTPRODUCT3) 5866 { 5867 /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates 5868 * the color result to the alpha component of the destination 5869 */ 5870 aop = cop; 5871 aarg1 = carg1; 5872 aarg2 = carg2; 5873 aarg0 = carg0; 5874 } 5875 else 5876 { 5877 aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] : ARG_UNUSED; 5878 aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] : ARG_UNUSED; 5879 aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] : ARG_UNUSED; 5880 } 5881 5882 if (!i && state->textures[0] && state->render_states[WINED3D_RS_COLORKEYENABLE]) 5883 { 5884 GLenum texture_dimensions; 5885 5886 texture = state->textures[0]; 5887 texture_dimensions = texture->target; 5888 5889 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) 5890 { 5891 if (texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT && !texture->resource.format->alpha_size) 5892 { 5893 if (aop == WINED3D_TOP_DISABLE) 5894 { 5895 aarg1 = WINED3DTA_TEXTURE; 5896 aop = WINED3D_TOP_SELECT_ARG1; 5897 } 5898 else if (aop == WINED3D_TOP_SELECT_ARG1 && aarg1 != WINED3DTA_TEXTURE) 5899 { 5900 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE]) 5901 { 5902 aarg2 = WINED3DTA_TEXTURE; 5903 aop = WINED3D_TOP_MODULATE; 5904 } 5905 else aarg1 = WINED3DTA_TEXTURE; 5906 } 5907 else if (aop == WINED3D_TOP_SELECT_ARG2 && aarg2 != WINED3DTA_TEXTURE) 5908 { 5909 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE]) 5910 { 5911 aarg1 = WINED3DTA_TEXTURE; 5912 aop = WINED3D_TOP_MODULATE; 5913 } 5914 else aarg2 = WINED3DTA_TEXTURE; 5915 } 5916 } 5917 } 5918 } 5919 5920 if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0)) 5921 { 5922 aarg0 = ARG_UNUSED; 5923 aarg2 = ARG_UNUSED; 5924 aarg1 = WINED3DTA_CURRENT; 5925 aop = WINED3D_TOP_SELECT_ARG1; 5926 } 5927 5928 if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE 5929 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE) 5930 { 5931 ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS]; 5932 if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3)) 5933 settings->op[i].projected = proj_count3; 5934 else if (ttff & WINED3D_TTFF_PROJECTED) 5935 settings->op[i].projected = proj_count4; 5936 else 5937 settings->op[i].projected = proj_none; 5938 } 5939 else 5940 { 5941 settings->op[i].projected = proj_none; 5942 } 5943 5944 settings->op[i].cop = cop; 5945 settings->op[i].aop = aop; 5946 settings->op[i].carg0 = carg0; 5947 settings->op[i].carg1 = carg1; 5948 settings->op[i].carg2 = carg2; 5949 settings->op[i].aarg0 = aarg0; 5950 settings->op[i].aarg1 = aarg1; 5951 settings->op[i].aarg2 = aarg2; 5952 5953 if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP) 5954 settings->op[i].dst = tempreg; 5955 else 5956 settings->op[i].dst = resultreg; 5957 } 5958 5959 /* Clear unsupported stages */ 5960 for(; i < MAX_TEXTURES; i++) { 5961 memset(&settings->op[i], 0xff, sizeof(settings->op[i])); 5962 } 5963 5964 if (!state->render_states[WINED3D_RS_FOGENABLE]) 5965 { 5966 settings->fog = WINED3D_FFP_PS_FOG_OFF; 5967 } 5968 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE) 5969 { 5970 if (use_vs(state) || state->vertex_declaration->position_transformed) 5971 { 5972 settings->fog = WINED3D_FFP_PS_FOG_LINEAR; 5973 } 5974 else 5975 { 5976 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE]) 5977 { 5978 case WINED3D_FOG_NONE: 5979 case WINED3D_FOG_LINEAR: 5980 settings->fog = WINED3D_FFP_PS_FOG_LINEAR; 5981 break; 5982 case WINED3D_FOG_EXP: 5983 settings->fog = WINED3D_FFP_PS_FOG_EXP; 5984 break; 5985 case WINED3D_FOG_EXP2: 5986 settings->fog = WINED3D_FFP_PS_FOG_EXP2; 5987 break; 5988 } 5989 } 5990 } 5991 else 5992 { 5993 switch (state->render_states[WINED3D_RS_FOGTABLEMODE]) 5994 { 5995 case WINED3D_FOG_LINEAR: 5996 settings->fog = WINED3D_FFP_PS_FOG_LINEAR; 5997 break; 5998 case WINED3D_FOG_EXP: 5999 settings->fog = WINED3D_FFP_PS_FOG_EXP; 6000 break; 6001 case WINED3D_FOG_EXP2: 6002 settings->fog = WINED3D_FFP_PS_FOG_EXP2; 6003 break; 6004 } 6005 } 6006 settings->sRGB_write = !gl_info->supported[ARB_FRAMEBUFFER_SRGB] && needs_srgb_write(context, state, state->fb); 6007 if (d3d_info->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING] 6008 || !state->render_states[WINED3D_RS_CLIPPLANEENABLE]) 6009 { 6010 /* No need to emulate clipplanes if GL supports native vertex shader clipping or if 6011 * the fixed function vertex pipeline is used(which always supports clipplanes), or 6012 * if no clipplane is enabled 6013 */ 6014 settings->emul_clipplanes = 0; 6015 } else { 6016 settings->emul_clipplanes = 1; 6017 } 6018 6019 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && state->textures[0] 6020 && state->textures[0]->async.color_key_flags & WINED3D_CKEY_SRC_BLT 6021 && settings->op[0].cop != WINED3D_TOP_DISABLE) 6022 settings->color_key_enabled = 1; 6023 else 6024 settings->color_key_enabled = 0; 6025 6026 /* texcoords_initialized is set to meaningful values only when GL doesn't 6027 * support enough varyings to always pass around all the possible texture 6028 * coordinates. 6029 * This is used to avoid reading a varying not written by the vertex shader. 6030 * Reading uninitialized varyings on core profile contexts results in an 6031 * error while with builtin varyings on legacy contexts you get undefined 6032 * behavior. */ 6033 if (d3d_info->limits.varying_count 6034 && d3d_info->limits.varying_count < wined3d_max_compat_varyings(gl_info)) 6035 { 6036 settings->texcoords_initialized = 0; 6037 for (i = 0; i < MAX_TEXTURES; ++i) 6038 { 6039 if (use_vs(state)) 6040 { 6041 if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.output_registers & (1u << i)) 6042 settings->texcoords_initialized |= 1u << i; 6043 } 6044 else 6045 { 6046 const struct wined3d_stream_info *si = &context->stream_info; 6047 unsigned int coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; 6048 if ((state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT) 6049 & WINED3D_FFP_TCI_MASK 6050 || (coord_idx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx))))) 6051 settings->texcoords_initialized |= 1u << i; 6052 } 6053 } 6054 } 6055 else 6056 { 6057 settings->texcoords_initialized = (1u << MAX_TEXTURES) - 1; 6058 } 6059 6060 settings->pointsprite = state->render_states[WINED3D_RS_POINTSPRITEENABLE] 6061 && state->gl_primitive_type == GL_POINTS; 6062 6063 if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) 6064 settings->alpha_test_func = WINED3D_CMP_ALWAYS - 1; 6065 else 6066 settings->alpha_test_func = (state->render_states[WINED3D_RS_ALPHATESTENABLE] 6067 ? wined3d_sanitize_cmp_func(state->render_states[WINED3D_RS_ALPHAFUNC]) 6068 : WINED3D_CMP_ALWAYS) - 1; 6069 6070 if (d3d_info->emulated_flatshading) 6071 settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; 6072 else 6073 settings->flatshading = FALSE; 6074 } 6075 6076 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders, 6077 const struct ffp_frag_settings *settings) 6078 { 6079 struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings); 6080 return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL; 6081 } 6082 6083 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc) 6084 { 6085 /* Note that the key is the implementation independent part of the ffp_frag_desc structure, 6086 * whereas desc points to an extended structure with implementation specific parts. */ 6087 if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1) 6088 { 6089 ERR("Failed to insert ffp frag shader.\n"); 6090 } 6091 } 6092 6093 /* Activates the texture dimension according to the bound D3D texture. Does 6094 * not care for the colorop or correct gl texture unit (when using nvrc). 6095 * Requires the caller to activate the correct unit. */ 6096 /* Context activation is done by the caller (state handler). */ 6097 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info) 6098 { 6099 if (texture) 6100 { 6101 switch (texture->target) 6102 { 6103 case GL_TEXTURE_1D: 6104 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); 6105 checkGLcall("glDisable(GL_TEXTURE_2D)"); 6106 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); 6107 checkGLcall("glDisable(GL_TEXTURE_3D)"); 6108 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) 6109 { 6110 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); 6111 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); 6112 } 6113 if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) 6114 { 6115 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); 6116 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); 6117 } 6118 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_1D); 6119 checkGLcall("glEnable(GL_TEXTURE_1D)"); 6120 break; 6121 case GL_TEXTURE_2D: 6122 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); 6123 checkGLcall("glDisable(GL_TEXTURE_1D)"); 6124 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); 6125 checkGLcall("glDisable(GL_TEXTURE_3D)"); 6126 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) 6127 { 6128 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); 6129 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); 6130 } 6131 if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) 6132 { 6133 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); 6134 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); 6135 } 6136 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D); 6137 checkGLcall("glEnable(GL_TEXTURE_2D)"); 6138 break; 6139 case GL_TEXTURE_RECTANGLE_ARB: 6140 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); 6141 checkGLcall("glDisable(GL_TEXTURE_1D)"); 6142 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); 6143 checkGLcall("glDisable(GL_TEXTURE_2D)"); 6144 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); 6145 checkGLcall("glDisable(GL_TEXTURE_3D)"); 6146 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) 6147 { 6148 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); 6149 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); 6150 } 6151 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_RECTANGLE_ARB); 6152 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)"); 6153 break; 6154 case GL_TEXTURE_3D: 6155 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) 6156 { 6157 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); 6158 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); 6159 } 6160 if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) 6161 { 6162 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); 6163 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); 6164 } 6165 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); 6166 checkGLcall("glDisable(GL_TEXTURE_1D)"); 6167 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); 6168 checkGLcall("glDisable(GL_TEXTURE_2D)"); 6169 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D); 6170 checkGLcall("glEnable(GL_TEXTURE_3D)"); 6171 break; 6172 case GL_TEXTURE_CUBE_MAP_ARB: 6173 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); 6174 checkGLcall("glDisable(GL_TEXTURE_1D)"); 6175 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); 6176 checkGLcall("glDisable(GL_TEXTURE_2D)"); 6177 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); 6178 checkGLcall("glDisable(GL_TEXTURE_3D)"); 6179 if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) 6180 { 6181 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); 6182 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); 6183 } 6184 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_CUBE_MAP_ARB); 6185 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)"); 6186 break; 6187 } 6188 } 6189 else 6190 { 6191 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); 6192 checkGLcall("glDisable(GL_TEXTURE_1D)"); 6193 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D); 6194 checkGLcall("glEnable(GL_TEXTURE_2D)"); 6195 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); 6196 checkGLcall("glDisable(GL_TEXTURE_3D)"); 6197 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) 6198 { 6199 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); 6200 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); 6201 } 6202 if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) 6203 { 6204 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); 6205 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); 6206 } 6207 /* Binding textures is done by samplers. A dummy texture will be bound */ 6208 } 6209 } 6210 6211 /* Context activation is done by the caller (state handler). */ 6212 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) 6213 { 6214 DWORD sampler = state_id - STATE_SAMPLER(0); 6215 DWORD mapped_stage = context->tex_unit_map[sampler]; 6216 6217 /* No need to enable / disable anything here for unused samplers. The 6218 * tex_colorop handler takes care. Also no action is needed with pixel 6219 * shaders, or if tex_colorop will take care of this business. */ 6220 if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) 6221 return; 6222 if (sampler >= context->lowest_disabled_stage) 6223 return; 6224 if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP))) 6225 return; 6226 6227 texture_activate_dimensions(state->textures[sampler], context->gl_info); 6228 } 6229 6230 int wined3d_ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry) 6231 { 6232 const struct ffp_frag_settings *ka = key; 6233 const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings; 6234 6235 return memcmp(ka, kb, sizeof(*ka)); 6236 } 6237 6238 void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, 6239 const struct wined3d_state *state, struct wined3d_ffp_vs_settings *settings) 6240 { 6241 const struct wined3d_stream_info *si = &context->stream_info; 6242 const struct wined3d_gl_info *gl_info = context->gl_info; 6243 const struct wined3d_d3d_info *d3d_info = context->d3d_info; 6244 unsigned int coord_idx, i; 6245 6246 memset(settings, 0, sizeof(*settings)); 6247 6248 if (si->position_transformed) 6249 { 6250 settings->transformed = 1; 6251 settings->point_size = state->gl_primitive_type == GL_POINTS; 6252 settings->per_vertex_point_size = !!(si->use_map & 1u << WINED3D_FFP_PSIZE); 6253 if (!state->render_states[WINED3D_RS_FOGENABLE]) 6254 settings->fog_mode = WINED3D_FFP_VS_FOG_OFF; 6255 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE) 6256 settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH; 6257 else 6258 settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD; 6259 6260 for (i = 0; i < MAX_TEXTURES; ++i) 6261 { 6262 coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; 6263 if (coord_idx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))) 6264 settings->texcoords |= 1u << i; 6265 settings->texgen[i] = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; 6266 } 6267 if (d3d_info->limits.varying_count >= wined3d_max_compat_varyings(gl_info)) 6268 settings->texcoords = (1u << MAX_TEXTURES) - 1; 6269 6270 if (d3d_info->emulated_flatshading) 6271 settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; 6272 else 6273 settings->flatshading = FALSE; 6274 6275 settings->swizzle_map = si->swizzle_map; 6276 6277 return; 6278 } 6279 6280 switch (state->render_states[WINED3D_RS_VERTEXBLEND]) 6281 { 6282 case WINED3D_VBF_DISABLE: 6283 case WINED3D_VBF_1WEIGHTS: 6284 case WINED3D_VBF_2WEIGHTS: 6285 case WINED3D_VBF_3WEIGHTS: 6286 settings->vertexblends = state->render_states[WINED3D_RS_VERTEXBLEND]; 6287 break; 6288 default: 6289 FIXME("Unsupported vertex blending: %d\n", state->render_states[WINED3D_RS_VERTEXBLEND]); 6290 break; 6291 } 6292 6293 if (use_indexed_vertex_blending(state, si)) 6294 { 6295 if (use_software_vertex_processing(context->device)) 6296 settings->sw_blending = 1; 6297 else 6298 settings->vb_indices = 1; 6299 } 6300 6301 settings->clipping = state->render_states[WINED3D_RS_CLIPPING] 6302 && state->render_states[WINED3D_RS_CLIPPLANEENABLE]; 6303 settings->normal = !!(si->use_map & (1u << WINED3D_FFP_NORMAL)); 6304 settings->normalize = settings->normal && state->render_states[WINED3D_RS_NORMALIZENORMALS]; 6305 settings->lighting = !!state->render_states[WINED3D_RS_LIGHTING]; 6306 settings->localviewer = !!state->render_states[WINED3D_RS_LOCALVIEWER]; 6307 settings->point_size = state->gl_primitive_type == GL_POINTS; 6308 settings->per_vertex_point_size = !!(si->use_map & 1u << WINED3D_FFP_PSIZE); 6309 6310 if (state->render_states[WINED3D_RS_COLORVERTEX] && (si->use_map & (1u << WINED3D_FFP_DIFFUSE))) 6311 { 6312 settings->diffuse_source = state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE]; 6313 settings->emissive_source = state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE]; 6314 settings->ambient_source = state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE]; 6315 settings->specular_source = state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]; 6316 } 6317 else 6318 { 6319 settings->diffuse_source = WINED3D_MCS_MATERIAL; 6320 settings->emissive_source = WINED3D_MCS_MATERIAL; 6321 settings->ambient_source = WINED3D_MCS_MATERIAL; 6322 settings->specular_source = WINED3D_MCS_MATERIAL; 6323 } 6324 6325 for (i = 0; i < MAX_TEXTURES; ++i) 6326 { 6327 coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; 6328 if (coord_idx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))) 6329 settings->texcoords |= 1u << i; 6330 settings->texgen[i] = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; 6331 } 6332 if (d3d_info->limits.varying_count >= wined3d_max_compat_varyings(gl_info)) 6333 settings->texcoords = (1u << MAX_TEXTURES) - 1; 6334 6335 for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i) 6336 { 6337 if (!state->lights[i]) 6338 continue; 6339 6340 switch (state->lights[i]->OriginalParms.type) 6341 { 6342 case WINED3D_LIGHT_POINT: 6343 ++settings->point_light_count; 6344 break; 6345 case WINED3D_LIGHT_SPOT: 6346 ++settings->spot_light_count; 6347 break; 6348 case WINED3D_LIGHT_DIRECTIONAL: 6349 ++settings->directional_light_count; 6350 break; 6351 case WINED3D_LIGHT_PARALLELPOINT: 6352 ++settings->parallel_point_light_count; 6353 break; 6354 default: 6355 FIXME("Unhandled light type %#x.\n", state->lights[i]->OriginalParms.type); 6356 break; 6357 } 6358 } 6359 6360 if (!state->render_states[WINED3D_RS_FOGENABLE]) 6361 settings->fog_mode = WINED3D_FFP_VS_FOG_OFF; 6362 else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE) 6363 { 6364 settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH; 6365 6366 if (state->transforms[WINED3D_TS_PROJECTION]._14 == 0.0f 6367 && state->transforms[WINED3D_TS_PROJECTION]._24 == 0.0f 6368 && state->transforms[WINED3D_TS_PROJECTION]._34 == 0.0f 6369 && state->transforms[WINED3D_TS_PROJECTION]._44 == 1.0f) 6370 settings->ortho_fog = 1; 6371 } 6372 else if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE) 6373 settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD; 6374 else if (state->render_states[WINED3D_RS_RANGEFOGENABLE]) 6375 settings->fog_mode = WINED3D_FFP_VS_FOG_RANGE; 6376 else 6377 settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH; 6378 6379 if (d3d_info->emulated_flatshading) 6380 settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; 6381 else 6382 settings->flatshading = FALSE; 6383 6384 settings->swizzle_map = si->swizzle_map; 6385 } 6386 6387 int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry) 6388 { 6389 const struct wined3d_ffp_vs_settings *ka = key; 6390 const struct wined3d_ffp_vs_settings *kb = &WINE_RB_ENTRY_VALUE(entry, 6391 const struct wined3d_ffp_vs_desc, entry)->settings; 6392 6393 return memcmp(ka, kb, sizeof(*ka)); 6394 } 6395 6396 const char *wined3d_debug_location(DWORD location) 6397 { 6398 struct debug_buffer buffer; 6399 const char *prefix = ""; 6400 const char *suffix = ""; 6401 6402 if (wined3d_popcount(location) > 16) 6403 { 6404 prefix = "~("; 6405 location = ~location; 6406 suffix = ")"; 6407 } 6408 6409 init_debug_buffer(&buffer, "0"); 6410 #define LOCATION_TO_STR(x) if (location & x) { debug_append(&buffer, #x, " | "); location &= ~x; } 6411 LOCATION_TO_STR(WINED3D_LOCATION_DISCARDED); 6412 LOCATION_TO_STR(WINED3D_LOCATION_SYSMEM); 6413 LOCATION_TO_STR(WINED3D_LOCATION_USER_MEMORY); 6414 LOCATION_TO_STR(WINED3D_LOCATION_BUFFER); 6415 LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_RGB); 6416 LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_SRGB); 6417 LOCATION_TO_STR(WINED3D_LOCATION_DRAWABLE); 6418 LOCATION_TO_STR(WINED3D_LOCATION_RB_MULTISAMPLE); 6419 LOCATION_TO_STR(WINED3D_LOCATION_RB_RESOLVED); 6420 #undef LOCATION_TO_STR 6421 if (location) 6422 FIXME("Unrecognized location flag(s) %#x.\n", location); 6423 6424 return wine_dbg_sprintf("%s%s%s", prefix, buffer.str, suffix); 6425 } 6426 6427 /* Print a floating point value with the %.8e format specifier, always using 6428 * '.' as decimal separator. */ 6429 void wined3d_ftoa(float value, char *s) 6430 { 6431 int idx = 1; 6432 6433 if (copysignf(1.0f, value) < 0.0f) 6434 ++idx; 6435 6436 /* Be sure to allocate a buffer of at least 17 characters for the result 6437 as sprintf may return a 3 digit exponent when using the MSVC runtime 6438 instead of a 2 digit exponent. */ 6439 sprintf(s, "%.8e", value); 6440 if (isfinite(value)) 6441 s[idx] = '.'; 6442 } 6443 6444 void wined3d_release_dc(HWND window, HDC dc) 6445 { 6446 /* You'd figure ReleaseDC() would fail if the DC doesn't match the window. 6447 * However, that's not what actually happens, and there are user32 tests 6448 * that confirm ReleaseDC() with the wrong window is supposed to succeed. 6449 * So explicitly check that the DC belongs to the window, since we want to 6450 * avoid releasing a DC that belongs to some other window if the original 6451 * window was already destroyed. */ 6452 if (WindowFromDC(dc) != window) 6453 WARN("DC %p does not belong to window %p.\n", dc, window); 6454 else if (!ReleaseDC(window, dc)) 6455 ERR("Failed to release device context %p, last error %#x.\n", dc, GetLastError()); 6456 } 6457 6458 BOOL wined3d_clip_blit(const RECT *clip_rect, RECT *clipped, RECT *other) 6459 { 6460 RECT orig = *clipped; 6461 float scale_x = (float)(orig.right - orig.left) / (float)(other->right - other->left); 6462 float scale_y = (float)(orig.bottom - orig.top) / (float)(other->bottom - other->top); 6463 6464 IntersectRect(clipped, clipped, clip_rect); 6465 6466 if (IsRectEmpty(clipped)) 6467 { 6468 SetRectEmpty(other); 6469 return FALSE; 6470 } 6471 6472 other->left += (LONG)((clipped->left - orig.left) / scale_x); 6473 other->top += (LONG)((clipped->top - orig.top) / scale_y); 6474 other->right -= (LONG)((orig.right - clipped->right) / scale_x); 6475 other->bottom -= (LONG)((orig.bottom - clipped->bottom) / scale_y); 6476 6477 return TRUE; 6478 } 6479 6480 void wined3d_gl_limits_get_uniform_block_range(const struct wined3d_gl_limits *gl_limits, 6481 enum wined3d_shader_type shader_type, unsigned int *base, unsigned int *count) 6482 { 6483 unsigned int i; 6484 6485 *base = 0; 6486 for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) 6487 { 6488 *count = gl_limits->uniform_blocks[i]; 6489 if (i == shader_type) 6490 return; 6491 *base += *count; 6492 } 6493 6494 ERR("Unrecognized shader type %#x.\n", shader_type); 6495 *count = 0; 6496 } 6497 6498 void wined3d_gl_limits_get_texture_unit_range(const struct wined3d_gl_limits *gl_limits, 6499 enum wined3d_shader_type shader_type, unsigned int *base, unsigned int *count) 6500 { 6501 unsigned int i; 6502 6503 if (shader_type == WINED3D_SHADER_TYPE_COMPUTE) 6504 { 6505 if (gl_limits->combined_samplers == gl_limits->graphics_samplers) 6506 *base = 0; 6507 else 6508 *base = gl_limits->graphics_samplers; 6509 *count = gl_limits->samplers[WINED3D_SHADER_TYPE_COMPUTE]; 6510 return; 6511 } 6512 6513 *base = 0; 6514 for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i) 6515 { 6516 *count = gl_limits->samplers[i]; 6517 if (i == shader_type) 6518 return; 6519 *base += *count; 6520 } 6521 6522 ERR("Unrecognized shader type %#x.\n", shader_type); 6523 *count = 0; 6524 } 6525 6526 BOOL wined3d_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size) 6527 { 6528 SIZE_T max_capacity, new_capacity; 6529 void *new_elements; 6530 6531 if (count <= *capacity) 6532 return TRUE; 6533 6534 max_capacity = ~(SIZE_T)0 / size; 6535 if (count > max_capacity) 6536 return FALSE; 6537 6538 new_capacity = max(1, *capacity); 6539 while (new_capacity < count && new_capacity <= max_capacity / 2) 6540 new_capacity *= 2; 6541 if (new_capacity < count) 6542 new_capacity = count; 6543 6544 if (!*elements) 6545 new_elements = heap_alloc_zero(new_capacity * size); 6546 else 6547 new_elements = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *elements, new_capacity * size); 6548 if (!new_elements) 6549 return FALSE; 6550 6551 *elements = new_elements; 6552 *capacity = new_capacity; 6553 return TRUE; 6554 } 6555