aboutsummaryrefslogtreecommitdiff
path: root/src/core/memory.cpp
diff options
context:
space:
mode:
authorYuri Kunde Schlesner <yuriks@yuriks.net>2017-06-21 22:48:00 -0700
committerYuri Kunde Schlesner <yuriks@yuriks.net>2017-06-21 22:57:12 -0700
commit1423b3b10e138f54eb3b7ad54f2b1237b12b0700 (patch)
tree22a4991545b092b5a46cc448c0359d3bfcaf253e /src/core/memory.cpp
parent75be7907c10542080020fe5bb2abe510520d2760 (diff)
Memory: Add function to flush a virtual range from the rasterizer cache
This is slightly more ergonomic to use, correctly handles virtual regions which are disjoint in physical addressing space, and checks only regions which can be cached by the rasterizer.
Diffstat (limited to 'src/core/memory.cpp')
-rw-r--r--src/core/memory.cpp91
1 files changed, 52 insertions, 39 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 42ca69e006..38fe9e2317 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -83,19 +83,13 @@ static void MapPages(u32 base, u32 size, u8* memory, PageType type) {
LOG_DEBUG(HW_Memory, "Mapping %p onto %08X-%08X", memory, base * PAGE_SIZE,
(base + size) * PAGE_SIZE);
- u32 end = base + size;
+ RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE,
+ FlushMode::FlushAndInvalidate);
+ u32 end = base + size;
while (base != end) {
ASSERT_MSG(base < PAGE_TABLE_NUM_ENTRIES, "out of range mapping at %08X", base);
- // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
- // null here
- if (current_page_table->attributes[base] == PageType::RasterizerCachedMemory ||
- current_page_table->attributes[base] == PageType::RasterizerCachedSpecial) {
- RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(base << PAGE_BITS),
- PAGE_SIZE);
- }
-
current_page_table->attributes[base] = type;
current_page_table->pointers[base] = memory;
current_page_table->cached_res_count[base] = 0;
@@ -189,7 +183,7 @@ T Read(const VAddr vaddr) {
ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr);
break;
case PageType::RasterizerCachedMemory: {
- RasterizerFlushRegion(VirtualToPhysicalAddress(vaddr), sizeof(T));
+ RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush);
T value;
std::memcpy(&value, GetPointerFromVMA(vaddr), sizeof(T));
@@ -198,8 +192,7 @@ T Read(const VAddr vaddr) {
case PageType::Special:
return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr);
case PageType::RasterizerCachedSpecial: {
- RasterizerFlushRegion(VirtualToPhysicalAddress(vaddr), sizeof(T));
-
+ RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush);
return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr);
}
default:
@@ -229,8 +222,7 @@ void Write(const VAddr vaddr, const T data) {
ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr);
break;
case PageType::RasterizerCachedMemory: {
- RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(vaddr), sizeof(T));
-
+ RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::FlushAndInvalidate);
std::memcpy(GetPointerFromVMA(vaddr), &data, sizeof(T));
break;
}
@@ -238,8 +230,7 @@ void Write(const VAddr vaddr, const T data) {
WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data);
break;
case PageType::RasterizerCachedSpecial: {
- RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(vaddr), sizeof(T));
-
+ RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::FlushAndInvalidate);
WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data);
break;
}
@@ -369,11 +360,48 @@ void RasterizerFlushRegion(PAddr start, u32 size) {
}
void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size) {
+ // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
+ // null here
if (VideoCore::g_renderer != nullptr) {
VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(start, size);
}
}
+void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) {
+ // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
+ // null here
+ if (VideoCore::g_renderer != nullptr) {
+ VAddr end = start + size;
+
+ auto CheckRegion = [&](VAddr region_start, VAddr region_end) {
+ if (start >= region_end || end <= region_start) {
+ // No overlap with region
+ return;
+ }
+
+ VAddr overlap_start = std::max(start, region_start);
+ VAddr overlap_end = std::min(end, region_end);
+
+ PAddr physical_start = TryVirtualToPhysicalAddress(overlap_start).value();
+ u32 overlap_size = overlap_end - overlap_start;
+
+ auto* rasterizer = VideoCore::g_renderer->Rasterizer();
+ switch (mode) {
+ case FlushMode::Flush:
+ rasterizer->FlushRegion(physical_start, overlap_size);
+ break;
+ case FlushMode::FlushAndInvalidate:
+ rasterizer->FlushAndInvalidateRegion(physical_start, overlap_size);
+ break;
+ }
+ };
+
+ CheckRegion(LINEAR_HEAP_VADDR, LINEAR_HEAP_VADDR_END);
+ CheckRegion(NEW_LINEAR_HEAP_VADDR, NEW_LINEAR_HEAP_VADDR_END);
+ CheckRegion(VRAM_VADDR, VRAM_VADDR_END);
+ }
+}
+
u8 Read8(const VAddr addr) {
return Read<u8>(addr);
}
@@ -420,16 +448,13 @@ void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) {
break;
}
case PageType::RasterizerCachedMemory: {
- RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
-
+ RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
std::memcpy(dest_buffer, GetPointerFromVMA(current_vaddr), copy_amount);
break;
}
case PageType::RasterizerCachedSpecial: {
DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
-
- RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
-
+ RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount);
break;
}
@@ -490,18 +515,13 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size
break;
}
case PageType::RasterizerCachedMemory: {
- RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr),
- copy_amount);
-
+ RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
std::memcpy(GetPointerFromVMA(current_vaddr), src_buffer, copy_amount);
break;
}
case PageType::RasterizerCachedSpecial: {
DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
-
- RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr),
- copy_amount);
-
+ RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount);
break;
}
@@ -547,18 +567,13 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) {
break;
}
case PageType::RasterizerCachedMemory: {
- RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr),
- copy_amount);
-
+ RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
std::memset(GetPointerFromVMA(current_vaddr), 0, copy_amount);
break;
}
case PageType::RasterizerCachedSpecial: {
DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
-
- RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr),
- copy_amount);
-
+ RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount);
break;
}
@@ -603,15 +618,13 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) {
break;
}
case PageType::RasterizerCachedMemory: {
- RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
-
+ RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
WriteBlock(dest_addr, GetPointerFromVMA(current_vaddr), copy_amount);
break;
}
case PageType::RasterizerCachedSpecial: {
DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
-
- RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
+ RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
std::vector<u8> buffer(copy_amount);
GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, buffer.data(), buffer.size());