mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	buffer_cache: Use boost::intrusive::set for caching
Instead of using boost::icl::interval_map for caching, use boost::intrusive::set. interval_map is intended as a container where the keys can overlap with one another; we don't need this for caching buffers and a std::set-like data structure that allows us to search with lower_bound is enough.
This commit is contained in:
		
							parent
							
								
									3b0baf746e
								
							
						
					
					
						commit
						891236124c
					
				| @ -14,9 +14,11 @@ | |||||||
| 
 | 
 | ||||||
| #include <boost/icl/interval_map.hpp> | #include <boost/icl/interval_map.hpp> | ||||||
| #include <boost/icl/interval_set.hpp> | #include <boost/icl/interval_set.hpp> | ||||||
|  | #include <boost/intrusive/set.hpp> | ||||||
| #include <boost/range/iterator_range.hpp> | #include <boost/range/iterator_range.hpp> | ||||||
| 
 | 
 | ||||||
| #include "common/alignment.h" | #include "common/alignment.h" | ||||||
|  | #include "common/assert.h" | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| @ -73,7 +75,7 @@ public: | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         auto block = GetBlock(cpu_addr, size); |         OwnerBuffer block = GetBlock(cpu_addr, size); | ||||||
|         MapInterval* const map = MapAddress(block, gpu_addr, cpu_addr, size); |         MapInterval* const map = MapAddress(block, gpu_addr, cpu_addr, size); | ||||||
|         if (!map) { |         if (!map) { | ||||||
|             return {GetEmptyBuffer(size), 0}; |             return {GetEmptyBuffer(size), 0}; | ||||||
| @ -272,16 +274,16 @@ protected: | |||||||
|         } |         } | ||||||
|         const std::size_t size = new_map.end - new_map.start; |         const std::size_t size = new_map.end - new_map.start; | ||||||
|         new_map.is_registered = true; |         new_map.is_registered = true; | ||||||
|         const IntervalType interval{new_map.start, new_map.end}; |  | ||||||
|         rasterizer.UpdatePagesCachedCount(cpu_addr, size, 1); |         rasterizer.UpdatePagesCachedCount(cpu_addr, size, 1); | ||||||
|         new_map.is_memory_marked = true; |         new_map.is_memory_marked = true; | ||||||
|         if (inherit_written) { |         if (inherit_written) { | ||||||
|             MarkRegionAsWritten(new_map.start, new_map.end - 1); |             MarkRegionAsWritten(new_map.start, new_map.end - 1); | ||||||
|             new_map.is_written = true; |             new_map.is_written = true; | ||||||
|         } |         } | ||||||
|         mapped_addresses.insert({interval, new_map}); |         // Temporary hack, leaks memory and it's not cache local
 | ||||||
|         // Temporary hack until this is replaced with boost::intrusive::rbtree
 |         MapInterval* const storage = &mapped_addresses_storage.emplace_back(new_map); | ||||||
|         return const_cast<MapInterval*>(&mapped_addresses.find(interval)->second); |         mapped_addresses.insert(*storage); | ||||||
|  |         return storage; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void UnmarkMemory(MapInterval* map) { |     void UnmarkMemory(MapInterval* map) { | ||||||
| @ -304,8 +306,9 @@ protected: | |||||||
|         if (map->is_written) { |         if (map->is_written) { | ||||||
|             UnmarkRegionAsWritten(map->start, map->end - 1); |             UnmarkRegionAsWritten(map->start, map->end - 1); | ||||||
|         } |         } | ||||||
|         const IntervalType delete_interval{map->start, map->end}; |         const auto it = mapped_addresses.find(*map); | ||||||
|         mapped_addresses.erase(delete_interval); |         ASSERT(it != mapped_addresses.end()); | ||||||
|  |         mapped_addresses.erase(it); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| @ -389,13 +392,20 @@ private: | |||||||
|             return {}; |             return {}; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         std::vector<MapInterval*> objects; |         std::vector<MapInterval*> result; | ||||||
|         const IntervalType interval{addr, addr + size}; |         const VAddr addr_end = addr + size; | ||||||
|         for (auto& pair : boost::make_iterator_range(mapped_addresses.equal_range(interval))) { |  | ||||||
|             objects.push_back(&pair.second); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         return objects; |         auto it = mapped_addresses.lower_bound(addr); | ||||||
|  |         if (it != mapped_addresses.begin()) { | ||||||
|  |             --it; | ||||||
|  |         } | ||||||
|  |         while (it != mapped_addresses.end() && it->start < addr_end) { | ||||||
|  |             if (it->Overlaps(addr, addr_end)) { | ||||||
|  |                 result.push_back(&*it); | ||||||
|  |             } | ||||||
|  |             ++it; | ||||||
|  |         } | ||||||
|  |         return result; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Returns a ticks counter used for tracking when cached objects were last modified
 |     /// Returns a ticks counter used for tracking when cached objects were last modified
 | ||||||
| @ -565,9 +575,9 @@ private: | |||||||
|     u64 buffer_offset_base = 0; |     u64 buffer_offset_base = 0; | ||||||
| 
 | 
 | ||||||
|     using IntervalSet = boost::icl::interval_set<VAddr>; |     using IntervalSet = boost::icl::interval_set<VAddr>; | ||||||
|     using IntervalCache = boost::icl::interval_map<VAddr, MapInterval>; |     using IntervalType = typename IntervalSet::interval_type; | ||||||
|     using IntervalType = typename IntervalCache::interval_type; |     std::list<MapInterval> mapped_addresses_storage; // Temporary hack
 | ||||||
|     IntervalCache mapped_addresses; |     boost::intrusive::set<MapInterval, boost::intrusive::compare<MapIntervalCompare>> mapped_addresses; | ||||||
| 
 | 
 | ||||||
|     static constexpr u64 write_page_bit = 11; |     static constexpr u64 write_page_bit = 11; | ||||||
|     std::unordered_map<u64, u32> written_pages; |     std::unordered_map<u64, u32> written_pages; | ||||||
|  | |||||||
| @ -4,38 +4,36 @@ | |||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include <boost/intrusive/set_hook.hpp> | ||||||
|  | 
 | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "video_core/gpu.h" | #include "video_core/gpu.h" | ||||||
| 
 | 
 | ||||||
| namespace VideoCommon { | namespace VideoCommon { | ||||||
| 
 | 
 | ||||||
| struct MapInterval { | struct MapInterval : public boost::intrusive::set_base_hook<boost::intrusive::optimize_size<true>> { | ||||||
|     constexpr explicit MapInterval() noexcept = default; |     /*implicit*/ MapInterval(VAddr start_) noexcept : start{start_} {} | ||||||
| 
 | 
 | ||||||
|     constexpr explicit MapInterval(VAddr start, VAddr end, GPUVAddr gpu_addr) noexcept |     explicit MapInterval(VAddr start_, VAddr end_, GPUVAddr gpu_addr_) noexcept | ||||||
|         : start{start}, end{end}, gpu_addr{gpu_addr} {} |         : start{start_}, end{end_}, gpu_addr{gpu_addr_} {} | ||||||
| 
 | 
 | ||||||
|     constexpr bool IsInside(VAddr other_start, VAddr other_end) const noexcept { |     bool IsInside(VAddr other_start, VAddr other_end) const noexcept { | ||||||
|         return (start <= other_start && other_end <= end); |         return start <= other_start && other_end <= end; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     constexpr bool operator==(const MapInterval& rhs) const noexcept { |     bool Overlaps(VAddr other_start, VAddr other_end) const noexcept { | ||||||
|         return start == rhs.start && end == rhs.end; |         return start < other_end && other_start < end; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     constexpr bool operator!=(const MapInterval& rhs) const noexcept { |     void MarkAsModified(bool is_modified_, u64 ticks_) noexcept { | ||||||
|         return !operator==(rhs); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     constexpr void MarkAsModified(bool is_modified_, u64 ticks_) noexcept { |  | ||||||
|         is_modified = is_modified_; |         is_modified = is_modified_; | ||||||
|         ticks = ticks_; |         ticks = ticks_; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     boost::intrusive::set_member_hook<> member_hook_; | ||||||
|     VAddr start = 0; |     VAddr start = 0; | ||||||
|     VAddr end = 0; |     VAddr end = 0; | ||||||
|     GPUVAddr gpu_addr = 0; |     GPUVAddr gpu_addr = 0; | ||||||
|     VAddr cpu_addr = 0; |  | ||||||
|     u64 ticks = 0; |     u64 ticks = 0; | ||||||
|     bool is_written = false; |     bool is_written = false; | ||||||
|     bool is_modified = false; |     bool is_modified = false; | ||||||
| @ -44,4 +42,10 @@ struct MapInterval { | |||||||
|     bool is_sync_pending = false; |     bool is_sync_pending = false; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | struct MapIntervalCompare { | ||||||
|  |     constexpr bool operator()(const MapInterval& lhs, const MapInterval& rhs) const noexcept { | ||||||
|  |         return lhs.start < rhs.start; | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| } // namespace VideoCommon
 | } // namespace VideoCommon
 | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ | |||||||
| 
 | 
 | ||||||
| #include "common/assert.h" | #include "common/assert.h" | ||||||
| #include "common/microprofile.h" | #include "common/microprofile.h" | ||||||
|  | #include "video_core/buffer_cache/buffer_cache.h" | ||||||
| #include "video_core/engines/maxwell_3d.h" | #include "video_core/engines/maxwell_3d.h" | ||||||
| #include "video_core/rasterizer_interface.h" | #include "video_core/rasterizer_interface.h" | ||||||
| #include "video_core/renderer_opengl/gl_buffer_cache.h" | #include "video_core/renderer_opengl/gl_buffer_cache.h" | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ | |||||||
| 
 | 
 | ||||||
| #include "common/assert.h" | #include "common/assert.h" | ||||||
| 
 | 
 | ||||||
|  | #include "video_core/renderer_opengl/gl_buffer_cache.h" | ||||||
| #include "video_core/renderer_opengl/gl_fence_manager.h" | #include "video_core/renderer_opengl/gl_fence_manager.h" | ||||||
| 
 | 
 | ||||||
| namespace OpenGL { | namespace OpenGL { | ||||||
|  | |||||||
| @ -7,6 +7,7 @@ | |||||||
| #include <memory> | #include <memory> | ||||||
| 
 | 
 | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
|  | #include "video_core/buffer_cache/buffer_cache.h" | ||||||
| #include "video_core/renderer_vulkan/vk_buffer_cache.h" | #include "video_core/renderer_vulkan/vk_buffer_cache.h" | ||||||
| #include "video_core/renderer_vulkan/vk_device.h" | #include "video_core/renderer_vulkan/vk_device.h" | ||||||
| #include "video_core/renderer_vulkan/vk_scheduler.h" | #include "video_core/renderer_vulkan/vk_scheduler.h" | ||||||
|  | |||||||
| @ -7,6 +7,7 @@ | |||||||
| #include <memory> | #include <memory> | ||||||
| 
 | 
 | ||||||
| #include "video_core/fence_manager.h" | #include "video_core/fence_manager.h" | ||||||
|  | #include "video_core/renderer_vulkan/vk_buffer_cache.h" | ||||||
| #include "video_core/renderer_vulkan/wrapper.h" | #include "video_core/renderer_vulkan/wrapper.h" | ||||||
| 
 | 
 | ||||||
| namespace Core { | namespace Core { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 ReinUsesLisp
						ReinUsesLisp