diff --git a/src/xenia/gpu/d3d12/texture_cache.cc b/src/xenia/gpu/d3d12/texture_cache.cc index 51421226b..4595febcc 100644 --- a/src/xenia/gpu/d3d12/texture_cache.cc +++ b/src/xenia/gpu/d3d12/texture_cache.cc @@ -88,6 +88,8 @@ TextureCache::HostFormat TextureCache::host_formats_[64] = { {DXGI_FORMAT_UNKNOWN}, // k_2_10_10_10_FLOAT }; +const char* TextureCache::dimension_names_[4] = {"1D", "2D", "3D", "cube"}; + TextureCache::TextureCache(D3D12CommandProcessor* command_processor, RegisterFile* register_file, SharedMemory* shared_memory) @@ -375,6 +377,31 @@ void TextureCache::TextureKeyFromFetchConstant( ~((fetch.swizzle & (4 | (4 << 3) | (4 << 6) | (4 << 9))) >> 1); } +void TextureCache::LogTextureKeyAction(TextureKey key, const char* action) { + XELOGGPU( + "%s %s %ux%ux%u %s %s texture with %u %spacked mip level%s, " + "base at 0x%.8X, mips at 0x%.8X", action, key.tiled ? "tiled" : "linear", + key.width, key.height, key.depth, + dimension_names_[uint32_t(key.dimension)], + FormatInfo::Get(key.format)->name, key.mip_max_level + 1, + key.packed_mips ? "" : "un", key.mip_max_level != 0 ? "s" : "", + key.base_page << 12, key.mip_page << 12); +} + +void TextureCache::LogTextureAction(const Texture& texture, + const char* action) { + XELOGGPU( + "%s %s %ux%ux%u %s %s texture with %u %spacked mip level%s, " + "base at 0x%.8X (size %u), mips at 0x%.8X (size %u)", action, + texture.key.tiled ? "tiled" : "linear", texture.key.width, + texture.key.height, texture.key.depth, + dimension_names_[uint32_t(texture.key.dimension)], + FormatInfo::Get(texture.key.format)->name, + texture.key.mip_max_level + 1, texture.key.packed_mips ? "" : "un", + texture.key.mip_max_level != 0 ? "s" : "", texture.key.base_page << 12, + texture.base_size, texture.key.mip_page << 12, texture.mip_size); +} + TextureCache::Texture* TextureCache::FindOrCreateTexture(TextureKey key) { uint64_t map_key = key.GetMapKey(); @@ -421,8 +448,7 @@ TextureCache::Texture* TextureCache::FindOrCreateTexture(TextureKey key) { if (FAILED(device->CreateCommittedResource( &heap_properties, D3D12_HEAP_FLAG_NONE, &desc, state, nullptr, IID_PPV_ARGS(&resource)))) { - XELOGE("Failed to create a %ux%ux%u %s texture with %u mip levels", - key.width, key.height, key.depth); + LogTextureKeyAction(key, "Failed to create"); return nullptr; } @@ -456,16 +482,17 @@ TextureCache::Texture* TextureCache::FindOrCreateTexture(TextureKey key) { texture_util::GetGuestMipBlocks(key.dimension, key.width, key.height, key.depth, key.format, i, width_blocks, height_blocks, depth_blocks); - texture->base_size = texture_util::GetGuestMipStorageSize( + texture->mip_size += texture_util::GetGuestMipStorageSize( width_blocks, height_blocks, depth_blocks, key.tiled, key.format, nullptr); } - texture->base_in_sync = false; + texture->mips_in_sync = false; } else { // Never try to upload the mipmaps if there are none. - texture->base_in_sync = true; + texture->mips_in_sync = true; } textures_.insert(std::make_pair(map_key, texture)); + LogTextureAction(*texture, "Created"); return texture; } diff --git a/src/xenia/gpu/d3d12/texture_cache.h b/src/xenia/gpu/d3d12/texture_cache.h index 15d47240b..b2b822fcb 100644 --- a/src/xenia/gpu/d3d12/texture_cache.h +++ b/src/xenia/gpu/d3d12/texture_cache.h @@ -90,19 +90,19 @@ class TextureCache { // range prefix. uint32_t base_page : 17; // 17 total Dimension dimension : 2; // 19 - uint32_t width : 13; // 32 + uint32_t width : 13; // 32 - uint32_t height : 13; // 45 - uint32_t tiled : 1; // 46 + uint32_t height : 13; // 45 + uint32_t tiled : 1; // 46 uint32_t packed_mips : 1; // 47 // Physical 4 KB page with mip 1 and smaller. uint32_t mip_page : 17; // 64 // Layers for stacked and 3D, 6 for cube, 1 for other dimensions. - uint32_t depth : 10; // 74 + uint32_t depth : 10; // 74 uint32_t mip_max_level : 4; // 78 - TextureFormat format : 6; // 84 - Endian endianness : 2; // 86 + TextureFormat format : 6; // 84 + Endian endianness : 2; // 86 }; struct { // The key used for unordered_multimap lookup. Single uint32_t instead of @@ -172,6 +172,9 @@ class TextureCache { const xenos::xe_gpu_texture_fetch_t& fetch, TextureKey& key_out, uint32_t& swizzle_out); + static void LogTextureKeyAction(TextureKey key, const char* action); + static void LogTextureAction(const Texture& texture, const char* action); + // Returns nullptr if the key is not supported, but also if couldn't create // the texture - if it's nullptr, occasionally a recreation attempt should be // made. @@ -184,7 +187,7 @@ class TextureCache { static HostFormat host_formats_[64]; - static const char* dimension_names_[]; + static const char* dimension_names_[4]; D3D12CommandProcessor* command_processor_; RegisterFile* register_file_; diff --git a/src/xenia/gpu/texture_util.cc b/src/xenia/gpu/texture_util.cc index acb56cd62..6647980bc 100644 --- a/src/xenia/gpu/texture_util.cc +++ b/src/xenia/gpu/texture_util.cc @@ -58,9 +58,9 @@ uint32_t GetGuestMipStorageSize(uint32_t width_blocks, uint32_t height_blocks, uint32_t depth_blocks, bool is_tiled, TextureFormat format, uint32_t* row_pitch_out) { const FormatInfo* format_info = FormatInfo::Get(format); - uint32_t row_pitch = width_blocks * format_info->block_width * - format_info->block_height * 8 / - format_info->bits_per_pixel; + uint32_t row_pitch = + width_blocks * format_info->block_width * format_info->block_height * + format_info->bits_per_pixel / 8; if (!is_tiled) { row_pitch = xe::align(row_pitch, 256u); }