summaryrefslogtreecommitdiffstats
path: root/src/common/multi_level_page_table.h
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2021-11-10 17:37:17 +0100
committerFernando Sahmkow <fsahmkow27@gmail.com>2022-10-06 21:00:51 +0200
commitb617874724c461cba270a00c0f8e67fc4a6d553a (patch)
treed340f10064341c938ab952a53fb4ec0b941ee635 /src/common/multi_level_page_table.h
parentVideoCore: Fix channels with disk pipeline/shader cache. (diff)
downloadyuzu-b617874724c461cba270a00c0f8e67fc4a6d553a.tar
yuzu-b617874724c461cba270a00c0f8e67fc4a6d553a.tar.gz
yuzu-b617874724c461cba270a00c0f8e67fc4a6d553a.tar.bz2
yuzu-b617874724c461cba270a00c0f8e67fc4a6d553a.tar.lz
yuzu-b617874724c461cba270a00c0f8e67fc4a6d553a.tar.xz
yuzu-b617874724c461cba270a00c0f8e67fc4a6d553a.tar.zst
yuzu-b617874724c461cba270a00c0f8e67fc4a6d553a.zip
Diffstat (limited to 'src/common/multi_level_page_table.h')
-rw-r--r--src/common/multi_level_page_table.h79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/common/multi_level_page_table.h b/src/common/multi_level_page_table.h
new file mode 100644
index 000000000..dde1cc962
--- /dev/null
+++ b/src/common/multi_level_page_table.h
@@ -0,0 +1,79 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "common/common_types.h"
+
+namespace Common {
+
+template <typename BaseAddr>
+class MultiLevelPageTable final {
+public:
+ constexpr MultiLevelPageTable() = default;
+ explicit MultiLevelPageTable(std::size_t address_space_bits, std::size_t first_level_bits,
+ std::size_t page_bits);
+
+ ~MultiLevelPageTable() noexcept;
+
+ MultiLevelPageTable(const MultiLevelPageTable&) = delete;
+ MultiLevelPageTable& operator=(const MultiLevelPageTable&) = delete;
+
+ MultiLevelPageTable(MultiLevelPageTable&& other) noexcept
+ : address_space_bits{std::exchange(other.address_space_bits, 0)},
+ first_level_bits{std::exchange(other.first_level_bits, 0)}, page_bits{std::exchange(
+ other.page_bits, 0)},
+ first_level_shift{std::exchange(other.first_level_shift, 0)},
+ first_level_chunk_size{std::exchange(other.first_level_chunk_size, 0)},
+ first_level_map{std::move(other.first_level_map)}, base_ptr{std::exchange(other.base_ptr,
+ nullptr)} {}
+
+ MultiLevelPageTable& operator=(MultiLevelPageTable&& other) noexcept {
+ address_space_bits = std::exchange(other.address_space_bits, 0);
+ first_level_bits = std::exchange(other.first_level_bits, 0);
+ page_bits = std::exchange(other.page_bits, 0);
+ first_level_shift = std::exchange(other.first_level_shift, 0);
+ first_level_chunk_size = std::exchange(other.first_level_chunk_size, 0);
+ alloc_size = std::exchange(other.alloc_size, 0);
+ first_level_map = std::move(other.first_level_map);
+ base_ptr = std::exchange(other.base_ptr, nullptr);
+ return *this;
+ }
+
+ void ReserveRange(u64 start, std::size_t size);
+
+ [[nodiscard]] constexpr const BaseAddr& operator[](std::size_t index) const {
+ return base_ptr[index];
+ }
+
+ [[nodiscard]] constexpr BaseAddr& operator[](std::size_t index) {
+ return base_ptr[index];
+ }
+
+ [[nodiscard]] constexpr BaseAddr* data() {
+ return base_ptr;
+ }
+
+ [[nodiscard]] constexpr const BaseAddr* data() const {
+ return base_ptr;
+ }
+
+private:
+ void AllocateLevel(u64 level);
+
+ std::size_t address_space_bits{};
+ std::size_t first_level_bits{};
+ std::size_t page_bits{};
+ std::size_t first_level_shift{};
+ std::size_t first_level_chunk_size{};
+ std::size_t alloc_size{};
+ std::vector<void*> first_level_map{};
+ BaseAddr* base_ptr{};
+};
+
+} // namespace Common