summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-04-23 14:00:52 -0400
committerGravatar GitHub2018-04-23 14:00:52 -0400
commit3967f9c6efae0af3d4e1b58b9898cef96335615f (patch)
tree539a907ded52d1eb05f2c006e93cf851973baa7b /src
parentMerge pull request #382 from Subv/a2rgb10_rt (diff)
parentGPU: Make the GPU virtual memory manager use 16 page bits and 10 page table b... (diff)
downloadyuzu-3967f9c6efae0af3d4e1b58b9898cef96335615f.tar.gz
yuzu-3967f9c6efae0af3d4e1b58b9898cef96335615f.tar.xz
yuzu-3967f9c6efae0af3d4e1b58b9898cef96335615f.zip
Merge pull request #383 from Subv/gpu_mmu
GPU: Make the GPU virtual memory manager use 16 page bits and 10 pagetable bits.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/memory_manager.cpp53
-rw-r--r--src/video_core/memory_manager.h6
2 files changed, 25 insertions, 34 deletions
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp
index 2789a4ca1..2e1edee03 100644
--- a/src/video_core/memory_manager.cpp
+++ b/src/video_core/memory_manager.cpp
@@ -2,6 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/alignment.h"
5#include "common/assert.h" 6#include "common/assert.h"
6#include "video_core/memory_manager.h" 7#include "video_core/memory_manager.h"
7 8
@@ -11,7 +12,8 @@ PAddr MemoryManager::AllocateSpace(u64 size, u64 align) {
11 boost::optional<PAddr> paddr = FindFreeBlock(size, align); 12 boost::optional<PAddr> paddr = FindFreeBlock(size, align);
12 ASSERT(paddr); 13 ASSERT(paddr);
13 14
14 for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { 15 for (u64 offset = 0; offset < size; offset += PAGE_SIZE) {
16 ASSERT(PageSlot(*paddr + offset) == static_cast<u64>(PageStatus::Unmapped));
15 PageSlot(*paddr + offset) = static_cast<u64>(PageStatus::Allocated); 17 PageSlot(*paddr + offset) = static_cast<u64>(PageStatus::Allocated);
16 } 18 }
17 19
@@ -19,13 +21,8 @@ PAddr MemoryManager::AllocateSpace(u64 size, u64 align) {
19} 21}
20 22
21PAddr MemoryManager::AllocateSpace(PAddr paddr, u64 size, u64 align) { 23PAddr MemoryManager::AllocateSpace(PAddr paddr, u64 size, u64 align) {
22 for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { 24 for (u64 offset = 0; offset < size; offset += PAGE_SIZE) {
23 if (IsPageMapped(paddr + offset)) { 25 ASSERT(PageSlot(paddr + offset) == static_cast<u64>(PageStatus::Unmapped));
24 return AllocateSpace(size, align);
25 }
26 }
27
28 for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) {
29 PageSlot(paddr + offset) = static_cast<u64>(PageStatus::Allocated); 26 PageSlot(paddr + offset) = static_cast<u64>(PageStatus::Allocated);
30 } 27 }
31 28
@@ -33,12 +30,11 @@ PAddr MemoryManager::AllocateSpace(PAddr paddr, u64 size, u64 align) {
33} 30}
34 31
35PAddr MemoryManager::MapBufferEx(VAddr vaddr, u64 size) { 32PAddr MemoryManager::MapBufferEx(VAddr vaddr, u64 size) {
36 vaddr &= ~Memory::PAGE_MASK; 33 boost::optional<PAddr> paddr = FindFreeBlock(size, PAGE_SIZE);
37
38 boost::optional<PAddr> paddr = FindFreeBlock(size);
39 ASSERT(paddr); 34 ASSERT(paddr);
40 35
41 for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { 36 for (u64 offset = 0; offset < size; offset += PAGE_SIZE) {
37 ASSERT(PageSlot(*paddr + offset) == static_cast<u64>(PageStatus::Unmapped));
42 PageSlot(*paddr + offset) = vaddr + offset; 38 PageSlot(*paddr + offset) = vaddr + offset;
43 } 39 }
44 40
@@ -46,16 +42,10 @@ PAddr MemoryManager::MapBufferEx(VAddr vaddr, u64 size) {
46} 42}
47 43
48PAddr MemoryManager::MapBufferEx(VAddr vaddr, PAddr paddr, u64 size) { 44PAddr MemoryManager::MapBufferEx(VAddr vaddr, PAddr paddr, u64 size) {
49 vaddr &= ~Memory::PAGE_MASK; 45 ASSERT((paddr & PAGE_MASK) == 0);
50 paddr &= ~Memory::PAGE_MASK;
51 46
52 for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { 47 for (u64 offset = 0; offset < size; offset += PAGE_SIZE) {
53 if (PageSlot(paddr + offset) != static_cast<u64>(PageStatus::Allocated)) { 48 ASSERT(PageSlot(paddr + offset) == static_cast<u64>(PageStatus::Allocated));
54 return MapBufferEx(vaddr, size);
55 }
56 }
57
58 for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) {
59 PageSlot(paddr + offset) = vaddr + offset; 49 PageSlot(paddr + offset) = vaddr + offset;
60 } 50 }
61 51
@@ -63,23 +53,20 @@ PAddr MemoryManager::MapBufferEx(VAddr vaddr, PAddr paddr, u64 size) {
63} 53}
64 54
65boost::optional<PAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) { 55boost::optional<PAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) {
66 PAddr paddr{}; 56 PAddr paddr = 0;
67 u64 free_space{}; 57 u64 free_space = 0;
68 align = (align + Memory::PAGE_MASK) & ~Memory::PAGE_MASK; 58 align = (align + PAGE_MASK) & ~PAGE_MASK;
69 59
70 while (paddr + free_space < MAX_ADDRESS) { 60 while (paddr + free_space < MAX_ADDRESS) {
71 if (!IsPageMapped(paddr + free_space)) { 61 if (!IsPageMapped(paddr + free_space)) {
72 free_space += Memory::PAGE_SIZE; 62 free_space += PAGE_SIZE;
73 if (free_space >= size) { 63 if (free_space >= size) {
74 return paddr; 64 return paddr;
75 } 65 }
76 } else { 66 } else {
77 paddr += free_space + Memory::PAGE_SIZE; 67 paddr += free_space + PAGE_SIZE;
78 free_space = 0; 68 free_space = 0;
79 const u64 remainder{paddr % align}; 69 paddr = Common::AlignUp(paddr, align);
80 if (!remainder) {
81 paddr = (paddr - remainder) + align;
82 }
83 } 70 }
84 } 71 }
85 72
@@ -89,7 +76,7 @@ boost::optional<PAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) {
89VAddr MemoryManager::PhysicalToVirtualAddress(PAddr paddr) { 76VAddr MemoryManager::PhysicalToVirtualAddress(PAddr paddr) {
90 VAddr base_addr = PageSlot(paddr); 77 VAddr base_addr = PageSlot(paddr);
91 ASSERT(base_addr != static_cast<u64>(PageStatus::Unmapped)); 78 ASSERT(base_addr != static_cast<u64>(PageStatus::Unmapped));
92 return base_addr + (paddr & Memory::PAGE_MASK); 79 return base_addr + (paddr & PAGE_MASK);
93} 80}
94 81
95bool MemoryManager::IsPageMapped(PAddr paddr) { 82bool MemoryManager::IsPageMapped(PAddr paddr) {
@@ -97,14 +84,14 @@ bool MemoryManager::IsPageMapped(PAddr paddr) {
97} 84}
98 85
99VAddr& MemoryManager::PageSlot(PAddr paddr) { 86VAddr& MemoryManager::PageSlot(PAddr paddr) {
100 auto& block = page_table[(paddr >> (Memory::PAGE_BITS + PAGE_TABLE_BITS)) & PAGE_TABLE_MASK]; 87 auto& block = page_table[(paddr >> (PAGE_BITS + PAGE_TABLE_BITS)) & PAGE_TABLE_MASK];
101 if (!block) { 88 if (!block) {
102 block = std::make_unique<PageBlock>(); 89 block = std::make_unique<PageBlock>();
103 for (unsigned index = 0; index < PAGE_BLOCK_SIZE; index++) { 90 for (unsigned index = 0; index < PAGE_BLOCK_SIZE; index++) {
104 (*block)[index] = static_cast<u64>(PageStatus::Unmapped); 91 (*block)[index] = static_cast<u64>(PageStatus::Unmapped);
105 } 92 }
106 } 93 }
107 return (*block)[(paddr >> Memory::PAGE_BITS) & PAGE_BLOCK_MASK]; 94 return (*block)[(paddr >> PAGE_BITS) & PAGE_BLOCK_MASK];
108} 95}
109 96
110} // namespace Tegra 97} // namespace Tegra
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h
index 47da7acd6..b73e283f8 100644
--- a/src/video_core/memory_manager.h
+++ b/src/video_core/memory_manager.h
@@ -24,6 +24,10 @@ public:
24 PAddr MapBufferEx(VAddr vaddr, PAddr paddr, u64 size); 24 PAddr MapBufferEx(VAddr vaddr, PAddr paddr, u64 size);
25 VAddr PhysicalToVirtualAddress(PAddr paddr); 25 VAddr PhysicalToVirtualAddress(PAddr paddr);
26 26
27 static constexpr u64 PAGE_BITS = 16;
28 static constexpr u64 PAGE_SIZE = 1 << PAGE_BITS;
29 static constexpr u64 PAGE_MASK = PAGE_SIZE - 1;
30
27private: 31private:
28 boost::optional<PAddr> FindFreeBlock(u64 size, u64 align = 1); 32 boost::optional<PAddr> FindFreeBlock(u64 size, u64 align = 1);
29 bool IsPageMapped(PAddr paddr); 33 bool IsPageMapped(PAddr paddr);
@@ -35,7 +39,7 @@ private:
35 }; 39 };
36 40
37 static constexpr u64 MAX_ADDRESS{0x10000000000ULL}; 41 static constexpr u64 MAX_ADDRESS{0x10000000000ULL};
38 static constexpr u64 PAGE_TABLE_BITS{14}; 42 static constexpr u64 PAGE_TABLE_BITS{10};
39 static constexpr u64 PAGE_TABLE_SIZE{1 << PAGE_TABLE_BITS}; 43 static constexpr u64 PAGE_TABLE_SIZE{1 << PAGE_TABLE_BITS};
40 static constexpr u64 PAGE_TABLE_MASK{PAGE_TABLE_SIZE - 1}; 44 static constexpr u64 PAGE_TABLE_MASK{PAGE_TABLE_SIZE - 1};
41 static constexpr u64 PAGE_BLOCK_BITS{14}; 45 static constexpr u64 PAGE_BLOCK_BITS{14};