diff options
| author | Fernando Sahmkow <fsahmkow27@gmail.com> | 2022-03-24 21:30:54 +0100 | 
|---|---|---|
| committer | Fernando Sahmkow <fsahmkow27@gmail.com> | 2022-03-25 04:24:05 +0100 | 
| commit | 7a9d9e575b4d85ca30fc119dfb73c1b22a6dbe63 (patch) | |
| tree | 67e146bd3f41413eb6c875234877cc4f3cf0e161 /src/video_core | |
| parent | ab6a5784fa991016b5d8c097471fbda88853ba5d (diff) | |
Texture Cache: Add Cached CPU system.
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_base.h | 3 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 41 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache_base.h | 11 | 
5 files changed, 64 insertions, 3 deletions
| diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 4d632d211..7e06d0069 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -352,7 +352,7 @@ void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) {      shader_cache.OnCPUWrite(addr, size);      {          std::scoped_lock lock{texture_cache.mutex}; -        texture_cache.WriteMemory(addr, size); +        texture_cache.CachedWriteMemory(addr, size);      }      {          std::scoped_lock lock{buffer_cache.mutex}; @@ -364,6 +364,10 @@ void RasterizerOpenGL::SyncGuestHost() {      MICROPROFILE_SCOPE(OpenGL_CacheManagement);      shader_cache.SyncGuestHost();      { +        std::scoped_lock lock{texture_cache.mutex}; +        texture_cache.FlushCachedWrites(); +    } +    {          std::scoped_lock lock{buffer_cache.mutex};          buffer_cache.FlushCachedWrites();      } diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index fa87d37f8..dd6e0027e 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -408,7 +408,7 @@ void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) {      pipeline_cache.OnCPUWrite(addr, size);      {          std::scoped_lock lock{texture_cache.mutex}; -        texture_cache.WriteMemory(addr, size); +        texture_cache.CachedWriteMemory(addr, size);      }      {          std::scoped_lock lock{buffer_cache.mutex}; @@ -419,6 +419,10 @@ void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) {  void RasterizerVulkan::SyncGuestHost() {      pipeline_cache.SyncGuestHost();      { +        std::scoped_lock lock{texture_cache.mutex}; +        texture_cache.FlushCachedWrites(); +    } +    {          std::scoped_lock lock{buffer_cache.mutex};          buffer_cache.FlushCachedWrites();      } diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h index dd0106432..cc7999027 100644 --- a/src/video_core/texture_cache/image_base.h +++ b/src/video_core/texture_cache/image_base.h @@ -39,6 +39,9 @@ enum class ImageFlagBits : u32 {      Rescaled = 1 << 13,      CheckingRescalable = 1 << 14,      IsRescalable = 1 << 15, + +    // Cached CPU +    CachedCpuModified = 1 << 16, ///< Contents have been modified from the CPU  };  DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits) diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index efc1c4525..099b2ae1b 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -438,6 +438,23 @@ void TextureCache<P>::WriteMemory(VAddr cpu_addr, size_t size) {  }  template <class P> +void TextureCache<P>::CachedWriteMemory(VAddr cpu_addr, size_t size) { +    const VAddr new_cpu_addr = Common::AlignDown(cpu_addr, CPU_PAGE_SIZE); +    const size_t new_size = Common::AlignUp(size + cpu_addr - new_cpu_addr, CPU_PAGE_SIZE); +    ForEachImageInRegion(new_cpu_addr, new_size, [this](ImageId image_id, Image& image) { +        if (True(image.flags & ImageFlagBits::CachedCpuModified)) { +            return; +        } +        image.flags |= ImageFlagBits::CachedCpuModified; +        cached_cpu_invalidate.insert(image_id); + +        if (True(image.flags & ImageFlagBits::Tracked)) { +            UntrackImage(image, image_id); +        } +    }); +} + +template <class P>  void TextureCache<P>::DownloadMemory(VAddr cpu_addr, size_t size) {      std::vector<ImageId> images;      ForEachImageInRegion(cpu_addr, size, [this, &images](ImageId image_id, ImageBase& image) { @@ -495,6 +512,18 @@ void TextureCache<P>::UnmapGPUMemory(GPUVAddr gpu_addr, size_t size) {  }  template <class P> +void TextureCache<P>::FlushCachedWrites() { +    for (ImageId image_id : cached_cpu_invalidate) { +        Image& image = slot_images[image_id]; +        if (True(image.flags & ImageFlagBits::CachedCpuModified)) { +            image.flags &= ~ImageFlagBits::CachedCpuModified; +            image.flags |= ImageFlagBits::CpuModified; +        } +    } +    cached_cpu_invalidate.clear(); +} + +template <class P>  void TextureCache<P>::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,                                  const Tegra::Engines::Fermi2D::Surface& src,                                  const Tegra::Engines::Fermi2D::Config& copy) { @@ -1560,6 +1589,9 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) {  template <class P>  void TextureCache<P>::TrackImage(ImageBase& image, ImageId image_id) {      ASSERT(False(image.flags & ImageFlagBits::Tracked)); +    if (True(image.flags & ImageFlagBits::CachedCpuModified)) { +        return; +    }      image.flags |= ImageFlagBits::Tracked;      if (False(image.flags & ImageFlagBits::Sparse)) {          rasterizer.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, 1); @@ -1616,6 +1648,9 @@ void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) {          tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format);      }      total_used_memory -= Common::AlignUp(tentative_size, 1024); +    if (True(image.flags & ImageFlagBits::CachedCpuModified)) { +        cached_cpu_invalidate.erase(image_id); +    }      const GPUVAddr gpu_addr = image.gpu_addr;      const auto alloc_it = image_allocs_table.find(gpu_addr);      if (alloc_it == image_allocs_table.end()) { @@ -1782,7 +1817,11 @@ template <class P>  void TextureCache<P>::PrepareImage(ImageId image_id, bool is_modification, bool invalidate) {      Image& image = slot_images[image_id];      if (invalidate) { -        image.flags &= ~(ImageFlagBits::CpuModified | ImageFlagBits::GpuModified); +        if (True(image.flags & ImageFlagBits::CachedCpuModified)) { +            cached_cpu_invalidate.erase(image_id); +        } +        image.flags &= ~(ImageFlagBits::CpuModified | ImageFlagBits::GpuModified | +                         ImageFlagBits::CachedCpuModified);          if (False(image.flags & ImageFlagBits::Tracked)) {              TrackImage(image, image_id);          } diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index b1324edf3..ad5978a33 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h @@ -8,6 +8,7 @@  #include <span>  #include <type_traits>  #include <unordered_map> +#include <unordered_set>  #include <vector>  #include <queue> @@ -50,6 +51,9 @@ class TextureCache {      /// Address shift for caching images into a hash table      static constexpr u64 PAGE_BITS = 20; +    static constexpr u64 CPU_PAGE_BITS = 12; +    static constexpr u64 CPU_PAGE_SIZE = 1ULL << CPU_PAGE_BITS; +      /// Enables debugging features to the texture cache      static constexpr bool ENABLE_VALIDATION = P::ENABLE_VALIDATION;      /// Implement blits as copies between framebuffers @@ -136,6 +140,9 @@ public:      /// Mark images in a range as modified from the CPU      void WriteMemory(VAddr cpu_addr, size_t size); +    /// Mark images in a range as modified from the CPU +    void CachedWriteMemory(VAddr cpu_addr, size_t size); +      /// Download contents of host images to guest memory in a region      void DownloadMemory(VAddr cpu_addr, size_t size); @@ -145,6 +152,8 @@ public:      /// Remove images in a region      void UnmapGPUMemory(GPUVAddr gpu_addr, size_t size); +    void FlushCachedWrites(); +      /// Blit an image with the given parameters      void BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,                     const Tegra::Engines::Fermi2D::Surface& src, @@ -366,6 +375,8 @@ private:      std::unordered_map<ImageId, std::vector<ImageViewId>> sparse_views; +    std::unordered_set<ImageId> cached_cpu_invalidate; +      VAddr virtual_invalid_space{};      bool has_deleted_images = false; | 
