summaryrefslogtreecommitdiff
path: root/src/common/host_memory.cpp
diff options
context:
space:
mode:
authorGravatar Markus Wick2021-06-11 11:47:23 +0200
committerGravatar Markus Wick2021-06-11 17:27:17 +0200
commit7f85abb28120fbb57bb813b828ee42f2a2031990 (patch)
tree0e4ce28226164e465b8739b22604b1741d2b1c11 /src/common/host_memory.cpp
parentcommon/host_shader: Load Windows 10 functions dynamically (diff)
downloadyuzu-7f85abb28120fbb57bb813b828ee42f2a2031990.tar.gz
yuzu-7f85abb28120fbb57bb813b828ee42f2a2031990.tar.xz
yuzu-7f85abb28120fbb57bb813b828ee42f2a2031990.zip
common/host_memory: Implement a fallback if fastmem fails.
This falls back to the old approach of using a virtual buffer. Windows is untested, but this build should fix support for Windows < 10 v1803. However without fastmem support at all.
Diffstat (limited to 'src/common/host_memory.cpp')
-rw-r--r--src/common/host_memory.cpp59
1 files changed, 45 insertions, 14 deletions
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp
index 9ae384f01..8bd70abc7 100644
--- a/src/common/host_memory.cpp
+++ b/src/common/host_memory.cpp
@@ -449,21 +449,52 @@ private:
449 int fd{-1}; // memfd file descriptor, -1 is the error value of memfd_create 449 int fd{-1}; // memfd file descriptor, -1 is the error value of memfd_create
450}; 450};
451 451
452#else // ^^^ Linux ^^^ 452#else // ^^^ Linux ^^^ vvv Generic vvv
453 453
454#error Please implement the host memory for your platform 454class HostMemory::Impl {
455public:
456 explicit Impl(size_t /*backing_size */, size_t /* virtual_size */) {
457 // This is just a place holder.
458 // Please implement fastmem in a propper way on your platform.
459 throw std::bad_alloc{};
460 }
455 461
456#endif 462 void Map(size_t virtual_offset, size_t host_offset, size_t length) {}
463
464 void Unmap(size_t virtual_offset, size_t length) {}
465
466 void Protect(size_t virtual_offset, size_t length, bool read, bool write) {}
467
468 u8* backing_base{nullptr};
469 u8* virtual_base{nullptr};
470};
471
472#endif // ^^^ Generic ^^^
457 473
458HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_) 474HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_)
459 : backing_size(backing_size_), 475 : backing_size(backing_size_), virtual_size(virtual_size_) {
460 virtual_size(virtual_size_), impl{std::make_unique<HostMemory::Impl>( 476 try {
461 AlignUp(backing_size, PageAlignment), 477 // Try to allocate a fastmem arena.
462 AlignUp(virtual_size, PageAlignment) + 3 * HugePageSize)}, 478 // The implementation will fail with std::bad_alloc on errors.
463 backing_base{impl->backing_base}, virtual_base{impl->virtual_base} { 479 impl = std::make_unique<HostMemory::Impl>(AlignUp(backing_size, PageAlignment),
464 virtual_base += 2 * HugePageSize - 1; 480 AlignUp(virtual_size, PageAlignment) +
465 virtual_base -= reinterpret_cast<size_t>(virtual_base) & (HugePageSize - 1); 481 3 * HugePageSize);
466 virtual_base_offset = virtual_base - impl->virtual_base; 482 backing_base = impl->backing_base;
483 virtual_base = impl->virtual_base;
484
485 if (virtual_base) {
486 virtual_base += 2 * HugePageSize - 1;
487 virtual_base -= reinterpret_cast<size_t>(virtual_base) & (HugePageSize - 1);
488 virtual_base_offset = virtual_base - impl->virtual_base;
489 }
490
491 } catch (const std::bad_alloc&) {
492 LOG_CRITICAL(HW_Memory,
493 "Fastmem unavailable, falling back to VirtualBuffer for memory allocation");
494 fallback_buffer = std::make_unique<Common::VirtualBuffer<u8>>(backing_size);
495 backing_base = fallback_buffer->data();
496 virtual_base = nullptr;
497 }
467} 498}
468 499
469HostMemory::~HostMemory() = default; 500HostMemory::~HostMemory() = default;
@@ -478,7 +509,7 @@ void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length) {
478 ASSERT(length % PageAlignment == 0); 509 ASSERT(length % PageAlignment == 0);
479 ASSERT(virtual_offset + length <= virtual_size); 510 ASSERT(virtual_offset + length <= virtual_size);
480 ASSERT(host_offset + length <= backing_size); 511 ASSERT(host_offset + length <= backing_size);
481 if (length == 0) { 512 if (length == 0 || !virtual_base || !impl) {
482 return; 513 return;
483 } 514 }
484 impl->Map(virtual_offset + virtual_base_offset, host_offset, length); 515 impl->Map(virtual_offset + virtual_base_offset, host_offset, length);
@@ -488,7 +519,7 @@ void HostMemory::Unmap(size_t virtual_offset, size_t length) {
488 ASSERT(virtual_offset % PageAlignment == 0); 519 ASSERT(virtual_offset % PageAlignment == 0);
489 ASSERT(length % PageAlignment == 0); 520 ASSERT(length % PageAlignment == 0);
490 ASSERT(virtual_offset + length <= virtual_size); 521 ASSERT(virtual_offset + length <= virtual_size);
491 if (length == 0) { 522 if (length == 0 || !virtual_base || !impl) {
492 return; 523 return;
493 } 524 }
494 impl->Unmap(virtual_offset + virtual_base_offset, length); 525 impl->Unmap(virtual_offset + virtual_base_offset, length);
@@ -498,7 +529,7 @@ void HostMemory::Protect(size_t virtual_offset, size_t length, bool read, bool w
498 ASSERT(virtual_offset % PageAlignment == 0); 529 ASSERT(virtual_offset % PageAlignment == 0);
499 ASSERT(length % PageAlignment == 0); 530 ASSERT(length % PageAlignment == 0);
500 ASSERT(virtual_offset + length <= virtual_size); 531 ASSERT(virtual_offset + length <= virtual_size);
501 if (length == 0) { 532 if (length == 0 || !virtual_base || !impl) {
502 return; 533 return;
503 } 534 }
504 impl->Protect(virtual_offset + virtual_base_offset, length, read, write); 535 impl->Protect(virtual_offset + virtual_base_offset, length, read, write);