summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2021-12-23 01:40:45 +0100
committerGravatar Fernando Sahmkow2022-10-06 21:00:52 +0200
commit9cf4c8831d6a8b0d9c6e2a48e89b667fd73accee (patch)
treeb213e143366041f07ac9389e91801384f698b0d8
parentRefactor VideoCore to use AS sepparate from Channel. (diff)
downloadyuzu-9cf4c8831d6a8b0d9c6e2a48e89b667fd73accee.tar.gz
yuzu-9cf4c8831d6a8b0d9c6e2a48e89b667fd73accee.tar.xz
yuzu-9cf4c8831d6a8b0d9c6e2a48e89b667fd73accee.zip
Texture cache: Fix dangling references on multichannel.
-rw-r--r--src/video_core/control/channel_state_cache.h1
-rw-r--r--src/video_core/control/channel_state_cache.inc17
-rw-r--r--src/video_core/texture_cache/texture_cache.h45
3 files changed, 36 insertions, 27 deletions
diff --git a/src/video_core/control/channel_state_cache.h b/src/video_core/control/channel_state_cache.h
index c51040c83..9b1d7362b 100644
--- a/src/video_core/control/channel_state_cache.h
+++ b/src/video_core/control/channel_state_cache.h
@@ -72,6 +72,7 @@ protected:
72 std::deque<P> channel_storage; 72 std::deque<P> channel_storage;
73 std::deque<size_t> free_channel_ids; 73 std::deque<size_t> free_channel_ids;
74 std::unordered_map<s32, size_t> channel_map; 74 std::unordered_map<s32, size_t> channel_map;
75 std::vector<size_t> active_channel_ids;
75 struct AddresSpaceRef { 76 struct AddresSpaceRef {
76 size_t ref_count; 77 size_t ref_count;
77 size_t storage_id; 78 size_t storage_id;
diff --git a/src/video_core/control/channel_state_cache.inc b/src/video_core/control/channel_state_cache.inc
index 185eabc35..d3ae758b2 100644
--- a/src/video_core/control/channel_state_cache.inc
+++ b/src/video_core/control/channel_state_cache.inc
@@ -1,3 +1,6 @@
1
2#include <algorithm>
3
1#include "video_core/control/channel_state.h" 4#include "video_core/control/channel_state.h"
2#include "video_core/control/channel_state_cache.h" 5#include "video_core/control/channel_state_cache.h"
3#include "video_core/engines/kepler_compute.h" 6#include "video_core/engines/kepler_compute.h"
@@ -27,15 +30,16 @@ void ChannelSetupCaches<P>::CreateChannel(struct Tegra::Control::ChannelState& c
27 if (current_channel_id != UNSET_CHANNEL) { 30 if (current_channel_id != UNSET_CHANNEL) {
28 channel_state = &channel_storage[current_channel_id]; 31 channel_state = &channel_storage[current_channel_id];
29 } 32 }
33 active_channel_ids.push_back(new_id);
30 auto as_it = address_spaces.find(channel.memory_manager->GetID()); 34 auto as_it = address_spaces.find(channel.memory_manager->GetID());
31 if (as_it != address_spaces.end()) { 35 if (as_it != address_spaces.end()) {
32 as_it->second.ref_count++; 36 as_it->second.ref_count++;
33 return; 37 return;
34 } 38 }
35 AddresSpaceRef new_gpu_mem_ref{ 39 AddresSpaceRef new_gpu_mem_ref{
36 .ref_count = 1, 40 .ref_count = 1,
37 .storage_id = address_spaces.size(), 41 .storage_id = address_spaces.size(),
38 .gpu_memory = channel.memory_manager.get(), 42 .gpu_memory = channel.memory_manager.get(),
39 }; 43 };
40 address_spaces.emplace(channel.memory_manager->GetID(), new_gpu_mem_ref); 44 address_spaces.emplace(channel.memory_manager->GetID(), new_gpu_mem_ref);
41 OnGPUASRegister(channel.memory_manager->GetID()); 45 OnGPUASRegister(channel.memory_manager->GetID());
@@ -73,7 +77,8 @@ void ChannelSetupCaches<P>::EraseChannel(s32 id) {
73 } else if (current_channel_id != UNSET_CHANNEL) { 77 } else if (current_channel_id != UNSET_CHANNEL) {
74 channel_state = &channel_storage[current_channel_id]; 78 channel_state = &channel_storage[current_channel_id];
75 } 79 }
80 active_channel_ids.erase(
81 std::find(active_channel_ids.begin(), active_channel_ids.end(), this_id));
76} 82}
77 83
78
79} // namespace VideoCommon 84} // namespace VideoCommon
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 89c5faf88..5ef07d18f 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -41,9 +41,6 @@ TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&
41 sampler_descriptor.mipmap_filter.Assign(Tegra::Texture::TextureMipmapFilter::Linear); 41 sampler_descriptor.mipmap_filter.Assign(Tegra::Texture::TextureMipmapFilter::Linear);
42 sampler_descriptor.cubemap_anisotropy.Assign(1); 42 sampler_descriptor.cubemap_anisotropy.Assign(1);
43 43
44 // Setup channels
45 current_channel_id = UNSET_CHANNEL;
46
47 // Make sure the first index is reserved for the null resources 44 // Make sure the first index is reserved for the null resources
48 // This way the null resource becomes a compile time constant 45 // This way the null resource becomes a compile time constant
49 void(slot_images.insert(NullImageParams{})); 46 void(slot_images.insert(NullImageParams{}));
@@ -886,13 +883,15 @@ void TextureCache<P>::InvalidateScale(Image& image) {
886 } 883 }
887 image.image_view_ids.clear(); 884 image.image_view_ids.clear();
888 image.image_view_infos.clear(); 885 image.image_view_infos.clear();
889 auto& channel_info = channel_storage[image.channel]; 886 for (size_t c : active_channel_ids) {
890 if constexpr (ENABLE_VALIDATION) { 887 auto& channel_info = channel_storage[c];
891 std::ranges::fill(channel_info.graphics_image_view_ids, CORRUPT_ID); 888 if constexpr (ENABLE_VALIDATION) {
892 std::ranges::fill(channel_info.compute_image_view_ids, CORRUPT_ID); 889 std::ranges::fill(channel_info.graphics_image_view_ids, CORRUPT_ID);
890 std::ranges::fill(channel_info.compute_image_view_ids, CORRUPT_ID);
891 }
892 channel_info.graphics_image_table.Invalidate();
893 channel_info.compute_image_table.Invalidate();
893 } 894 }
894 channel_info.graphics_image_table.Invalidate();
895 channel_info.compute_image_table.Invalidate();
896 has_deleted_images = true; 895 has_deleted_images = true;
897} 896}
898 897
@@ -1690,26 +1689,30 @@ void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) {
1690 if (alloc_images.empty()) { 1689 if (alloc_images.empty()) {
1691 image_allocs_table.erase(alloc_it); 1690 image_allocs_table.erase(alloc_it);
1692 } 1691 }
1693 for (auto& this_state : channel_storage) { 1692 for (size_t c : active_channel_ids) {
1693 auto& channel_info = channel_storage[c];
1694 if constexpr (ENABLE_VALIDATION) { 1694 if constexpr (ENABLE_VALIDATION) {
1695 std::ranges::fill(this_state.graphics_image_view_ids, CORRUPT_ID); 1695 std::ranges::fill(channel_info.graphics_image_view_ids, CORRUPT_ID);
1696 std::ranges::fill(this_state.compute_image_view_ids, CORRUPT_ID); 1696 std::ranges::fill(channel_info.compute_image_view_ids, CORRUPT_ID);
1697 } 1697 }
1698 this_state.graphics_image_table.Invalidate(); 1698 channel_info.graphics_image_table.Invalidate();
1699 this_state.compute_image_table.Invalidate(); 1699 channel_info.compute_image_table.Invalidate();
1700 } 1700 }
1701 has_deleted_images = true; 1701 has_deleted_images = true;
1702} 1702}
1703 1703
1704template <class P> 1704template <class P>
1705void TextureCache<P>::RemoveImageViewReferences(std::span<const ImageViewId> removed_views) { 1705void TextureCache<P>::RemoveImageViewReferences(std::span<const ImageViewId> removed_views) {
1706 auto it = channel_state->image_views.begin(); 1706 for (size_t c : active_channel_ids) {
1707 while (it != channel_state->image_views.end()) { 1707 auto& channel_info = channel_storage[c];
1708 const auto found = std::ranges::find(removed_views, it->second); 1708 auto it = channel_info.image_views.begin();
1709 if (found != removed_views.end()) { 1709 while (it != channel_info.image_views.end()) {
1710 it = channel_state->image_views.erase(it); 1710 const auto found = std::ranges::find(removed_views, it->second);
1711 } else { 1711 if (found != removed_views.end()) {
1712 ++it; 1712 it = channel_info.image_views.erase(it);
1713 } else {
1714 ++it;
1715 }
1713 } 1716 }
1714 } 1717 }
1715} 1718}