From 599274e3f0d97c36b31016ba63dcc300d0cf8f6a Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 16 May 2020 17:08:33 -0300 Subject: buffer_cache: Minor style changes Minor style changes. Mostly done so I avoid editing it while doing other changes. --- src/video_core/buffer_cache/map_interval.h | 94 +++++------------------------- 1 file changed, 16 insertions(+), 78 deletions(-) (limited to 'src/video_core/buffer_cache/map_interval.h') diff --git a/src/video_core/buffer_cache/map_interval.h b/src/video_core/buffer_cache/map_interval.h index 29d8b26f3..1e77012d9 100644 --- a/src/video_core/buffer_cache/map_interval.h +++ b/src/video_core/buffer_cache/map_interval.h @@ -9,99 +9,37 @@ namespace VideoCommon { -class MapIntervalBase { -public: - MapIntervalBase(const VAddr start, const VAddr end, const GPUVAddr gpu_addr) +struct MapIntervalBase { + constexpr explicit MapIntervalBase(VAddr start, VAddr end, GPUVAddr gpu_addr) noexcept : start{start}, end{end}, gpu_addr{gpu_addr} {} - void SetCpuAddress(VAddr new_cpu_addr) { - cpu_addr = new_cpu_addr; - } - - VAddr GetCpuAddress() const { - return cpu_addr; - } - - GPUVAddr GetGpuAddress() const { - return gpu_addr; - } - - bool IsInside(const VAddr other_start, const VAddr other_end) const { + constexpr bool IsInside(const VAddr other_start, const VAddr other_end) const noexcept { return (start <= other_start && other_end <= end); } - bool operator==(const MapIntervalBase& rhs) const { - return std::tie(start, end) == std::tie(rhs.start, rhs.end); - } - - bool operator!=(const MapIntervalBase& rhs) const { - return !operator==(rhs); - } - - void MarkAsRegistered(const bool registered) { - is_registered = registered; - } - - bool IsRegistered() const { - return is_registered; - } - - void SetMemoryMarked(bool is_memory_marked_) { - is_memory_marked = is_memory_marked_; - } - - bool IsMemoryMarked() const { - return is_memory_marked; - } - - void SetSyncPending(bool is_sync_pending_) { - is_sync_pending = is_sync_pending_; - } - - bool IsSyncPending() const { - return is_sync_pending; - } - - VAddr GetStart() const { - return start; - } - - VAddr GetEnd() const { - return end; - } - - void MarkAsModified(const bool is_modified_, const u64 tick) { + constexpr void MarkAsModified(bool is_modified_, u64 ticks_) noexcept { is_modified = is_modified_; - ticks = tick; - } - - bool IsModified() const { - return is_modified; - } - - u64 GetModificationTick() const { - return ticks; + ticks = ticks_; } - void MarkAsWritten(const bool is_written_) { - is_written = is_written_; + constexpr bool operator==(const MapIntervalBase& rhs) const noexcept { + return start == rhs.start && end == rhs.end; } - bool IsWritten() const { - return is_written; + constexpr bool operator!=(const MapIntervalBase& rhs) const noexcept { + return !operator==(rhs); } -private: VAddr start; VAddr end; GPUVAddr gpu_addr; - VAddr cpu_addr{}; - bool is_written{}; - bool is_modified{}; - bool is_registered{}; - bool is_memory_marked{}; - bool is_sync_pending{}; - u64 ticks{}; + VAddr cpu_addr = 0; + u64 ticks = 0; + bool is_written = false; + bool is_modified = false; + bool is_registered = false; + bool is_memory_marked = false; + bool is_sync_pending = false; }; } // namespace VideoCommon -- cgit v1.2.3 From 3b0baf746ea6863d38d90521abba95303f321bf3 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 16 May 2020 18:07:03 -0300 Subject: buffer_cache: Remove shared pointers Removing shared pointers is a first step to be able to use intrusive objects and keep allocations close to one another in memory. --- src/video_core/buffer_cache/map_interval.h | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'src/video_core/buffer_cache/map_interval.h') diff --git a/src/video_core/buffer_cache/map_interval.h b/src/video_core/buffer_cache/map_interval.h index 1e77012d9..ad4db0135 100644 --- a/src/video_core/buffer_cache/map_interval.h +++ b/src/video_core/buffer_cache/map_interval.h @@ -9,30 +9,32 @@ namespace VideoCommon { -struct MapIntervalBase { - constexpr explicit MapIntervalBase(VAddr start, VAddr end, GPUVAddr gpu_addr) noexcept +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} {} - constexpr bool IsInside(const VAddr other_start, const VAddr other_end) const noexcept { + constexpr bool IsInside(VAddr other_start, VAddr other_end) const noexcept { return (start <= other_start && other_end <= end); } - constexpr void MarkAsModified(bool is_modified_, u64 ticks_) noexcept { - is_modified = is_modified_; - ticks = ticks_; - } - - constexpr bool operator==(const MapIntervalBase& rhs) const noexcept { + constexpr bool operator==(const MapInterval& rhs) const noexcept { return start == rhs.start && end == rhs.end; } - constexpr bool operator!=(const MapIntervalBase& rhs) const noexcept { + constexpr bool operator!=(const MapInterval& rhs) const noexcept { return !operator==(rhs); } - VAddr start; - VAddr end; - GPUVAddr gpu_addr; + constexpr void MarkAsModified(bool is_modified_, u64 ticks_) noexcept { + is_modified = is_modified_; + ticks = ticks_; + } + + VAddr start = 0; + VAddr end = 0; + GPUVAddr gpu_addr = 0; VAddr cpu_addr = 0; u64 ticks = 0; bool is_written = false; -- cgit v1.2.3 From 891236124caaed34cdefac61cf90896a5b66b267 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 17 May 2020 16:56:08 -0300 Subject: 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. --- src/video_core/buffer_cache/map_interval.h | 32 +++++++++++++++++------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'src/video_core/buffer_cache/map_interval.h') 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 + #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> { + /*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 -- cgit v1.2.3 From a2dcc642c1737721bafe54605c7826fa08d18f47 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 21 May 2020 01:06:40 -0300 Subject: map_interval: Add interval allocator and drop hack Drop the std::list hack to allocate memory indefinitely. Instead use a custom allocator that keeps references valid until destruction. This allocates fixed chunks of memory and puts pointers in a free list. When an allocation is no longer used put it back to the free list, this doesn't heap allocate because std::vector doesn't change the capacity. If the free list is empty, allocate a new chunk. --- src/video_core/buffer_cache/map_interval.h | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'src/video_core/buffer_cache/map_interval.h') diff --git a/src/video_core/buffer_cache/map_interval.h b/src/video_core/buffer_cache/map_interval.h index 45705cccf..fe0bcd1d8 100644 --- a/src/video_core/buffer_cache/map_interval.h +++ b/src/video_core/buffer_cache/map_interval.h @@ -4,6 +4,11 @@ #pragma once +#include +#include +#include +#include + #include #include "common/common_types.h" @@ -12,6 +17,8 @@ namespace VideoCommon { struct MapInterval : public boost::intrusive::set_base_hook> { + MapInterval() = default; + /*implicit*/ MapInterval(VAddr start_) noexcept : start{start_} {} explicit MapInterval(VAddr start_, VAddr end_, GPUVAddr gpu_addr_) noexcept @@ -48,4 +55,38 @@ struct MapIntervalCompare { } }; +class MapIntervalAllocator { +public: + MapIntervalAllocator(); + ~MapIntervalAllocator(); + + MapInterval* Allocate() { + if (free_list.empty()) { + AllocateNewChunk(); + } + MapInterval* const interval = free_list.back(); + free_list.pop_back(); + return interval; + } + + void Release(MapInterval* interval) { + free_list.push_back(interval); + } + +private: + struct Chunk { + std::unique_ptr next; + std::array data; + }; + + void AllocateNewChunk(); + + void FillFreeList(Chunk& chunk); + + std::vector free_list; + std::unique_ptr* new_chunk = &first_chunk.next; + + Chunk first_chunk; +}; + } // namespace VideoCommon -- cgit v1.2.3