mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2025-07-20 12:55:45 +00:00
[android] Snapdragon 865 patches (#23)
Co-authored-by: Aleksandr Popovich <alekpopo@pm.me> Reviewed-on: https://git.bixed.xyz/Bix/eden/pulls/23
This commit is contained in:
parent
0ce2ec3b36
commit
444109c251
10 changed files with 97 additions and 11 deletions
|
@ -1,11 +1,21 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2015 Citra Emulator Project
|
// SPDX-FileCopyrightText: 2015 Citra Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Uncomment this to disable microprofile. This will get you cleaner profiles when using
|
// Use this to disable microprofile. This will get you cleaner profiles when using
|
||||||
// external sampling profilers like "Very Sleepy", and will improve performance somewhat.
|
// external sampling profilers like "Very Sleepy", and will improve performance somewhat.
|
||||||
// #define MICROPROFILE_ENABLED 0
|
#ifdef ANDROID
|
||||||
|
#define MICROPROFILE_ENABLED 0
|
||||||
|
#define MICROPROFILEUI_ENABLED 0
|
||||||
|
#define MicroProfileOnThreadExit() do{}while(0)
|
||||||
|
#define MICROPROFILE_TOKEN(x) 0
|
||||||
|
#define MicroProfileEnter(x) 0
|
||||||
|
#define MicroProfileLeave(x, y) ignore_all(x, y)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Customized Citra settings.
|
// Customized Citra settings.
|
||||||
// This file wraps the MicroProfile header so that these are consistent everywhere.
|
// This file wraps the MicroProfile header so that these are consistent everywhere.
|
||||||
|
@ -19,6 +29,12 @@
|
||||||
typedef void* HANDLE;
|
typedef void* HANDLE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
template <typename... Args>
|
||||||
|
void ignore_all(Args&&... args) {
|
||||||
|
(static_cast<void>(std::ignore = args), ...);
|
||||||
|
}
|
||||||
|
|
||||||
#include <microprofile.h>
|
#include <microprofile.h>
|
||||||
|
|
||||||
#define MP_RGB(r, g, b) ((r) << 16 | (g) << 8 | (b) << 0)
|
#define MP_RGB(r, g, b) ((r) << 16 | (g) << 8 | (b) << 0)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
|
#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
namespace Shader::Maxwell {
|
namespace Shader::Maxwell {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -36,6 +37,17 @@ enum class ShuffleMode : u64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsKONA() {
|
||||||
|
std::ifstream machineFile("/sys/devices/soc0/machine");
|
||||||
|
if (machineFile.is_open()) {
|
||||||
|
std::string line;
|
||||||
|
std::getline(machineFile, line);
|
||||||
|
if (line == "KONA")
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Shuffle(TranslatorVisitor& v, u64 insn, const IR::U32& index, const IR::U32& mask) {
|
void Shuffle(TranslatorVisitor& v, u64 insn, const IR::U32& index, const IR::U32& mask) {
|
||||||
union {
|
union {
|
||||||
u64 insn;
|
u64 insn;
|
||||||
|
@ -47,6 +59,9 @@ void Shuffle(TranslatorVisitor& v, u64 insn, const IR::U32& index, const IR::U32
|
||||||
|
|
||||||
const IR::U32 result{ShuffleOperation(v.ir, v.X(shfl.src_reg), index, mask, shfl.mode)};
|
const IR::U32 result{ShuffleOperation(v.ir, v.X(shfl.src_reg), index, mask, shfl.mode)};
|
||||||
v.ir.SetPred(shfl.pred, v.ir.GetInBoundsFromOp(result));
|
v.ir.SetPred(shfl.pred, v.ir.GetInBoundsFromOp(result));
|
||||||
|
if (IsKONA())
|
||||||
|
v.X(shfl.dest_reg, v.ir.Imm32(0xffffffff)); // This fixes the freeze for Retroid / Snapdragon SD865
|
||||||
|
else
|
||||||
v.X(shfl.dest_reg, result);
|
v.X(shfl.dest_reg, result);
|
||||||
}
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -1383,6 +1385,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1674,6 +1678,8 @@ void BufferCache<P>::DeleteBuffer(BufferId buffer_id, bool do_not_mark) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Unregister(buffer_id);
|
Unregister(buffer_id);
|
||||||
|
|
||||||
|
if (!do_not_mark || !immediately_free)
|
||||||
delayed_destruction_ring.Push(std::move(slot_buffers[buffer_id]));
|
delayed_destruction_ring.Push(std::move(slot_buffers[buffer_id]));
|
||||||
slot_buffers.erase(buffer_id);
|
slot_buffers.erase(buffer_id);
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,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;
|
||||||
|
@ -173,9 +177,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.
|
||||||
|
|
||||||
|
@ -451,7 +461,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{};
|
||||||
|
|
||||||
|
@ -483,6 +498,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;
|
||||||
|
|
|
@ -271,7 +271,10 @@ vk::Buffer MemoryAllocator::CreateBuffer(const VkBufferCreateInfo& ci, MemoryUsa
|
||||||
VmaAllocation allocation{};
|
VmaAllocation allocation{};
|
||||||
VkMemoryPropertyFlags property_flags{};
|
VkMemoryPropertyFlags property_flags{};
|
||||||
|
|
||||||
vk::Check(vmaCreateBuffer(allocator, &ci, &alloc_ci, &handle, &allocation, &alloc_info));
|
VkResult result = vmaCreateBuffer(allocator, &ci, &alloc_ci, &handle, &allocation, &alloc_info);
|
||||||
|
if (result == VK_ERROR_OUT_OF_DEVICE_MEMORY) {
|
||||||
|
LOG_ERROR(Render_Vulkan, "Out of memory creating buffer (size: {})", ci.size);
|
||||||
|
}
|
||||||
vmaGetAllocationMemoryProperties(allocator, allocation, &property_flags);
|
vmaGetAllocationMemoryProperties(allocator, allocation, &property_flags);
|
||||||
|
|
||||||
u8* data = reinterpret_cast<u8*>(alloc_info.pMappedData);
|
u8* data = reinterpret_cast<u8*>(alloc_info.pMappedData);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue