Compare commits
10 commits
Author | SHA1 | Date | |
---|---|---|---|
6eef072842 | |||
81de509814 | |||
2dd76e9f7a | |||
062a1a9b1a | |||
c0ebe85a74 | |||
21433675e4 | |||
![]() |
b9c5a49546 | ||
![]() |
cd8cf317fb | ||
84b8e7bd50 | |||
010dde41eb |
11 changed files with 106 additions and 20 deletions
|
@ -58,7 +58,7 @@ android {
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO If this is ever modified, change application_id in strings.xml
|
// TODO If this is ever modified, change application_id in strings.xml
|
||||||
applicationId = "dev.eden.eden_emulator"
|
applicationId = "dev.legacy.eden_emulator"
|
||||||
minSdk = 30
|
minSdk = 30
|
||||||
targetSdk = 36
|
targetSdk = 36
|
||||||
versionName = getGitVersion()
|
versionName = getGitVersion()
|
||||||
|
@ -103,7 +103,7 @@ android {
|
||||||
signingConfigs.getByName("default")
|
signingConfigs.getByName("default")
|
||||||
}
|
}
|
||||||
|
|
||||||
resValue("string", "app_name_suffixed", "Eden")
|
resValue("string", "app_name_suffixed", "Eden Legacy")
|
||||||
isMinifyEnabled = true
|
isMinifyEnabled = true
|
||||||
isDebuggable = false
|
isDebuggable = false
|
||||||
proguardFiles(
|
proguardFiles(
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 195 KiB After Width: | Height: | Size: 438 KiB |
|
@ -227,7 +227,7 @@ HaltReason ArmNce::RunThread(Kernel::KThread* thread) {
|
||||||
if (auto it = post_handlers.find(m_guest_ctx.pc); it != post_handlers.end()) {
|
if (auto it = post_handlers.find(m_guest_ctx.pc); it != post_handlers.end()) {
|
||||||
hr = ReturnToRunCodeByTrampoline(thread_params, &m_guest_ctx, it->second);
|
hr = ReturnToRunCodeByTrampoline(thread_params, &m_guest_ctx, it->second);
|
||||||
} else {
|
} else {
|
||||||
hr = ReturnToRunCodeByExceptionLevelChange(m_thread_id, thread_params);
|
hr = ReturnToRunCodeByExceptionLevelChange(m_thread_id, thread_params); // Android: Use "process handle SIGUSR2 -n true -p true -s false" (and SIGURG) in LLDB when debugging
|
||||||
}
|
}
|
||||||
|
|
||||||
// Critical section for thread cleanup
|
// Critical section for thread cleanup
|
||||||
|
|
|
@ -53,6 +53,16 @@ enum class NetDbError : s32 {
|
||||||
NoData = 4,
|
NoData = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const std::vector<std::string> blockedDomains = {"srv.nintendo.net", "battle.net",
|
||||||
|
"microsoft.com", "mojang.com",
|
||||||
|
"xboxlive.com", "minecraftservices.com"};
|
||||||
|
|
||||||
|
static bool IsBlockedHost(const std::string& host) {
|
||||||
|
return std::any_of(
|
||||||
|
blockedDomains.begin(), blockedDomains.end(),
|
||||||
|
[&host](const std::string& domain) { return host.find(domain) != std::string::npos; });
|
||||||
|
}
|
||||||
|
|
||||||
static NetDbError GetAddrInfoErrorToNetDbError(GetAddrInfoError result) {
|
static NetDbError GetAddrInfoErrorToNetDbError(GetAddrInfoError result) {
|
||||||
// These combinations have been verified on console (but are not
|
// These combinations have been verified on console (but are not
|
||||||
// exhaustive).
|
// exhaustive).
|
||||||
|
@ -154,7 +164,7 @@ static std::pair<u32, GetAddrInfoError> GetHostByNameRequestImpl(HLERequestConte
|
||||||
// For now, ignore options, which are in input buffer 1 for GetHostByNameRequestWithOptions.
|
// For now, ignore options, which are in input buffer 1 for GetHostByNameRequestWithOptions.
|
||||||
|
|
||||||
// Prevent resolution of Nintendo servers
|
// Prevent resolution of Nintendo servers
|
||||||
if (host.find("srv.nintendo.net") != std::string::npos) {
|
if (IsBlockedHost(host)) {
|
||||||
LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host);
|
LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host);
|
||||||
return {0, GetAddrInfoError::AGAIN};
|
return {0, GetAddrInfoError::AGAIN};
|
||||||
}
|
}
|
||||||
|
@ -271,7 +281,7 @@ static std::pair<u32, GetAddrInfoError> GetAddrInfoRequestImpl(HLERequestContext
|
||||||
const std::string host = Common::StringFromBuffer(host_buffer);
|
const std::string host = Common::StringFromBuffer(host_buffer);
|
||||||
|
|
||||||
// Prevent resolution of Nintendo servers
|
// Prevent resolution of Nintendo servers
|
||||||
if (host.find("srv.nintendo.net") != std::string::npos) {
|
if (IsBlockedHost(host)) {
|
||||||
LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host);
|
LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host);
|
||||||
return {0, GetAddrInfoError::AGAIN};
|
return {0, GetAddrInfoError::AGAIN};
|
||||||
}
|
}
|
||||||
|
@ -359,5 +369,4 @@ void SFDNSRES::ResolverSetOptionRequest(HLERequestContext& ctx) {
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push<s32>(0); // bsd errno
|
rb.Push<s32>(0); // bsd errno
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::Sockets
|
} // namespace Service::Sockets
|
||||||
|
|
|
@ -26,7 +26,9 @@ BufferCache<P>::BufferCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, R
|
||||||
void(slot_buffers.insert(runtime, NullBufferParams{}));
|
void(slot_buffers.insert(runtime, NullBufferParams{}));
|
||||||
gpu_modified_ranges.Clear();
|
gpu_modified_ranges.Clear();
|
||||||
inline_buffer_id = NULL_BUFFER_ID;
|
inline_buffer_id = NULL_BUFFER_ID;
|
||||||
|
#ifdef ANDROID
|
||||||
|
immediately_free = (Settings::values.vram_usage_mode.GetValue() == Settings::VramUsageMode::Aggressive);
|
||||||
|
#endif
|
||||||
if (!runtime.CanReportMemoryUsage()) {
|
if (!runtime.CanReportMemoryUsage()) {
|
||||||
minimum_memory = DEFAULT_EXPECTED_MEMORY;
|
minimum_memory = DEFAULT_EXPECTED_MEMORY;
|
||||||
critical_memory = DEFAULT_CRITICAL_MEMORY;
|
critical_memory = DEFAULT_CRITICAL_MEMORY;
|
||||||
|
@ -1381,6 +1383,8 @@ void BufferCache<P>::JoinOverlap(BufferId new_buffer_id, BufferId overlap_id,
|
||||||
});
|
});
|
||||||
new_buffer.MarkUsage(copies[0].dst_offset, copies[0].size);
|
new_buffer.MarkUsage(copies[0].dst_offset, copies[0].size);
|
||||||
runtime.CopyBuffer(new_buffer, overlap, copies, true);
|
runtime.CopyBuffer(new_buffer, overlap, copies, true);
|
||||||
|
if (immediately_free)
|
||||||
|
runtime.Finish();
|
||||||
DeleteBuffer(overlap_id, true);
|
DeleteBuffer(overlap_id, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1671,7 +1675,9 @@ void BufferCache<P>::DeleteBuffer(BufferId buffer_id, bool do_not_mark) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Unregister(buffer_id);
|
Unregister(buffer_id);
|
||||||
delayed_destruction_ring.Push(std::move(slot_buffers[buffer_id]));
|
|
||||||
|
if (!do_not_mark || !immediately_free)
|
||||||
|
delayed_destruction_ring.Push(std::move(slot_buffers[buffer_id]));
|
||||||
slot_buffers.erase(buffer_id);
|
slot_buffers.erase(buffer_id);
|
||||||
|
|
||||||
if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
|
if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
|
||||||
|
|
|
@ -154,7 +154,11 @@ template <class P>
|
||||||
class BufferCache : public VideoCommon::ChannelSetupCaches<BufferCacheChannelInfo> {
|
class BufferCache : public VideoCommon::ChannelSetupCaches<BufferCacheChannelInfo> {
|
||||||
// Page size for caching purposes.
|
// Page size for caching purposes.
|
||||||
// This is unrelated to the CPU page size and it can be changed as it seems optimal.
|
// This is unrelated to the CPU page size and it can be changed as it seems optimal.
|
||||||
|
#ifdef ANDROID
|
||||||
|
static constexpr u32 CACHING_PAGEBITS = 12;
|
||||||
|
#else
|
||||||
static constexpr u32 CACHING_PAGEBITS = 16;
|
static constexpr u32 CACHING_PAGEBITS = 16;
|
||||||
|
#endif
|
||||||
static constexpr u64 CACHING_PAGESIZE = u64{1} << CACHING_PAGEBITS;
|
static constexpr u64 CACHING_PAGESIZE = u64{1} << CACHING_PAGEBITS;
|
||||||
|
|
||||||
static constexpr bool IS_OPENGL = P::IS_OPENGL;
|
static constexpr bool IS_OPENGL = P::IS_OPENGL;
|
||||||
|
@ -168,9 +172,15 @@ class BufferCache : public VideoCommon::ChannelSetupCaches<BufferCacheChannelInf
|
||||||
static constexpr bool SEPARATE_IMAGE_BUFFERS_BINDINGS = P::SEPARATE_IMAGE_BUFFER_BINDINGS;
|
static constexpr bool SEPARATE_IMAGE_BUFFERS_BINDINGS = P::SEPARATE_IMAGE_BUFFER_BINDINGS;
|
||||||
static constexpr bool USE_MEMORY_MAPS_FOR_UPLOADS = P::USE_MEMORY_MAPS_FOR_UPLOADS;
|
static constexpr bool USE_MEMORY_MAPS_FOR_UPLOADS = P::USE_MEMORY_MAPS_FOR_UPLOADS;
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
static constexpr s64 DEFAULT_EXPECTED_MEMORY = 512_MiB;
|
||||||
|
static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB;
|
||||||
|
static constexpr s64 TARGET_THRESHOLD = 3_GiB;
|
||||||
|
#else
|
||||||
static constexpr s64 DEFAULT_EXPECTED_MEMORY = 512_MiB;
|
static constexpr s64 DEFAULT_EXPECTED_MEMORY = 512_MiB;
|
||||||
static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB;
|
static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB;
|
||||||
static constexpr s64 TARGET_THRESHOLD = 4_GiB;
|
static constexpr s64 TARGET_THRESHOLD = 4_GiB;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Debug Flags.
|
// Debug Flags.
|
||||||
|
|
||||||
|
@ -446,7 +456,12 @@ private:
|
||||||
Tegra::MaxwellDeviceMemoryManager& device_memory;
|
Tegra::MaxwellDeviceMemoryManager& device_memory;
|
||||||
|
|
||||||
Common::SlotVector<Buffer> slot_buffers;
|
Common::SlotVector<Buffer> slot_buffers;
|
||||||
DelayedDestructionRing<Buffer, 8> delayed_destruction_ring;
|
#ifdef ANDROID
|
||||||
|
static constexpr size_t TICKS_TO_DESTROY = 6;
|
||||||
|
#else
|
||||||
|
static constexpr size_t TICKS_TO_DESTROY = 8;
|
||||||
|
#endif
|
||||||
|
DelayedDestructionRing<Buffer, TICKS_TO_DESTROY> delayed_destruction_ring;
|
||||||
|
|
||||||
const Tegra::Engines::DrawManager::IndirectParams* current_draw_indirect{};
|
const Tegra::Engines::DrawManager::IndirectParams* current_draw_indirect{};
|
||||||
|
|
||||||
|
@ -478,6 +493,7 @@ private:
|
||||||
u64 minimum_memory = 0;
|
u64 minimum_memory = 0;
|
||||||
u64 critical_memory = 0;
|
u64 critical_memory = 0;
|
||||||
BufferId inline_buffer_id;
|
BufferId inline_buffer_id;
|
||||||
|
bool immediately_free = false;
|
||||||
|
|
||||||
std::array<BufferId, ((1ULL << 34) >> CACHING_PAGEBITS)> page_table;
|
std::array<BufferId, ((1ULL << 34) >> CACHING_PAGEBITS)> page_table;
|
||||||
Common::ScratchBuffer<u8> tmp_buffer;
|
Common::ScratchBuffer<u8> tmp_buffer;
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
@ -18,9 +21,11 @@ Host1x::~Host1x() = default;
|
||||||
void Host1x::StartDevice(s32 fd, ChannelType type, u32 syncpt) {
|
void Host1x::StartDevice(s32 fd, ChannelType type, u32 syncpt) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ChannelType::NvDec:
|
case ChannelType::NvDec:
|
||||||
|
std::call_once(nvdec_first_init, []() {std::this_thread::sleep_for(std::chrono::milliseconds{500});}); // HACK: For Astroneer
|
||||||
devices[fd] = std::make_unique<Tegra::Host1x::Nvdec>(*this, fd, syncpt, frame_queue);
|
devices[fd] = std::make_unique<Tegra::Host1x::Nvdec>(*this, fd, syncpt, frame_queue);
|
||||||
break;
|
break;
|
||||||
case ChannelType::VIC:
|
case ChannelType::VIC:
|
||||||
|
std::call_once(vic_first_init, []() {std::this_thread::sleep_for(std::chrono::milliseconds{500});}); // HACK: For Astroneer
|
||||||
devices[fd] = std::make_unique<Tegra::Host1x::Vic>(*this, fd, syncpt, frame_queue);
|
devices[fd] = std::make_unique<Tegra::Host1x::Vic>(*this, fd, syncpt, frame_queue);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
@ -201,6 +204,8 @@ private:
|
||||||
std::unique_ptr<Common::FlatAllocator<u32, 0, 32>> allocator;
|
std::unique_ptr<Common::FlatAllocator<u32, 0, 32>> allocator;
|
||||||
FrameQueue frame_queue;
|
FrameQueue frame_queue;
|
||||||
std::unordered_map<s32, std::unique_ptr<CDmaPusher>> devices;
|
std::unordered_map<s32, std::unique_ptr<CDmaPusher>> devices;
|
||||||
|
std::once_flag nvdec_first_init;
|
||||||
|
std::once_flag vic_first_init;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Tegra::Host1x
|
} // namespace Tegra::Host1x
|
||||||
|
|
|
@ -110,10 +110,17 @@ class TextureCache : public VideoCommon::ChannelSetupCaches<TextureCacheChannelI
|
||||||
|
|
||||||
static constexpr size_t UNSET_CHANNEL{std::numeric_limits<size_t>::max()};
|
static constexpr size_t UNSET_CHANNEL{std::numeric_limits<size_t>::max()};
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
static constexpr s64 TARGET_THRESHOLD = 3_GiB;
|
||||||
|
static constexpr s64 DEFAULT_EXPECTED_MEMORY = 1_GiB + 125_MiB;
|
||||||
|
static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB + 625_MiB;
|
||||||
|
static constexpr size_t GC_EMERGENCY_COUNTS = 2;
|
||||||
|
#else
|
||||||
static constexpr s64 TARGET_THRESHOLD = 4_GiB;
|
static constexpr s64 TARGET_THRESHOLD = 4_GiB;
|
||||||
static constexpr s64 DEFAULT_EXPECTED_MEMORY = 1_GiB + 125_MiB;
|
static constexpr s64 DEFAULT_EXPECTED_MEMORY = 1_GiB + 125_MiB;
|
||||||
static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB + 625_MiB;
|
static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB + 625_MiB;
|
||||||
static constexpr size_t GC_EMERGENCY_COUNTS = 2;
|
static constexpr size_t GC_EMERGENCY_COUNTS = 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
using Runtime = typename P::Runtime;
|
using Runtime = typename P::Runtime;
|
||||||
using Image = typename P::Image;
|
using Image = typename P::Image;
|
||||||
|
@ -479,7 +486,11 @@ private:
|
||||||
};
|
};
|
||||||
Common::LeastRecentlyUsedCache<LRUItemParams> lru_cache;
|
Common::LeastRecentlyUsedCache<LRUItemParams> lru_cache;
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
static constexpr size_t TICKS_TO_DESTROY = 6;
|
||||||
|
#else
|
||||||
static constexpr size_t TICKS_TO_DESTROY = 8;
|
static constexpr size_t TICKS_TO_DESTROY = 8;
|
||||||
|
#endif
|
||||||
DelayedDestructionRing<Image, TICKS_TO_DESTROY> sentenced_images;
|
DelayedDestructionRing<Image, TICKS_TO_DESTROY> sentenced_images;
|
||||||
DelayedDestructionRing<ImageView, TICKS_TO_DESTROY> sentenced_image_view;
|
DelayedDestructionRing<ImageView, TICKS_TO_DESTROY> sentenced_image_view;
|
||||||
DelayedDestructionRing<Framebuffer, TICKS_TO_DESTROY> sentenced_framebuffers;
|
DelayedDestructionRing<Framebuffer, TICKS_TO_DESTROY> sentenced_framebuffers;
|
||||||
|
|
|
@ -759,16 +759,16 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
||||||
functions.vkGetDeviceProcAddr = dld.vkGetDeviceProcAddr;
|
functions.vkGetDeviceProcAddr = dld.vkGetDeviceProcAddr;
|
||||||
|
|
||||||
VmaAllocatorCreateFlags flags = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT;
|
VmaAllocatorCreateFlags flags = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT;
|
||||||
if (extensions.memory_budget) {
|
if (extensions.memory_budget && !is_qualcomm && !is_turnip) {
|
||||||
flags |= VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT;
|
flags |= VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT;
|
||||||
}
|
}
|
||||||
const VmaAllocatorCreateInfo allocator_info{
|
const VmaAllocatorCreateInfo allocator_info{
|
||||||
.flags = flags,
|
.flags = flags,
|
||||||
.physicalDevice = physical,
|
.physicalDevice = physical,
|
||||||
.device = *logical,
|
.device = *logical,
|
||||||
.preferredLargeHeapBlockSize = is_integrated
|
.preferredLargeHeapBlockSize = (is_qualcomm || is_turnip)
|
||||||
? (64u * 1024u * 1024u)
|
? (256u * 1024u * 1024u) // Use larger blocks for Adreno GPUs
|
||||||
: (256u * 1024u * 1024u),
|
: (is_integrated ? (64u * 1024u * 1024u) : (256u * 1024u * 1024u)),
|
||||||
.pAllocationCallbacks = nullptr,
|
.pAllocationCallbacks = nullptr,
|
||||||
.pDeviceMemoryCallbacks = nullptr,
|
.pDeviceMemoryCallbacks = nullptr,
|
||||||
.pHeapSizeLimit = nullptr,
|
.pHeapSizeLimit = nullptr,
|
||||||
|
|
|
@ -196,6 +196,21 @@ namespace Vulkan {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Additional workarounds for Adreno GPUs to avoid VMA fragmentation
|
||||||
|
const bool is_adreno = (device.GetDriverID() == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
|
||||||
|
device.GetDriverID() == VK_DRIVER_ID_MESA_TURNIP);
|
||||||
|
if (is_adreno) {
|
||||||
|
using namespace Common::Literals;
|
||||||
|
for (u32 t = 0; t < properties.memoryTypeCount; ++t) {
|
||||||
|
const auto& memory_type = properties.memoryTypes[t];
|
||||||
|
const auto& heap = properties.memoryHeaps[memory_type.heapIndex];
|
||||||
|
// Skip memory types from heaps smaller than 512MB to reduce fragmentation
|
||||||
|
if (heap.size < 512_MiB) {
|
||||||
|
valid_memory_types &= ~(1u << t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryAllocator::~MemoryAllocator() = default;
|
MemoryAllocator::~MemoryAllocator() = default;
|
||||||
|
@ -253,30 +268,42 @@ namespace Vulkan {
|
||||||
|
|
||||||
MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements &reqs, MemoryUsage usage)
|
MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements &reqs, MemoryUsage usage)
|
||||||
{
|
{
|
||||||
|
// Ensure 4KB alignment for all Adreno GPUs
|
||||||
|
VkMemoryRequirements adjusted_reqs = reqs;
|
||||||
|
const bool is_adreno = (device.GetDriverID() == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
|
||||||
|
device.GetDriverID() == VK_DRIVER_ID_MESA_TURNIP);
|
||||||
|
if (is_adreno) {
|
||||||
|
adjusted_reqs.size = Common::AlignUp(reqs.size, 4096);
|
||||||
|
}
|
||||||
|
|
||||||
const auto vma_usage = MemoryUsageVma(usage);
|
const auto vma_usage = MemoryUsageVma(usage);
|
||||||
VmaAllocationCreateInfo ci{};
|
VmaAllocationCreateInfo ci{};
|
||||||
ci.flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT | MemoryUsageVmaFlags(usage);
|
ci.flags = MemoryUsageVmaFlags(usage);
|
||||||
|
// Skip budget constraints for Adreno GPUs to avoid fragmentation issues
|
||||||
|
if (!is_adreno) {
|
||||||
|
ci.flags |= VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT;
|
||||||
|
}
|
||||||
ci.usage = vma_usage;
|
ci.usage = vma_usage;
|
||||||
ci.memoryTypeBits = reqs.memoryTypeBits & valid_memory_types;
|
ci.memoryTypeBits = adjusted_reqs.memoryTypeBits & valid_memory_types;
|
||||||
ci.requiredFlags = 0;
|
ci.requiredFlags = 0;
|
||||||
ci.preferredFlags = MemoryUsagePreferredVmaFlags(usage);
|
ci.preferredFlags = MemoryUsagePreferredVmaFlags(usage);
|
||||||
|
|
||||||
VmaAllocation a{};
|
VmaAllocation a{};
|
||||||
VmaAllocationInfo info{};
|
VmaAllocationInfo info{};
|
||||||
|
|
||||||
VkResult res = vmaAllocateMemory(allocator, &reqs, &ci, &a, &info);
|
VkResult res = vmaAllocateMemory(allocator, &adjusted_reqs, &ci, &a, &info);
|
||||||
|
|
||||||
if (res != VK_SUCCESS) {
|
if (res != VK_SUCCESS) {
|
||||||
// Relax 1: drop budget constraint
|
// Relax 1: drop budget constraint
|
||||||
auto ci2 = ci;
|
auto ci2 = ci;
|
||||||
ci2.flags &= ~VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT;
|
ci2.flags &= ~VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT;
|
||||||
res = vmaAllocateMemory(allocator, &reqs, &ci2, &a, &info);
|
res = vmaAllocateMemory(allocator, &adjusted_reqs, &ci2, &a, &info);
|
||||||
|
|
||||||
// Relax 2: if we preferred DEVICE_LOCAL, drop that preference
|
// Relax 2: if we preferred DEVICE_LOCAL, drop that preference
|
||||||
if (res != VK_SUCCESS && (ci.preferredFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
|
if (res != VK_SUCCESS && (ci.preferredFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
|
||||||
auto ci3 = ci2;
|
auto ci3 = ci2;
|
||||||
ci3.preferredFlags &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
ci3.preferredFlags &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||||
res = vmaAllocateMemory(allocator, &reqs, &ci3, &a, &info);
|
res = vmaAllocateMemory(allocator, &adjusted_reqs, &ci3, &a, &info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,11 +312,16 @@ namespace Vulkan {
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryCommit MemoryAllocator::Commit(const vk::Buffer &buffer, MemoryUsage usage) {
|
MemoryCommit MemoryAllocator::Commit(const vk::Buffer &buffer, MemoryUsage usage) {
|
||||||
// Allocate memory appropriate for this buffer automatically
|
|
||||||
const auto vma_usage = MemoryUsageVma(usage);
|
const auto vma_usage = MemoryUsageVma(usage);
|
||||||
|
const bool is_adreno = (device.GetDriverID() == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
|
||||||
|
device.GetDriverID() == VK_DRIVER_ID_MESA_TURNIP);
|
||||||
|
|
||||||
VmaAllocationCreateInfo ci{};
|
VmaAllocationCreateInfo ci{};
|
||||||
ci.flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT | MemoryUsageVmaFlags(usage);
|
ci.flags = MemoryUsageVmaFlags(usage);
|
||||||
|
// Skip budget constraints for Adreno GPUs to avoid fragmentation issues
|
||||||
|
if (!is_adreno) {
|
||||||
|
ci.flags |= VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT;
|
||||||
|
}
|
||||||
ci.usage = vma_usage;
|
ci.usage = vma_usage;
|
||||||
ci.requiredFlags = 0;
|
ci.requiredFlags = 0;
|
||||||
ci.preferredFlags = MemoryUsagePreferredVmaFlags(usage);
|
ci.preferredFlags = MemoryUsagePreferredVmaFlags(usage);
|
||||||
|
@ -322,4 +354,6 @@ namespace Vulkan {
|
||||||
return MemoryCommit(allocator, a, info);
|
return MemoryCommit(allocator, a, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue