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