diff options
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 35 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache_base.h | 6 | ||||
| -rw-r--r-- | src/video_core/texture_cache/util.cpp | 20 | ||||
| -rw-r--r-- | src/video_core/texture_cache/util.h | 5 | 
4 files changed, 44 insertions, 22 deletions
| diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 8e68a2e53..27c82cd20 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -39,6 +39,12 @@ TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&      sampler_descriptor.mipmap_filter.Assign(Tegra::Texture::TextureMipmapFilter::Linear);      sampler_descriptor.cubemap_anisotropy.Assign(1); +    // These values were chosen based on typical peak swizzle data sizes seen in some titles +    static constexpr size_t SWIZZLE_DATA_BUFFER_INITIAL_CAPACITY = 8_MiB; +    static constexpr size_t UNSWIZZLE_DATA_BUFFER_INITIAL_CAPACITY = 1_MiB; +    swizzle_data_buffer.resize_destructive(SWIZZLE_DATA_BUFFER_INITIAL_CAPACITY); +    unswizzle_data_buffer.resize_destructive(UNSWIZZLE_DATA_BUFFER_INITIAL_CAPACITY); +      // Make sure the first index is reserved for the null resources      // This way the null resource becomes a compile time constant      void(slot_images.insert(NullImageParams{})); @@ -90,7 +96,8 @@ void TextureCache<P>::RunGarbageCollector() {              const auto copies = FullDownloadCopies(image.info);              image.DownloadMemory(map, copies);              runtime.Finish(); -            SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span); +            SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span, +                         swizzle_data_buffer);          }          if (True(image.flags & ImageFlagBits::Tracked)) {              UntrackImage(image, image_id); @@ -461,7 +468,8 @@ void TextureCache<P>::DownloadMemory(VAddr cpu_addr, size_t size) {          const auto copies = FullDownloadCopies(image.info);          image.DownloadMemory(map, copies);          runtime.Finish(); -        SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span); +        SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span, +                     swizzle_data_buffer);      }  } @@ -672,7 +680,8 @@ void TextureCache<P>::PopAsyncFlushes() {      for (const ImageId image_id : download_ids) {          const ImageBase& image = slot_images[image_id];          const auto copies = FullDownloadCopies(image.info); -        SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, download_span); +        SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, download_span, +                     swizzle_data_buffer);          download_map.offset += image.unswizzled_size_bytes;          download_span = download_span.subspan(image.unswizzled_size_bytes);      } @@ -734,13 +743,21 @@ void TextureCache<P>::UploadImageContents(Image& image, StagingBuffer& staging)          gpu_memory->ReadBlockUnsafe(gpu_addr, mapped_span.data(), mapped_span.size_bytes());          const auto uploads = FullUploadSwizzles(image.info);          runtime.AccelerateImageUpload(image, staging, uploads); -    } else if (True(image.flags & ImageFlagBits::Converted)) { -        std::vector<u8> unswizzled_data(image.unswizzled_size_bytes); -        auto copies = UnswizzleImage(*gpu_memory, gpu_addr, image.info, unswizzled_data); -        ConvertImage(unswizzled_data, image.info, mapped_span, copies); +        return; +    } +    const size_t guest_size_bytes = image.guest_size_bytes; +    swizzle_data_buffer.resize_destructive(guest_size_bytes); +    gpu_memory->ReadBlockUnsafe(gpu_addr, swizzle_data_buffer.data(), guest_size_bytes); + +    if (True(image.flags & ImageFlagBits::Converted)) { +        unswizzle_data_buffer.resize_destructive(image.unswizzled_size_bytes); +        auto copies = UnswizzleImage(*gpu_memory, gpu_addr, image.info, swizzle_data_buffer, +                                     unswizzle_data_buffer); +        ConvertImage(unswizzle_data_buffer, image.info, mapped_span, copies);          image.UploadMemory(staging, copies);      } else { -        const auto copies = UnswizzleImage(*gpu_memory, gpu_addr, image.info, mapped_span); +        const auto copies = +            UnswizzleImage(*gpu_memory, gpu_addr, image.info, swizzle_data_buffer, mapped_span);          image.UploadMemory(staging, copies);      }  } @@ -910,7 +927,7 @@ void TextureCache<P>::InvalidateScale(Image& image) {  }  template <class P> -u64 TextureCache<P>::GetScaledImageSizeBytes(ImageBase& image) { +u64 TextureCache<P>::GetScaledImageSizeBytes(const ImageBase& image) {      const u64 scale_up = static_cast<u64>(Settings::values.resolution_info.up_scale *                                            Settings::values.resolution_info.up_scale);      const u64 down_shift = static_cast<u64>(Settings::values.resolution_info.down_shift + diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index 587339a31..4fd677a80 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h @@ -17,6 +17,7 @@  #include "common/literals.h"  #include "common/lru_cache.h"  #include "common/polyfill_ranges.h" +#include "common/scratch_buffer.h"  #include "video_core/compatible_formats.h"  #include "video_core/control/channel_state_cache.h"  #include "video_core/delayed_destruction_ring.h" @@ -368,7 +369,7 @@ private:      void InvalidateScale(Image& image);      bool ScaleUp(Image& image);      bool ScaleDown(Image& image); -    u64 GetScaledImageSizeBytes(ImageBase& image); +    u64 GetScaledImageSizeBytes(const ImageBase& image);      Runtime& runtime; @@ -417,6 +418,9 @@ private:      std::unordered_map<GPUVAddr, ImageAllocId> image_allocs_table; +    Common::ScratchBuffer<u8> swizzle_data_buffer; +    Common::ScratchBuffer<u8> unswizzle_data_buffer; +      u64 modification_tick = 0;      u64 frame_tick = 0;  }; diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp index e8c908b42..03acc68d9 100644 --- a/src/video_core/texture_cache/util.cpp +++ b/src/video_core/texture_cache/util.cpp @@ -505,7 +505,7 @@ void SwizzlePitchLinearImage(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr  void SwizzleBlockLinearImage(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr,                               const ImageInfo& info, const BufferImageCopy& copy, -                             std::span<const u8> input) { +                             std::span<const u8> input, Common::ScratchBuffer<u8>& tmp_buffer) {      const Extent3D size = info.size;      const LevelInfo level_info = MakeLevelInfo(info);      const Extent2D tile_size = DefaultBlockSize(info.format); @@ -534,8 +534,8 @@ void SwizzleBlockLinearImage(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr                         tile_size.height, info.tile_width_spacing);      const size_t subresource_size = sizes[level]; -    const auto dst_data = std::make_unique<u8[]>(subresource_size); -    const std::span<u8> dst(dst_data.get(), subresource_size); +    tmp_buffer.resize_destructive(subresource_size); +    const std::span<u8> dst(tmp_buffer);      for (s32 layer = 0; layer < info.resources.layers; ++layer) {          const std::span<const u8> src = input.subspan(host_offset); @@ -765,8 +765,9 @@ bool IsValidEntry(const Tegra::MemoryManager& gpu_memory, const TICEntry& config  }  std::vector<BufferImageCopy> UnswizzleImage(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr, -                                            const ImageInfo& info, std::span<u8> output) { -    const size_t guest_size_bytes = CalculateGuestSizeInBytes(info); +                                            const ImageInfo& info, std::span<const u8> input, +                                            std::span<u8> output) { +    const size_t guest_size_bytes = input.size_bytes();      const u32 bpp_log2 = BytesPerBlockLog2(info.format);      const Extent3D size = info.size; @@ -789,10 +790,6 @@ std::vector<BufferImageCopy> UnswizzleImage(Tegra::MemoryManager& gpu_memory, GP              .image_extent = size,          }};      } -    const auto input_data = std::make_unique<u8[]>(guest_size_bytes); -    gpu_memory.ReadBlockUnsafe(gpu_addr, input_data.get(), guest_size_bytes); -    const std::span<const u8> input(input_data.get(), guest_size_bytes); -      const LevelInfo level_info = MakeLevelInfo(info);      const s32 num_layers = info.resources.layers;      const s32 num_levels = info.resources.levels; @@ -980,13 +977,14 @@ std::vector<SwizzleParameters> FullUploadSwizzles(const ImageInfo& info) {  }  void SwizzleImage(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr, const ImageInfo& info, -                  std::span<const BufferImageCopy> copies, std::span<const u8> memory) { +                  std::span<const BufferImageCopy> copies, std::span<const u8> memory, +                  Common::ScratchBuffer<u8>& tmp_buffer) {      const bool is_pitch_linear = info.type == ImageType::Linear;      for (const BufferImageCopy& copy : copies) {          if (is_pitch_linear) {              SwizzlePitchLinearImage(gpu_memory, gpu_addr, info, copy, memory);          } else { -            SwizzleBlockLinearImage(gpu_memory, gpu_addr, info, copy, memory); +            SwizzleBlockLinearImage(gpu_memory, gpu_addr, info, copy, memory, tmp_buffer);          }      }  } diff --git a/src/video_core/texture_cache/util.h b/src/video_core/texture_cache/util.h index 5e28f4ab3..d103db8ae 100644 --- a/src/video_core/texture_cache/util.h +++ b/src/video_core/texture_cache/util.h @@ -7,6 +7,7 @@  #include <span>  #include "common/common_types.h" +#include "common/scratch_buffer.h"  #include "video_core/surface.h"  #include "video_core/texture_cache/image_base.h" @@ -59,6 +60,7 @@ struct OverlapResult {  [[nodiscard]] std::vector<BufferImageCopy> UnswizzleImage(Tegra::MemoryManager& gpu_memory,                                                            GPUVAddr gpu_addr, const ImageInfo& info, +                                                          std::span<const u8> input,                                                            std::span<u8> output);  [[nodiscard]] BufferCopy UploadBufferCopy(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr, @@ -76,7 +78,8 @@ void ConvertImage(std::span<const u8> input, const ImageInfo& info, std::span<u8  [[nodiscard]] std::vector<SwizzleParameters> FullUploadSwizzles(const ImageInfo& info);  void SwizzleImage(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr, const ImageInfo& info, -                  std::span<const BufferImageCopy> copies, std::span<const u8> memory); +                  std::span<const BufferImageCopy> copies, std::span<const u8> memory, +                  Common::ScratchBuffer<u8>& tmp_buffer);  [[nodiscard]] bool IsBlockLinearSizeCompatible(const ImageInfo& new_info,                                                 const ImageInfo& overlap_info, u32 new_level, | 
