diff options
| author | JMC47 <JMC4789@gmail.com> | 2026-01-17 16:03:26 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-17 16:03:26 -0500 |
| commit | 8a606fca88a81b5a24d8cc53e5eaba91f2e38fbd (patch) | |
| tree | 531fa197722dfb7c1684292c4259232d8a5205c8 /Source/Core/VideoCommon/TextureInfo.cpp | |
| parent | 7ec5b06ab9b4464710a807f79f493b6c7ea3356c (diff) | |
| parent | f7b4d2738be26b233510577bd4e972da298dc578 (diff) | |
Merge pull request #14286 from JosJuice/textureinfo-vector
VideoCommon: Don't create mipmap vector in TextureInfo
Diffstat (limited to 'Source/Core/VideoCommon/TextureInfo.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/TextureInfo.cpp | 109 |
1 files changed, 61 insertions, 48 deletions
diff --git a/Source/Core/VideoCommon/TextureInfo.cpp b/Source/Core/VideoCommon/TextureInfo.cpp index 27055f462d..8c73626a35 100644 --- a/Source/Core/VideoCommon/TextureInfo.cpp +++ b/Source/Core/VideoCommon/TextureInfo.cpp @@ -61,9 +61,9 @@ TextureInfo::TextureInfo(u32 stage, std::span<const u8> data, std::span<const u8 u32 address, TextureFormat texture_format, TLUTFormat tlut_format, u32 width, u32 height, bool from_tmem, std::span<const u8> tmem_odd, std::span<const u8> tmem_even, std::optional<u32> mip_count) - : m_ptr(data.data()), m_tlut_ptr(tlut_data.data()), m_address(address), m_from_tmem(from_tmem), - m_tmem_odd(tmem_odd.data()), m_texture_format(texture_format), m_tlut_format(tlut_format), - m_raw_width(width), m_raw_height(height), m_stage(stage) + : m_data(data), m_tlut_data(tlut_data), m_address(address), m_from_tmem(from_tmem), + m_tmem_even(tmem_even), m_tmem_odd(tmem_odd), m_texture_format(texture_format), + m_tlut_format(tlut_format), m_raw_width(width), m_raw_height(height), m_stage(stage) { const bool is_palette_texture = IsColorIndexed(m_texture_format); if (is_palette_texture) @@ -103,23 +103,8 @@ TextureInfo::TextureInfo(u32 stage, std::span<const u8> data, std::span<const u8 // the mipmap chain // e.g. 64x64 with 7 LODs would have the mipmap chain 64x64,32x32,16x16,8x8,4x4,2x2,1x1,0x0, so // we limit the mipmap count to 6 there - const u32 limited_mip_count = + m_limited_mip_count = std::min<u32>(MathUtil::IntLog2(std::max(width, height)) + 1, raw_mip_count + 1) - 1; - - // load mips - std::span<const u8> src_data = Common::SafeSubspan(data, GetTextureSize()); - tmem_even = Common::SafeSubspan(tmem_even, GetTextureSize()); - - for (u32 i = 0; i < limited_mip_count; i++) - { - MipLevel mip_level(i + 1, *this, m_from_tmem, &src_data, &tmem_even, &tmem_odd); - if (!mip_level.IsDataValid()) - { - ERROR_LOG_FMT(VIDEO, "Trying to use an invalid mipmap address {:#010x}", GetRawAddress()); - break; - } - m_mip_levels.push_back(std::move(mip_level)); - } } } @@ -133,7 +118,7 @@ TextureInfo::NameDetails TextureInfo::CalculateTextureName() const if (!IsDataValid()) return NameDetails{}; - const u8* tlut = m_tlut_ptr; + const u8* tlut = m_tlut_data.data(); size_t tlut_size = m_palette_size ? *m_palette_size : 0; // checking for min/max on paletted textures @@ -146,8 +131,8 @@ TextureInfo::NameDetails TextureInfo::CalculateTextureName() const case 16 * 2: for (size_t i = 0; i < m_texture_size; i++) { - const u32 low_nibble = m_ptr[i] & 0xf; - const u32 high_nibble = m_ptr[i] >> 4; + const u32 low_nibble = m_data[i] & 0xf; + const u32 high_nibble = m_data[i] >> 4; min = std::min({min, low_nibble, high_nibble}); max = std::max({max, low_nibble, high_nibble}); @@ -156,7 +141,7 @@ TextureInfo::NameDetails TextureInfo::CalculateTextureName() const case 256 * 2: for (size_t i = 0; i < m_texture_size; i++) { - const u32 texture_byte = m_ptr[i]; + const u32 texture_byte = m_data[i]; min = std::min(min, texture_byte); max = std::max(max, texture_byte); @@ -165,7 +150,7 @@ TextureInfo::NameDetails TextureInfo::CalculateTextureName() const case 16384 * 2: for (size_t i = 0; i < m_texture_size; i += sizeof(u16)) { - const u32 texture_halfword = Common::swap16(m_ptr[i]) & 0x3fff; + const u32 texture_halfword = Common::swap16(m_data[i]) & 0x3fff; min = std::min(min, texture_halfword); max = std::max(max, texture_halfword); @@ -180,7 +165,7 @@ TextureInfo::NameDetails TextureInfo::CalculateTextureName() const DEBUG_ASSERT(tlut_size <= m_palette_size.value_or(0)); - const u64 tex_hash = XXH64(m_ptr, m_texture_size, 0); + const u64 tex_hash = XXH64(m_data.data(), m_texture_size, 0); const u64 tlut_hash = tlut_size ? XXH64(tlut, tlut_size, 0) : 0; return {.base_name = fmt::format("{}{}x{}{}", format_prefix, m_raw_width, m_raw_height, @@ -197,12 +182,12 @@ bool TextureInfo::IsDataValid() const const u8* TextureInfo::GetData() const { - return m_ptr; + return m_data.data(); } const u8* TextureInfo::GetTlutAddress() const { - return m_tlut_ptr; + return m_tlut_data.data(); } u32 TextureInfo::GetRawAddress() const @@ -217,7 +202,7 @@ bool TextureInfo::IsFromTmem() const const u8* TextureInfo::GetTmemOddAddress() const { - return m_tmem_odd; + return m_tmem_odd.data(); } TextureFormat TextureInfo::GetTextureFormat() const @@ -277,25 +262,43 @@ u32 TextureInfo::GetStage() const bool TextureInfo::HasMipMaps() const { - return !m_mip_levels.empty(); + return m_limited_mip_count != 0; } u32 TextureInfo::GetLevelCount() const { - return static_cast<u32>(m_mip_levels.size()) + 1; + return m_limited_mip_count + 1; } -const TextureInfo::MipLevel* TextureInfo::GetMipMapLevel(u32 level) const +TextureInfo::MipLevels TextureInfo::GetMipMapLevels() const { - if (level < m_mip_levels.size()) - return &m_mip_levels[level]; + MipLevelIterator begin; + begin.m_parent = this; + begin.m_from_tmem = m_from_tmem; + begin.m_data = Common::SafeSubspan(m_data, GetTextureSize()); + begin.m_tmem_even = Common::SafeSubspan(m_tmem_even, GetTextureSize()); + begin.m_tmem_odd = m_tmem_odd; + begin.CreateMipLevel(); + + MipLevelIterator end; + end.m_level_index = m_limited_mip_count; + + return MipLevels(begin, end); +} - return nullptr; +u32 TextureInfo::GetFullLevelSize() const +{ + u32 all_mips_size = 0; + for (const auto& mip_map : GetMipMapLevels()) + { + if (mip_map.IsDataValid()) + all_mips_size += mip_map.GetTextureSize(); + } + return m_texture_size + all_mips_size; } -TextureInfo::MipLevel::MipLevel(u32 level, const TextureInfo& parent, bool from_tmem, - std::span<const u8>* src_data, std::span<const u8>* tmem_even, - std::span<const u8>* tmem_odd) +TextureInfo::MipLevel::MipLevel(u32 level, const TextureInfo& parent, std::span<const u8>* data) + : m_level(level) { m_raw_width = std::max(parent.GetRawWidth() >> level, 1u); m_raw_height = std::max(parent.GetRawHeight() >> level, 1u); @@ -305,23 +308,12 @@ TextureInfo::MipLevel::MipLevel(u32 level, const TextureInfo& parent, bool from_ m_texture_size = TexDecoder_GetTextureSizeInBytes(m_expanded_width, m_expanded_height, parent.GetTextureFormat()); - std::span<const u8>* data = from_tmem ? ((level % 2) ? tmem_odd : tmem_even) : src_data; m_ptr = data->data(); m_data_valid = data->size() >= m_texture_size; *data = Common::SafeSubspan(*data, m_texture_size); } -u32 TextureInfo::GetFullLevelSize() const -{ - u32 all_mips_size = 0; - for (const auto& mip_map : m_mip_levels) - { - all_mips_size += mip_map.GetTextureSize(); - } - return m_texture_size + all_mips_size; -} - bool TextureInfo::MipLevel::IsDataValid() const { return m_data_valid; @@ -356,3 +348,24 @@ u32 TextureInfo::MipLevel::GetRawHeight() const { return m_raw_height; } + +u32 TextureInfo::MipLevel::GetLevel() const +{ + return m_level; +} + +TextureInfo::MipLevelIterator& TextureInfo::MipLevelIterator::operator++() +{ + ++m_level_index; + CreateMipLevel(); + return *this; +} + +void TextureInfo::MipLevelIterator::CreateMipLevel() +{ + const u32 level = m_level_index + 1; + std::span<const u8>* data = m_from_tmem ? ((level % 2) ? &m_tmem_odd : &m_tmem_even) : &m_data; + + // The MipLevel constructor mutates the data argument so the next MipLevel gets the right data + m_mip_level = MipLevel(level, *m_parent, data); +} |
