diff options
author | gidoly <66776795+gidoly@users.noreply.github.com> | 2022-12-29 09:39:42 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-29 09:39:42 +0100 |
commit | 10eaf31af373a01c989b4df2d13c2fa770857b3a (patch) | |
tree | e184c5bfa13ee0efa07c8ad1afecb339035bb671 /src/core/hle/kernel/k_page_group.h | |
parent | Merge pull request #9423 from vonchenplus/vulkan_quad_strip (diff) | |
download | yuzu-10eaf31af373a01c989b4df2d13c2fa770857b3a.tar yuzu-10eaf31af373a01c989b4df2d13c2fa770857b3a.tar.gz yuzu-10eaf31af373a01c989b4df2d13c2fa770857b3a.tar.bz2 yuzu-10eaf31af373a01c989b4df2d13c2fa770857b3a.tar.lz yuzu-10eaf31af373a01c989b4df2d13c2fa770857b3a.tar.xz yuzu-10eaf31af373a01c989b4df2d13c2fa770857b3a.tar.zst yuzu-10eaf31af373a01c989b4df2d13c2fa770857b3a.zip |
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/kernel/k_page_group.h | 163 |
1 files changed, 71 insertions, 92 deletions
diff --git a/src/core/hle/kernel/k_page_group.h b/src/core/hle/kernel/k_page_group.h index c07f17663..316f172f2 100644 --- a/src/core/hle/kernel/k_page_group.h +++ b/src/core/hle/kernel/k_page_group.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -13,23 +13,24 @@ namespace Kernel { -class KBlockInfoManager; -class KernelCore; class KPageGroup; class KBlockInfo { +private: + friend class KPageGroup; + public: - constexpr explicit KBlockInfo() : m_next(nullptr) {} + constexpr KBlockInfo() = default; - constexpr void Initialize(KPhysicalAddress addr, size_t np) { + constexpr void Initialize(PAddr addr, size_t np) { ASSERT(Common::IsAligned(addr, PageSize)); ASSERT(static_cast<u32>(np) == np); - m_page_index = static_cast<u32>(addr / PageSize); + m_page_index = static_cast<u32>(addr) / PageSize; m_num_pages = static_cast<u32>(np); } - constexpr KPhysicalAddress GetAddress() const { + constexpr PAddr GetAddress() const { return m_page_index * PageSize; } constexpr size_t GetNumPages() const { @@ -38,10 +39,10 @@ public: constexpr size_t GetSize() const { return this->GetNumPages() * PageSize; } - constexpr KPhysicalAddress GetEndAddress() const { + constexpr PAddr GetEndAddress() const { return (m_page_index + m_num_pages) * PageSize; } - constexpr KPhysicalAddress GetLastAddress() const { + constexpr PAddr GetLastAddress() const { return this->GetEndAddress() - 1; } @@ -61,8 +62,8 @@ public: return !(*this == rhs); } - constexpr bool IsStrictlyBefore(KPhysicalAddress addr) const { - const KPhysicalAddress end = this->GetEndAddress(); + constexpr bool IsStrictlyBefore(PAddr addr) const { + const PAddr end = this->GetEndAddress(); if (m_page_index != 0 && end == 0) { return false; @@ -71,11 +72,11 @@ public: return end < addr; } - constexpr bool operator<(KPhysicalAddress addr) const { + constexpr bool operator<(PAddr addr) const { return this->IsStrictlyBefore(addr); } - constexpr bool TryConcatenate(KPhysicalAddress addr, size_t np) { + constexpr bool TryConcatenate(PAddr addr, size_t np) { if (addr != 0 && addr == this->GetEndAddress()) { m_num_pages += static_cast<u32>(np); return true; @@ -89,118 +90,96 @@ private: } private: - friend class KPageGroup; - KBlockInfo* m_next{}; u32 m_page_index{}; u32 m_num_pages{}; }; static_assert(sizeof(KBlockInfo) <= 0x10); -class KPageGroup { +class KPageGroup final { public: - class Iterator { + class Node final { public: - using iterator_category = std::forward_iterator_tag; - using value_type = const KBlockInfo; - using difference_type = std::ptrdiff_t; - using pointer = value_type*; - using reference = value_type&; - - constexpr explicit Iterator(pointer n) : m_node(n) {} - - constexpr bool operator==(const Iterator& rhs) const { - return m_node == rhs.m_node; - } - constexpr bool operator!=(const Iterator& rhs) const { - return !(*this == rhs); - } + constexpr Node(u64 addr_, std::size_t num_pages_) : addr{addr_}, num_pages{num_pages_} {} - constexpr pointer operator->() const { - return m_node; - } - constexpr reference operator*() const { - return *m_node; + constexpr u64 GetAddress() const { + return addr; } - constexpr Iterator& operator++() { - m_node = m_node->GetNext(); - return *this; + constexpr std::size_t GetNumPages() const { + return num_pages; } - constexpr Iterator operator++(int) { - const Iterator it{*this}; - ++(*this); - return it; + constexpr std::size_t GetSize() const { + return GetNumPages() * PageSize; } private: - pointer m_node{}; + u64 addr{}; + std::size_t num_pages{}; }; - explicit KPageGroup(KernelCore& kernel, KBlockInfoManager* m) - : m_kernel{kernel}, m_manager{m} {} - ~KPageGroup() { - this->Finalize(); +public: + KPageGroup() = default; + KPageGroup(u64 address, u64 num_pages) { + ASSERT(AddBlock(address, num_pages).IsSuccess()); } - void CloseAndReset(); - void Finalize(); - - Iterator begin() const { - return Iterator{m_first_block}; - } - Iterator end() const { - return Iterator{nullptr}; - } - bool empty() const { - return m_first_block == nullptr; + constexpr std::list<Node>& Nodes() { + return nodes; } - Result AddBlock(KPhysicalAddress addr, size_t num_pages); - void Open() const; - void OpenFirst() const; - void Close() const; - - size_t GetNumPages() const; - - bool IsEquivalentTo(const KPageGroup& rhs) const; - - bool operator==(const KPageGroup& rhs) const { - return this->IsEquivalentTo(rhs); + constexpr const std::list<Node>& Nodes() const { + return nodes; } - bool operator!=(const KPageGroup& rhs) const { - return !(*this == rhs); - } + std::size_t GetNumPages() const { + std::size_t num_pages = 0; + for (const Node& node : nodes) { + num_pages += node.GetNumPages(); + } + return num_pages; + } + + bool IsEqual(KPageGroup& other) const { + auto this_node = nodes.begin(); + auto other_node = other.nodes.begin(); + while (this_node != nodes.end() && other_node != other.nodes.end()) { + if (this_node->GetAddress() != other_node->GetAddress() || + this_node->GetNumPages() != other_node->GetNumPages()) { + return false; + } + this_node = std::next(this_node); + other_node = std::next(other_node); + } -private: - KernelCore& m_kernel; - KBlockInfo* m_first_block{}; - KBlockInfo* m_last_block{}; - KBlockInfoManager* m_manager{}; -}; + return this_node == nodes.end() && other_node == other.nodes.end(); + } -class KScopedPageGroup { -public: - explicit KScopedPageGroup(const KPageGroup* gp) : m_pg(gp) { - if (m_pg) { - m_pg->Open(); + Result AddBlock(u64 address, u64 num_pages) { + if (!num_pages) { + return ResultSuccess; } - } - explicit KScopedPageGroup(const KPageGroup& gp) : KScopedPageGroup(std::addressof(gp)) {} - ~KScopedPageGroup() { - if (m_pg) { - m_pg->Close(); + if (!nodes.empty()) { + const auto node = nodes.back(); + if (node.GetAddress() + node.GetNumPages() * PageSize == address) { + address = node.GetAddress(); + num_pages += node.GetNumPages(); + nodes.pop_back(); + } } + nodes.push_back({address, num_pages}); + return ResultSuccess; } - void CancelClose() { - m_pg = nullptr; + bool Empty() const { + return nodes.empty(); } + void Finalize() {} + private: - const KPageGroup* m_pg{}; + std::list<Node> nodes; }; } // namespace Kernel |