diff options
-rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 42 | ||||
-rw-r--r-- | src/video_core/buffer_cache/map_interval.h | 32 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.cpp | 1 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_fence_manager.cpp | 1 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/vk_buffer_cache.cpp | 1 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/vk_fence_manager.h | 1 |
6 files changed, 48 insertions, 30 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index eb03879c4..fb12af9d8 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -14,9 +14,11 @@ #include <boost/icl/interval_map.hpp> #include <boost/icl/interval_set.hpp> +#include <boost/intrusive/set.hpp> #include <boost/range/iterator_range.hpp> #include "common/alignment.h" +#include "common/assert.h" #include "common/common_types.h" #include "common/logging/log.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); if (!map) { return {GetEmptyBuffer(size), 0}; @@ -272,16 +274,16 @@ protected: } const std::size_t size = new_map.end - new_map.start; new_map.is_registered = true; - const IntervalType interval{new_map.start, new_map.end}; rasterizer.UpdatePagesCachedCount(cpu_addr, size, 1); new_map.is_memory_marked = true; if (inherit_written) { MarkRegionAsWritten(new_map.start, new_map.end - 1); new_map.is_written = true; } - mapped_addresses.insert({interval, new_map}); - // Temporary hack until this is replaced with boost::intrusive::rbtree - return const_cast<MapInterval*>(&mapped_addresses.find(interval)->second); + // Temporary hack, leaks memory and it's not cache local + MapInterval* const storage = &mapped_addresses_storage.emplace_back(new_map); + mapped_addresses.insert(*storage); + return storage; } void UnmarkMemory(MapInterval* map) { @@ -304,8 +306,9 @@ protected: if (map->is_written) { UnmarkRegionAsWritten(map->start, map->end - 1); } - const IntervalType delete_interval{map->start, map->end}; - mapped_addresses.erase(delete_interval); + const auto it = mapped_addresses.find(*map); + ASSERT(it != mapped_addresses.end()); + mapped_addresses.erase(it); } private: @@ -389,13 +392,20 @@ private: return {}; } - std::vector<MapInterval*> objects; - const IntervalType interval{addr, addr + size}; - for (auto& pair : boost::make_iterator_range(mapped_addresses.equal_range(interval))) { - objects.push_back(&pair.second); - } + std::vector<MapInterval*> result; + const VAddr addr_end = addr + size; - 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 @@ -565,9 +575,9 @@ private: u64 buffer_offset_base = 0; using IntervalSet = boost::icl::interval_set<VAddr>; - using IntervalCache = boost::icl::interval_map<VAddr, MapInterval>; - using IntervalType = typename IntervalCache::interval_type; - IntervalCache mapped_addresses; + using IntervalType = typename IntervalSet::interval_type; + std::list<MapInterval> mapped_addresses_storage; // Temporary hack + boost::intrusive::set<MapInterval, boost::intrusive::compare<MapIntervalCompare>> mapped_addresses; static constexpr u64 write_page_bit = 11; std::unordered_map<u64, u32> written_pages; diff --git a/src/video_core/buffer_cache/map_interval.h b/src/video_core/buffer_cache/map_interval.h index ad4db0135..45705cccf 100644 --- a/src/video_core/buffer_cache/map_interval.h +++ b/src/video_core/buffer_cache/map_interval.h @@ -4,38 +4,36 @@ #pragma once +#include <boost/intrusive/set_hook.hpp> + #include "common/common_types.h" #include "video_core/gpu.h" namespace VideoCommon { -struct MapInterval { - constexpr explicit MapInterval() noexcept = default; - - constexpr explicit MapInterval(VAddr start, VAddr end, GPUVAddr gpu_addr) noexcept - : start{start}, end{end}, gpu_addr{gpu_addr} {} +struct MapInterval : public boost::intrusive::set_base_hook<boost::intrusive::optimize_size<true>> { + /*implicit*/ MapInterval(VAddr start_) noexcept : start{start_} {} - constexpr bool IsInside(VAddr other_start, VAddr other_end) const noexcept { - return (start <= other_start && other_end <= end); - } + explicit MapInterval(VAddr start_, VAddr end_, GPUVAddr gpu_addr_) noexcept + : start{start_}, end{end_}, gpu_addr{gpu_addr_} {} - constexpr bool operator==(const MapInterval& rhs) const noexcept { - return start == rhs.start && end == rhs.end; + bool IsInside(VAddr other_start, VAddr other_end) const noexcept { + return start <= other_start && other_end <= end; } - constexpr bool operator!=(const MapInterval& rhs) const noexcept { - return !operator==(rhs); + bool Overlaps(VAddr other_start, VAddr other_end) const noexcept { + return start < other_end && other_start < end; } - constexpr void MarkAsModified(bool is_modified_, u64 ticks_) noexcept { + void MarkAsModified(bool is_modified_, u64 ticks_) noexcept { is_modified = is_modified_; ticks = ticks_; } + boost::intrusive::set_member_hook<> member_hook_; VAddr start = 0; VAddr end = 0; GPUVAddr gpu_addr = 0; - VAddr cpu_addr = 0; u64 ticks = 0; bool is_written = false; bool is_modified = false; @@ -44,4 +42,10 @@ struct MapInterval { 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 diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp index d2cab50bd..9964ea894 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp @@ -8,6 +8,7 @@ #include "common/assert.h" #include "common/microprofile.h" +#include "video_core/buffer_cache/buffer_cache.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/rasterizer_interface.h" #include "video_core/renderer_opengl/gl_buffer_cache.h" diff --git a/src/video_core/renderer_opengl/gl_fence_manager.cpp b/src/video_core/renderer_opengl/gl_fence_manager.cpp index 99ddcb3f8..ec5421afa 100644 --- a/src/video_core/renderer_opengl/gl_fence_manager.cpp +++ b/src/video_core/renderer_opengl/gl_fence_manager.cpp @@ -4,6 +4,7 @@ #include "common/assert.h" +#include "video_core/renderer_opengl/gl_buffer_cache.h" #include "video_core/renderer_opengl/gl_fence_manager.h" namespace OpenGL { diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 5b494da8c..5f33d9e40 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp @@ -7,6 +7,7 @@ #include <memory> #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_device.h" #include "video_core/renderer_vulkan/vk_scheduler.h" diff --git a/src/video_core/renderer_vulkan/vk_fence_manager.h b/src/video_core/renderer_vulkan/vk_fence_manager.h index 04d07fe6a..043fe7947 100644 --- a/src/video_core/renderer_vulkan/vk_fence_manager.h +++ b/src/video_core/renderer_vulkan/vk_fence_manager.h @@ -7,6 +7,7 @@ #include <memory> #include "video_core/fence_manager.h" +#include "video_core/renderer_vulkan/vk_buffer_cache.h" #include "video_core/renderer_vulkan/wrapper.h" namespace Core { |