mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-19 01:28:30 +00:00
[TEST] Increased window limiter on AHB
This commit is contained in:
@@ -637,12 +637,10 @@ public:
|
|||||||
const AHardwareBuffer_Desc desc = MakeBlobDesc(PageAlignment * 2);
|
const AHardwareBuffer_Desc desc = MakeBlobDesc(PageAlignment * 2);
|
||||||
AHardwareBuffer* buffer{};
|
AHardwareBuffer* buffer{};
|
||||||
if (AHardwareBuffer_allocate(&desc, &buffer) != 0 || buffer == nullptr) {
|
if (AHardwareBuffer_allocate(&desc, &buffer) != 0 || buffer == nullptr) {
|
||||||
LOG_WARNING(HW_Memory, "Hardware buffer probe allocation failed");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const NativeHandle* const handle = get_native_handle(buffer);
|
const NativeHandle* const handle = get_native_handle(buffer);
|
||||||
if (handle == nullptr || handle->numFds < 1) {
|
if (handle == nullptr || handle->numFds < 1) {
|
||||||
LOG_WARNING(HW_Memory, "Hardware buffer has no mappable file descriptor");
|
|
||||||
AHardwareBuffer_release(buffer);
|
AHardwareBuffer_release(buffer);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -654,8 +652,6 @@ public:
|
|||||||
}
|
}
|
||||||
void* const ptr = mmap(nullptr, PageAlignment, prot, MAP_SHARED, probe_fd, offset);
|
void* const ptr = mmap(nullptr, PageAlignment, prot, MAP_SHARED, probe_fd, offset);
|
||||||
if (ptr == MAP_FAILED) {
|
if (ptr == MAP_FAILED) {
|
||||||
LOG_WARNING(HW_Memory, "Hardware buffer backing rejects {}: {}", what,
|
|
||||||
strerror(errno));
|
|
||||||
ok = false;
|
ok = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -673,21 +669,15 @@ public:
|
|||||||
size_t ComputeAhbBudget(size_t window_size) const {
|
size_t ComputeAhbBudget(size_t window_size) const {
|
||||||
const u64 total_physical = Common::GetMemInfo().TotalPhysicalMemory;
|
const u64 total_physical = Common::GetMemInfo().TotalPhysicalMemory;
|
||||||
if (total_physical == 0) {
|
if (total_physical == 0) {
|
||||||
LOG_WARNING(HW_Memory, "Host memory size is unknown, not committing hardware buffers");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
constexpr u64 MinimumTotalPhysical = 7ULL << 30;
|
constexpr u64 MinimumTotalPhysical = 7ULL << 30;
|
||||||
if (total_physical < MinimumTotalPhysical) {
|
if (total_physical < MinimumTotalPhysical) {
|
||||||
LOG_INFO(HW_Memory,
|
|
||||||
"Skipping hardware buffer backing, {} MiB of RAM is below the {} MiB minimum",
|
|
||||||
total_physical >> 20, MinimumTotalPhysical >> 20);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const u64 max_map_count = Common::GetMaxMapCount();
|
const u64 max_map_count = Common::GetMaxMapCount();
|
||||||
constexpr u64 ReservedMaps = 24576;
|
constexpr u64 ReservedMaps = 24576;
|
||||||
if (max_map_count == 0 || max_map_count <= ReservedMaps) {
|
if (max_map_count == 0 || max_map_count <= ReservedMaps) {
|
||||||
LOG_WARNING(HW_Memory,
|
|
||||||
"Skipping hardware buffer backing, vm.max_map_count is unknown or too low");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
u64 budget = total_physical / 6;
|
u64 budget = total_physical / 6;
|
||||||
@@ -701,10 +691,6 @@ public:
|
|||||||
budget = Common::AlignDown(budget, window_size);
|
budget = Common::AlignDown(budget, window_size);
|
||||||
constexpr u64 MinimumBudget = 256ULL << 20;
|
constexpr u64 MinimumBudget = 256ULL << 20;
|
||||||
if (budget < MinimumBudget) {
|
if (budget < MinimumBudget) {
|
||||||
LOG_INFO(HW_Memory,
|
|
||||||
"Skipping hardware buffer backing, only {} MiB could be committed on a {} MiB "
|
|
||||||
"system with {} MiB available and vm.max_map_count {}",
|
|
||||||
budget >> 20, total_physical >> 20, available >> 20, max_map_count);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return static_cast<size_t>(budget);
|
return static_cast<size_t>(budget);
|
||||||
@@ -717,14 +703,11 @@ public:
|
|||||||
static const PFN_AHardwareBuffer_getNativeHandle get_native_handle =
|
static const PFN_AHardwareBuffer_getNativeHandle get_native_handle =
|
||||||
ResolveGetNativeHandle();
|
ResolveGetNativeHandle();
|
||||||
if (get_native_handle == nullptr) {
|
if (get_native_handle == nullptr) {
|
||||||
LOG_WARNING(HW_Memory, "AHardwareBuffer_getNativeHandle is not available");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
constexpr size_t window_size = 64ULL << 20;
|
constexpr size_t window_size = 128ULL << 20;
|
||||||
const AHardwareBuffer_Desc window_desc = MakeBlobDesc(window_size);
|
const AHardwareBuffer_Desc window_desc = MakeBlobDesc(window_size);
|
||||||
if (AHardwareBuffer_isSupported(&window_desc) == 0) {
|
if (AHardwareBuffer_isSupported(&window_desc) == 0) {
|
||||||
LOG_WARNING(HW_Memory, "Allocator rejects {} MiB hardware buffer windows",
|
|
||||||
window_size >> 20);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const size_t budget = ComputeAhbBudget(window_size);
|
const size_t budget = ComputeAhbBudget(window_size);
|
||||||
@@ -753,22 +736,18 @@ public:
|
|||||||
const AHardwareBuffer_Desc desc = MakeBlobDesc(window_size);
|
const AHardwareBuffer_Desc desc = MakeBlobDesc(window_size);
|
||||||
AHardwareBuffer* buffer{};
|
AHardwareBuffer* buffer{};
|
||||||
if (AHardwareBuffer_allocate(&desc, &buffer) != 0 || buffer == nullptr) {
|
if (AHardwareBuffer_allocate(&desc, &buffer) != 0 || buffer == nullptr) {
|
||||||
LOG_WARNING(HW_Memory, "Hardware buffer allocation failed for window {} of {}", i,
|
|
||||||
num_windows);
|
|
||||||
cleanup();
|
cleanup();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
buffers.push_back(buffer);
|
buffers.push_back(buffer);
|
||||||
const NativeHandle* const handle = get_native_handle(buffer);
|
const NativeHandle* const handle = get_native_handle(buffer);
|
||||||
if (handle == nullptr || handle->numFds < 1) {
|
if (handle == nullptr || handle->numFds < 1) {
|
||||||
LOG_WARNING(HW_Memory, "Hardware buffer has no mappable file descriptor");
|
|
||||||
cleanup();
|
cleanup();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const int buffer_fd = handle->data[0];
|
const int buffer_fd = handle->data[0];
|
||||||
const off_t buffer_len = lseek(buffer_fd, 0, SEEK_END);
|
const off_t buffer_len = lseek(buffer_fd, 0, SEEK_END);
|
||||||
if (buffer_len < static_cast<off_t>(window_size)) {
|
if (buffer_len < static_cast<off_t>(window_size)) {
|
||||||
LOG_WARNING(HW_Memory, "Hardware buffer descriptor smaller than requested");
|
|
||||||
cleanup();
|
cleanup();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -777,7 +756,6 @@ public:
|
|||||||
u8* const base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_NONE,
|
u8* const base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_NONE,
|
||||||
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0));
|
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0));
|
||||||
if (base == MAP_FAILED) {
|
if (base == MAP_FAILED) {
|
||||||
LOG_WARNING(HW_Memory, "Failed to reserve backing address space: {}", strerror(errno));
|
|
||||||
cleanup();
|
cleanup();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -788,7 +766,6 @@ public:
|
|||||||
}
|
}
|
||||||
if (mmap(base + offset, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, map_fd,
|
if (mmap(base + offset, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, map_fd,
|
||||||
map_offset) == MAP_FAILED) {
|
map_offset) == MAP_FAILED) {
|
||||||
LOG_WARNING(HW_Memory, "Backing mmap failed: {}", strerror(errno));
|
|
||||||
munmap(base, backing_size);
|
munmap(base, backing_size);
|
||||||
cleanup();
|
cleanup();
|
||||||
return false;
|
return false;
|
||||||
@@ -816,9 +793,6 @@ public:
|
|||||||
ahb_base = region_base;
|
ahb_base = region_base;
|
||||||
ahb_bytes = region_size;
|
ahb_bytes = region_size;
|
||||||
committed_backing_size.store(region_size, std::memory_order_relaxed);
|
committed_backing_size.store(region_size, std::memory_order_relaxed);
|
||||||
LOG_INFO(HW_Memory,
|
|
||||||
"Guest memory {:#x}-{:#x} backed by {} hardware buffer windows, {} MiB committed",
|
|
||||||
region_base, region_base + region_size, ahb_windows.size(), region_size >> 20);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -990,10 +990,6 @@ bool Device::GetSuitability(bool requires_swapchain) {
|
|||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
if (extensions.external_memory_ahb && !extensions.queue_family_foreign) {
|
if (extensions.external_memory_ahb && !extensions.queue_family_foreign) {
|
||||||
LOG_INFO(Render_Vulkan,
|
|
||||||
"Not loading {} because its dependency {} is unavailable",
|
|
||||||
VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME,
|
|
||||||
VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
|
|
||||||
loaded_extensions.erase(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
|
loaded_extensions.erase(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
|
||||||
extensions.external_memory_ahb = false;
|
extensions.external_memory_ahb = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -233,10 +233,10 @@ namespace Vulkan {
|
|||||||
size)) {
|
size)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (device.IsTiler()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!hardware_buffers.empty()) {
|
if (!hardware_buffers.empty()) {
|
||||||
LOG_INFO(Render_Vulkan,
|
|
||||||
"Unified memory disabled, guest memory is backed by hardware buffers that "
|
|
||||||
"could not be imported");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ImportHostPointer(base, size)) {
|
if (ImportHostPointer(base, size)) {
|
||||||
@@ -247,20 +247,16 @@ namespace Vulkan {
|
|||||||
|
|
||||||
bool HostMemoryImport::ImportHostPointer(void *base, size_t size) {
|
bool HostMemoryImport::ImportHostPointer(void *base, size_t size) {
|
||||||
if (!device.IsExtExternalMemoryHostSupported()) {
|
if (!device.IsExtExternalMemoryHostSupported()) {
|
||||||
LOG_INFO(Render_Vulkan,
|
|
||||||
"Unified memory disabled, VK_EXT_external_memory_host is not supported");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const u64 alignment = device.GetMinImportedHostPointerAlignment();
|
const u64 alignment = device.GetMinImportedHostPointerAlignment();
|
||||||
if (alignment == 0 || !Common::IsAligned(reinterpret_cast<uintptr_t>(base), alignment) ||
|
if (alignment == 0 || !Common::IsAligned(reinterpret_cast<uintptr_t>(base), alignment) ||
|
||||||
!Common::IsAligned(size, alignment)) {
|
!Common::IsAligned(size, alignment)) {
|
||||||
LOG_INFO(Render_Vulkan,
|
|
||||||
"Unified memory disabled, host allocation does not satisfy alignment {}",
|
|
||||||
alignment);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
using namespace Common::Literals;
|
using namespace Common::Literals;
|
||||||
VkDeviceSize candidate_window = 1_GiB;
|
constexpr VkDeviceSize DesktopWindowSize = 4_GiB;
|
||||||
|
VkDeviceSize candidate_window = DesktopWindowSize;
|
||||||
const u64 max_buffer_size = device.GetMaxBufferSize();
|
const u64 max_buffer_size = device.GetMaxBufferSize();
|
||||||
if (max_buffer_size != 0 && max_buffer_size < candidate_window) {
|
if (max_buffer_size != 0 && max_buffer_size < candidate_window) {
|
||||||
candidate_window = max_buffer_size;
|
candidate_window = max_buffer_size;
|
||||||
@@ -327,9 +323,6 @@ namespace Vulkan {
|
|||||||
const u32 heap_index = memory_props.memoryTypes[*type_index].heapIndex;
|
const u32 heap_index = memory_props.memoryTypes[*type_index].heapIndex;
|
||||||
const VkDeviceSize heap_size = memory_props.memoryHeaps[heap_index].size;
|
const VkDeviceSize heap_size = memory_props.memoryHeaps[heap_index].size;
|
||||||
if (imported_size + window_len > heap_size / 2) {
|
if (imported_size + window_len > heap_size / 2) {
|
||||||
LOG_INFO(Render_Vulkan,
|
|
||||||
"Stopping guest memory import at {} MiB to leave room on heap {} of {} MiB",
|
|
||||||
imported_size >> 20, heap_index, heap_size >> 20);
|
|
||||||
logical.DestroyBufferRaw(new_buffer);
|
logical.DestroyBufferRaw(new_buffer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -361,12 +354,8 @@ namespace Vulkan {
|
|||||||
imported_size += static_cast<size_t>(window_len);
|
imported_size += static_cast<size_t>(window_len);
|
||||||
}
|
}
|
||||||
if (windows.empty()) {
|
if (windows.empty()) {
|
||||||
LOG_INFO(Render_Vulkan, "Host pointer import failed");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
LOG_INFO(Render_Vulkan,
|
|
||||||
"Imported {} MiB of guest memory for unified memory access in {} windows",
|
|
||||||
imported_size >> 20, windows.size());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,9 +370,6 @@ namespace Vulkan {
|
|||||||
}
|
}
|
||||||
const u64 max_allocation_size = device.GetMaxMemoryAllocationSize();
|
const u64 max_allocation_size = device.GetMaxMemoryAllocationSize();
|
||||||
if (max_allocation_size != 0 && hardware_buffer_window > max_allocation_size) {
|
if (max_allocation_size != 0 && hardware_buffer_window > max_allocation_size) {
|
||||||
LOG_WARNING(Render_Vulkan,
|
|
||||||
"Hardware buffer windows of {} MiB exceed the {} MiB allocation limit",
|
|
||||||
hardware_buffer_window >> 20, max_allocation_size >> 20);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (hardware_buffer_base >= size) {
|
if (hardware_buffer_base >= size) {
|
||||||
@@ -477,15 +463,11 @@ namespace Vulkan {
|
|||||||
imported_size += static_cast<size_t>(window_len);
|
imported_size += static_cast<size_t>(window_len);
|
||||||
}
|
}
|
||||||
if (windows.empty()) {
|
if (windows.empty()) {
|
||||||
LOG_INFO(Render_Vulkan, "Hardware buffer import failed");
|
|
||||||
window_size = 0;
|
window_size = 0;
|
||||||
base_offset = 0;
|
base_offset = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
foreign_ownership = true;
|
foreign_ownership = true;
|
||||||
LOG_INFO(Render_Vulkan,
|
|
||||||
"Imported {} MiB of guest memory at {:#x} via hardware buffers in {} windows",
|
|
||||||
imported_size >> 20, base_offset, windows.size());
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user