diff options
| author | 2024-01-30 11:52:41 +0100 | |
|---|---|---|
| committer | 2024-01-31 16:38:51 +0100 | |
| commit | a7c1306e2d19f1270f6fa0603ba20043c90e9c05 (patch) | |
| tree | 5fd17b831cdb9beca5fc8ab2161ebe6c8b026608 /src | |
| parent | Merge pull request #12860 from liamwhite/serialization2 (diff) | |
| download | yuzu-a7c1306e2d19f1270f6fa0603ba20043c90e9c05.tar.gz yuzu-a7c1306e2d19f1270f6fa0603ba20043c90e9c05.tar.xz yuzu-a7c1306e2d19f1270f6fa0603ba20043c90e9c05.zip | |
Texture Cache: make sparse texture table per channel
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 87 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache_base.h | 4 |
2 files changed, 51 insertions, 40 deletions
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 7398ed2ec..a7400adfa 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -1431,7 +1431,8 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, DA | |||
| 1431 | } | 1431 | } |
| 1432 | } | 1432 | } |
| 1433 | }; | 1433 | }; |
| 1434 | ForEachSparseImageInRegion(gpu_addr, size_bytes, region_check_gpu); | 1434 | ForEachSparseImageInRegion(channel_state->gpu_memory.GetID(), gpu_addr, size_bytes, |
| 1435 | region_check_gpu); | ||
| 1435 | 1436 | ||
| 1436 | bool can_rescale = info.rescaleable; | 1437 | bool can_rescale = info.rescaleable; |
| 1437 | bool any_rescaled = false; | 1438 | bool any_rescaled = false; |
| @@ -1842,7 +1843,7 @@ void TextureCache<P>::ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, s | |||
| 1842 | if (!storage_id) { | 1843 | if (!storage_id) { |
| 1843 | return; | 1844 | return; |
| 1844 | } | 1845 | } |
| 1845 | auto& gpu_page_table = gpu_page_table_storage[*storage_id]; | 1846 | auto& gpu_page_table = gpu_page_table_storage[*storage_id * 2]; |
| 1846 | ForEachGPUPage(gpu_addr, size, | 1847 | ForEachGPUPage(gpu_addr, size, |
| 1847 | [this, &gpu_page_table, &images, gpu_addr, size, func](u64 page) { | 1848 | [this, &gpu_page_table, &images, gpu_addr, size, func](u64 page) { |
| 1848 | const auto it = gpu_page_table.find(page); | 1849 | const auto it = gpu_page_table.find(page); |
| @@ -1882,41 +1883,48 @@ void TextureCache<P>::ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, s | |||
| 1882 | 1883 | ||
| 1883 | template <class P> | 1884 | template <class P> |
| 1884 | template <typename Func> | 1885 | template <typename Func> |
| 1885 | void TextureCache<P>::ForEachSparseImageInRegion(GPUVAddr gpu_addr, size_t size, Func&& func) { | 1886 | void TextureCache<P>::ForEachSparseImageInRegion(size_t as_id, GPUVAddr gpu_addr, size_t size, |
| 1887 | Func&& func) { | ||
| 1886 | using FuncReturn = typename std::invoke_result<Func, ImageId, Image&>::type; | 1888 | using FuncReturn = typename std::invoke_result<Func, ImageId, Image&>::type; |
| 1887 | static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>; | 1889 | static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>; |
| 1888 | boost::container::small_vector<ImageId, 8> images; | 1890 | boost::container::small_vector<ImageId, 8> images; |
| 1889 | ForEachGPUPage(gpu_addr, size, [this, &images, gpu_addr, size, func](u64 page) { | 1891 | auto storage_id = getStorageID(as_id); |
| 1890 | const auto it = sparse_page_table.find(page); | 1892 | if (!storage_id) { |
| 1891 | if (it == sparse_page_table.end()) { | 1893 | return; |
| 1892 | if constexpr (BOOL_BREAK) { | 1894 | } |
| 1893 | return false; | 1895 | auto& sparse_page_table = gpu_page_table_storage[*storage_id * 2 + 1]; |
| 1894 | } else { | 1896 | ForEachGPUPage(gpu_addr, size, |
| 1895 | return; | 1897 | [this, &sparse_page_table, &images, gpu_addr, size, func](u64 page) { |
| 1896 | } | 1898 | const auto it = sparse_page_table.find(page); |
| 1897 | } | 1899 | if (it == sparse_page_table.end()) { |
| 1898 | for (const ImageId image_id : it->second) { | 1900 | if constexpr (BOOL_BREAK) { |
| 1899 | Image& image = slot_images[image_id]; | 1901 | return false; |
| 1900 | if (True(image.flags & ImageFlagBits::Picked)) { | 1902 | } else { |
| 1901 | continue; | 1903 | return; |
| 1902 | } | 1904 | } |
| 1903 | if (!image.OverlapsGPU(gpu_addr, size)) { | 1905 | } |
| 1904 | continue; | 1906 | for (const ImageId image_id : it->second) { |
| 1905 | } | 1907 | Image& image = slot_images[image_id]; |
| 1906 | image.flags |= ImageFlagBits::Picked; | 1908 | if (True(image.flags & ImageFlagBits::Picked)) { |
| 1907 | images.push_back(image_id); | 1909 | continue; |
| 1908 | if constexpr (BOOL_BREAK) { | 1910 | } |
| 1909 | if (func(image_id, image)) { | 1911 | if (!image.OverlapsGPU(gpu_addr, size)) { |
| 1910 | return true; | 1912 | continue; |
| 1911 | } | 1913 | } |
| 1912 | } else { | 1914 | image.flags |= ImageFlagBits::Picked; |
| 1913 | func(image_id, image); | 1915 | images.push_back(image_id); |
| 1914 | } | 1916 | if constexpr (BOOL_BREAK) { |
| 1915 | } | 1917 | if (func(image_id, image)) { |
| 1916 | if constexpr (BOOL_BREAK) { | 1918 | return true; |
| 1917 | return false; | 1919 | } |
| 1918 | } | 1920 | } else { |
| 1919 | }); | 1921 | func(image_id, image); |
| 1922 | } | ||
| 1923 | } | ||
| 1924 | if constexpr (BOOL_BREAK) { | ||
| 1925 | return false; | ||
| 1926 | } | ||
| 1927 | }); | ||
| 1920 | for (const ImageId image_id : images) { | 1928 | for (const ImageId image_id : images) { |
| 1921 | slot_images[image_id].flags &= ~ImageFlagBits::Picked; | 1929 | slot_images[image_id].flags &= ~ImageFlagBits::Picked; |
| 1922 | } | 1930 | } |
| @@ -1988,8 +1996,9 @@ void TextureCache<P>::RegisterImage(ImageId image_id) { | |||
| 1988 | sparse_maps.push_back(map_id); | 1996 | sparse_maps.push_back(map_id); |
| 1989 | }); | 1997 | }); |
| 1990 | sparse_views.emplace(image_id, std::move(sparse_maps)); | 1998 | sparse_views.emplace(image_id, std::move(sparse_maps)); |
| 1991 | ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, | 1999 | ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, image_id](u64 page) { |
| 1992 | [this, image_id](u64 page) { sparse_page_table[page].push_back(image_id); }); | 2000 | (*channel_state->sparse_page_table)[page].push_back(image_id); |
| 2001 | }); | ||
| 1993 | } | 2002 | } |
| 1994 | 2003 | ||
| 1995 | template <class P> | 2004 | template <class P> |
| @@ -2042,7 +2051,7 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) { | |||
| 2042 | return; | 2051 | return; |
| 2043 | } | 2052 | } |
| 2044 | ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, &clear_page_table](u64 page) { | 2053 | ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, &clear_page_table](u64 page) { |
| 2045 | clear_page_table(page, sparse_page_table); | 2054 | clear_page_table(page, (*channel_state->sparse_page_table)); |
| 2046 | }); | 2055 | }); |
| 2047 | auto it = sparse_views.find(image_id); | 2056 | auto it = sparse_views.find(image_id); |
| 2048 | ASSERT(it != sparse_views.end()); | 2057 | ASSERT(it != sparse_views.end()); |
| @@ -2496,13 +2505,15 @@ void TextureCache<P>::CreateChannel(struct Tegra::Control::ChannelState& channel | |||
| 2496 | const auto it = channel_map.find(channel.bind_id); | 2505 | const auto it = channel_map.find(channel.bind_id); |
| 2497 | auto* this_state = &channel_storage[it->second]; | 2506 | auto* this_state = &channel_storage[it->second]; |
| 2498 | const auto& this_as_ref = address_spaces[channel.memory_manager->GetID()]; | 2507 | const auto& this_as_ref = address_spaces[channel.memory_manager->GetID()]; |
| 2499 | this_state->gpu_page_table = &gpu_page_table_storage[this_as_ref.storage_id]; | 2508 | this_state->gpu_page_table = &gpu_page_table_storage[this_as_ref.storage_id * 2]; |
| 2509 | this_state->sparse_page_table = &gpu_page_table_storage[this_as_ref.storage_id * 2 + 1]; | ||
| 2500 | } | 2510 | } |
| 2501 | 2511 | ||
| 2502 | /// Bind a channel for execution. | 2512 | /// Bind a channel for execution. |
| 2503 | template <class P> | 2513 | template <class P> |
| 2504 | void TextureCache<P>::OnGPUASRegister([[maybe_unused]] size_t map_id) { | 2514 | void TextureCache<P>::OnGPUASRegister([[maybe_unused]] size_t map_id) { |
| 2505 | gpu_page_table_storage.emplace_back(); | 2515 | gpu_page_table_storage.emplace_back(); |
| 2516 | gpu_page_table_storage.emplace_back(); | ||
| 2506 | } | 2517 | } |
| 2507 | 2518 | ||
| 2508 | } // namespace VideoCommon | 2519 | } // namespace VideoCommon |
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index 8699d40d4..f9aebb293 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h | |||
| @@ -86,6 +86,7 @@ public: | |||
| 86 | std::unordered_map<TSCEntry, SamplerId> samplers; | 86 | std::unordered_map<TSCEntry, SamplerId> samplers; |
| 87 | 87 | ||
| 88 | TextureCacheGPUMap* gpu_page_table; | 88 | TextureCacheGPUMap* gpu_page_table; |
| 89 | TextureCacheGPUMap* sparse_page_table; | ||
| 89 | }; | 90 | }; |
| 90 | 91 | ||
| 91 | template <class P> | 92 | template <class P> |
| @@ -357,7 +358,7 @@ private: | |||
| 357 | void ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, size_t size, Func&& func); | 358 | void ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, size_t size, Func&& func); |
| 358 | 359 | ||
| 359 | template <typename Func> | 360 | template <typename Func> |
| 360 | void ForEachSparseImageInRegion(GPUVAddr gpu_addr, size_t size, Func&& func); | 361 | void ForEachSparseImageInRegion(size_t as_id, GPUVAddr gpu_addr, size_t size, Func&& func); |
| 361 | 362 | ||
| 362 | /// Iterates over all the images in a region calling func | 363 | /// Iterates over all the images in a region calling func |
| 363 | template <typename Func> | 364 | template <typename Func> |
| @@ -431,7 +432,6 @@ private: | |||
| 431 | std::unordered_map<RenderTargets, FramebufferId> framebuffers; | 432 | std::unordered_map<RenderTargets, FramebufferId> framebuffers; |
| 432 | 433 | ||
| 433 | std::unordered_map<u64, std::vector<ImageMapId>, Common::IdentityHash<u64>> page_table; | 434 | std::unordered_map<u64, std::vector<ImageMapId>, Common::IdentityHash<u64>> page_table; |
| 434 | std::unordered_map<u64, std::vector<ImageId>, Common::IdentityHash<u64>> sparse_page_table; | ||
| 435 | std::unordered_map<ImageId, boost::container::small_vector<ImageViewId, 16>> sparse_views; | 435 | std::unordered_map<ImageId, boost::container::small_vector<ImageViewId, 16>> sparse_views; |
| 436 | 436 | ||
| 437 | DAddr virtual_invalid_space{}; | 437 | DAddr virtual_invalid_space{}; |