diff options
| author | 2021-12-23 01:40:45 +0100 | |
|---|---|---|
| committer | 2022-10-06 21:00:52 +0200 | |
| commit | 9cf4c8831d6a8b0d9c6e2a48e89b667fd73accee (patch) | |
| tree | b213e143366041f07ac9389e91801384f698b0d8 | |
| parent | Refactor VideoCore to use AS sepparate from Channel. (diff) | |
| download | yuzu-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.h | 1 | ||||
| -rw-r--r-- | src/video_core/control/channel_state_cache.inc | 17 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 45 |
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 | ||
| 1704 | template <class P> | 1704 | template <class P> |
| 1705 | void TextureCache<P>::RemoveImageViewReferences(std::span<const ImageViewId> removed_views) { | 1705 | void 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 | } |