summaryrefslogtreecommitdiff
path: root/src/video_core/texture_cache
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2024-01-30 11:52:41 +0100
committerGravatar Fernando Sahmkow2024-01-31 16:38:51 +0100
commita7c1306e2d19f1270f6fa0603ba20043c90e9c05 (patch)
tree5fd17b831cdb9beca5fc8ab2161ebe6c8b026608 /src/video_core/texture_cache
parentMerge pull request #12860 from liamwhite/serialization2 (diff)
downloadyuzu-a7c1306e2d19f1270f6fa0603ba20043c90e9c05.tar.gz
yuzu-a7c1306e2d19f1270f6fa0603ba20043c90e9c05.tar.xz
yuzu-a7c1306e2d19f1270f6fa0603ba20043c90e9c05.zip
Texture Cache: make sparse texture table per channel
Diffstat (limited to 'src/video_core/texture_cache')
-rw-r--r--src/video_core/texture_cache/texture_cache.h87
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h4
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
1883template <class P> 1884template <class P>
1884template <typename Func> 1885template <typename Func>
1885void TextureCache<P>::ForEachSparseImageInRegion(GPUVAddr gpu_addr, size_t size, Func&& func) { 1886void 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
1995template <class P> 2004template <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.
2503template <class P> 2513template <class P>
2504void TextureCache<P>::OnGPUASRegister([[maybe_unused]] size_t map_id) { 2514void 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
91template <class P> 92template <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{};