Browse Source
[page_table/common] fix rasterizer cache and page traversal + misc fixes
pull/4219/head
Exverge
2 weeks ago
No known key found for this signature in database
GPG Key ID: DAD399BCC5FB77E4
6 changed files with
16 additions and
25 deletions
-
src/common/host_memory.cpp
-
src/common/host_memory.h
-
src/common/page_table.cpp
-
src/common/page_table.h
-
src/common/sparse_large_vector.h
-
src/core/memory.cpp
|
|
|
@ -184,7 +184,7 @@ public: |
|
|
|
if (ptr == nullptr) { |
|
|
|
LOG_CRITICAL(HW_Memory, "Failed to allocate fallback buffer with size {:#x}, error {}", size, GetLastError()); |
|
|
|
} |
|
|
|
return VirtualAlloc(nullptr, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); |
|
|
|
return ptr; |
|
|
|
} |
|
|
|
|
|
|
|
void Map(size_t virtual_offset, size_t host_offset, size_t length, MemoryPermission perms) { |
|
|
|
@ -707,7 +707,7 @@ HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_) |
|
|
|
{ |
|
|
|
#if defined(__OPENORBIS__) || defined(__managarm__)
|
|
|
|
LOG_WARNING(HW_Memory, "Platform doesn't support fastmem"); |
|
|
|
backing_base = malloc(backing_size); |
|
|
|
backing_base = static_cast<u8*>(malloc(backing_size)); |
|
|
|
virtual_base = nullptr; |
|
|
|
#else
|
|
|
|
// Try to allocate a fastmem arena.
|
|
|
|
|
|
|
|
@ -85,7 +85,7 @@ private: |
|
|
|
u8* virtual_base{}; |
|
|
|
size_t virtual_base_offset{}; |
|
|
|
// Windows requires it for kernels whom lack proper support for some functions! |
|
|
|
bool fallback_buffer; |
|
|
|
bool fallback_buffer{false}; |
|
|
|
}; |
|
|
|
|
|
|
|
} // namespace Common |
|
|
|
@ -26,18 +26,19 @@ bool PageTable::ContinueTraversal(TraversalEntry* out_entry, TraversalContext* c |
|
|
|
// Setup invalid defaults.
|
|
|
|
out_entry->phys_addr = 0; |
|
|
|
out_entry->block_size = page_size; |
|
|
|
// Setup return context
|
|
|
|
context->next_page += 1; |
|
|
|
context->next_offset += page_size; |
|
|
|
// Validate that we can read the actual entry.
|
|
|
|
if (auto const page = context->next_page; page < entries.size()) { |
|
|
|
// Validate that the entry is mapped.
|
|
|
|
if (auto const paddr = entries[page].addr; paddr != 0) { |
|
|
|
// Populate the results and return true
|
|
|
|
out_entry->phys_addr = (entries[page].GetPhysOffset(current_page_bits)) + context->next_offset; |
|
|
|
out_entry->phys_addr = entries[page].GetPhysOffset(current_page_bits) + context->next_offset; |
|
|
|
context->next_page += 1; |
|
|
|
context->next_offset += page_size; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
context->next_page += 1; |
|
|
|
context->next_offset += page_size; |
|
|
|
// Otherwise return false
|
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
@ -100,9 +100,8 @@ struct PageTable { |
|
|
|
|
|
|
|
PageTable(const PageTable&) = delete; |
|
|
|
PageTable& operator=(const PageTable&) = delete; |
|
|
|
|
|
|
|
PageTable(PageTable&&) noexcept = default; |
|
|
|
PageTable& operator=(PageTable&&) noexcept = default; |
|
|
|
PageTable(PageTable&&) noexcept = delete; |
|
|
|
PageTable& operator=(PageTable&&) noexcept = delete; |
|
|
|
|
|
|
|
bool BeginTraversal(TraversalEntry* out_entry, TraversalContext* out_context, |
|
|
|
Common::ProcessAddress address) const; |
|
|
|
|
|
|
|
@ -58,19 +58,8 @@ public: |
|
|
|
|
|
|
|
SparseLargeVector(const SparseLargeVector&) = delete; |
|
|
|
SparseLargeVector& operator=(const SparseLargeVector&) = delete; |
|
|
|
|
|
|
|
SparseLargeVector(SparseLargeVector&& other) noexcept |
|
|
|
: alloc_size{std::exchange(other.alloc_size, 0)} |
|
|
|
, base_ptr{std::exchange(other.base_ptr, nullptr)} |
|
|
|
, committed_pages{std::exchange(other.base_ptr, nullptr)} |
|
|
|
{} |
|
|
|
|
|
|
|
SparseLargeVector& operator=(SparseLargeVector&& other) noexcept { |
|
|
|
alloc_size = std::exchange(other.alloc_size, 0); |
|
|
|
base_ptr = std::exchange(other.base_ptr, nullptr); |
|
|
|
committed_pages = std::exchange(other.base_ptr, nullptr); |
|
|
|
return *this; |
|
|
|
} |
|
|
|
SparseLargeVector(SparseLargeVector&& other) = delete; |
|
|
|
SparseLargeVector& operator=(SparseLargeVector&& other) = delete; |
|
|
|
|
|
|
|
void ResizeAndClear(std::size_t count) noexcept { |
|
|
|
if (auto const new_size = count * sizeof(T); new_size != alloc_size) { |
|
|
|
|
|
|
|
@ -125,14 +125,14 @@ struct Memory::Impl { |
|
|
|
[[nodiscard]] u8* GetPointerFromRasterizerCachedMemory(u64 vaddr) const { |
|
|
|
Common::PhysicalAddress const paddr = current_page_table->entries[vaddr >> YUZU_PAGEBITS].GetPhysOffset(YUZU_PAGEBITS); |
|
|
|
if (paddr) |
|
|
|
return system.DeviceMemory().GetPointer<u8>((paddr << YUZU_PAGEBITS) + vaddr); |
|
|
|
return system.DeviceMemory().GetPointer<u8>(paddr + vaddr); |
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
[[nodiscard]] u8* GetPointerFromDebugMemory(u64 vaddr) const { |
|
|
|
const Common::PhysicalAddress paddr = current_page_table->entries[vaddr >> YUZU_PAGEBITS].GetPhysOffset(YUZU_PAGEBITS); |
|
|
|
if (paddr != 0) |
|
|
|
return system.DeviceMemory().GetPointer<u8>((paddr << YUZU_PAGEBITS) + vaddr); |
|
|
|
return system.DeviceMemory().GetPointer<u8>(paddr + vaddr); |
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
@ -555,6 +555,8 @@ struct Memory::Impl { |
|
|
|
entry.addr = static_cast<u32>(GetInteger(target) >> YUZU_PAGEBITS) - static_cast<u32>(base); |
|
|
|
entry.block = static_cast<u32>(orig_base); |
|
|
|
|
|
|
|
ASSERT_MSG(entry.GetPhysOffset(YUZU_PAGEBITS) == GetInteger(target) - (base << YUZU_PAGEBITS), "assert failed; {:#x} == {:#x}", entry.GetPhysOffset(YUZU_PAGEBITS), GetInteger(target) - (base << YUZU_PAGEBITS)); |
|
|
|
|
|
|
|
ASSERT_MSG(page_table.entries[base].ptr.Pointer(), |
|
|
|
"memory mapping base yield a nullptr within the table"); |
|
|
|
|
|
|
|
|