mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-05 20:04:13 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4bdda1b7ff | |||
| 320618c000 | |||
| cbdd2d64ee | |||
| 92bc82769e | |||
| f6e7686038 |
Vendored
+1
@@ -11,6 +11,7 @@
|
||||
#include <limits>
|
||||
#include <span>
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <time.h>
|
||||
|
||||
namespace Tz {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <string_view>
|
||||
#ifdef _WIN32
|
||||
#include <llvm/Demangle/Demangle.h>
|
||||
|
||||
@@ -148,11 +148,11 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_,
|
||||
}
|
||||
|
||||
StagingBufferMap BufferCacheRuntime::UploadStagingBuffer(size_t size) {
|
||||
return staging_buffer_pool.RequestUploadBuffer(device, size);
|
||||
return staging_buffer_pool.RequestUploadBuffer(size);
|
||||
}
|
||||
|
||||
StagingBufferMap BufferCacheRuntime::DownloadStagingBuffer(size_t size, bool deferred) {
|
||||
return staging_buffer_pool.RequestDownloadBuffer(device, size, deferred);
|
||||
return staging_buffer_pool.RequestDownloadBuffer(size, deferred);
|
||||
}
|
||||
|
||||
void BufferCacheRuntime::FreeDeferredStagingBuffer(StagingBufferMap& buffer) {
|
||||
|
||||
@@ -557,11 +557,11 @@ void TextureCacheRuntime::Finish() {
|
||||
}
|
||||
|
||||
StagingBufferMap TextureCacheRuntime::UploadStagingBuffer(size_t size, bool deferred) {
|
||||
return staging_buffer_pool.RequestUploadBuffer(device, size);
|
||||
return staging_buffer_pool.RequestUploadBuffer(size);
|
||||
}
|
||||
|
||||
StagingBufferMap TextureCacheRuntime::DownloadStagingBuffer(size_t size, bool deferred) {
|
||||
return staging_buffer_pool.RequestDownloadBuffer(device, size, deferred);
|
||||
return staging_buffer_pool.RequestDownloadBuffer(size, deferred);
|
||||
}
|
||||
|
||||
void TextureCacheRuntime::FreeDeferredStagingBuffer(StagingBufferMap& buffer) {
|
||||
|
||||
@@ -192,7 +192,7 @@ public:
|
||||
if (host_visible) {
|
||||
return StagingBufferRef{};
|
||||
}
|
||||
return staging_pool.Request(device, size_bytes, MemoryUsage::Upload);
|
||||
return staging_pool.Request(size_bytes, MemoryUsage::Upload);
|
||||
}();
|
||||
|
||||
u8* staging_data = host_visible ? buffer.Mapped().data() : staging.mapped_span.data();
|
||||
@@ -366,11 +366,11 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_, MemoryAllocator& m
|
||||
}
|
||||
|
||||
StagingBufferRef BufferCacheRuntime::UploadStagingBuffer(size_t size) {
|
||||
return staging_pool.Request(device, size, MemoryUsage::Upload);
|
||||
return staging_pool.Request(size, MemoryUsage::Upload);
|
||||
}
|
||||
|
||||
StagingBufferRef BufferCacheRuntime::DownloadStagingBuffer(size_t size, bool deferred) {
|
||||
return staging_pool.Request(device, size, MemoryUsage::Download, deferred);
|
||||
return staging_pool.Request(size, MemoryUsage::Download, deferred);
|
||||
}
|
||||
|
||||
VkFormat BufferCacheRuntime::TexelBufferFormat(VideoCore::Surface::PixelFormat format) const {
|
||||
|
||||
@@ -149,7 +149,7 @@ public:
|
||||
std::span<u8> BindMappedUniformBuffer([[maybe_unused]] size_t stage,
|
||||
[[maybe_unused]] u32 binding_index,
|
||||
u32 size) {
|
||||
const StagingBufferRef ref = staging_pool.Request(device, size, MemoryUsage::Upload);
|
||||
const StagingBufferRef ref = staging_pool.Request(size, MemoryUsage::Upload);
|
||||
guest_descriptor_queue.AddBuffer(ref.buffer, ref.device_address,
|
||||
static_cast<u32>(ref.offset), size);
|
||||
return ref.mapped_span;
|
||||
|
||||
@@ -287,7 +287,7 @@ Uint8Pass::~Uint8Pass() = default;
|
||||
std::pair<VkBuffer, VkDeviceSize> Uint8Pass::Assemble(u32 num_vertices, VkBuffer src_buffer,
|
||||
u32 src_offset) {
|
||||
const u32 staging_size = static_cast<u32>(num_vertices * sizeof(u16));
|
||||
const auto staging = staging_buffer_pool.Request(device, staging_size, MemoryUsage::DeviceLocal);
|
||||
const auto staging = staging_buffer_pool.Request(staging_size, MemoryUsage::DeviceLocal);
|
||||
|
||||
compute_pass_descriptor_queue.Acquire(scheduler, 2);
|
||||
compute_pass_descriptor_queue.AddBuffer(src_buffer, src_offset, num_vertices);
|
||||
@@ -345,7 +345,7 @@ std::pair<VkBuffer, VkDeviceSize> QuadIndexedPass::Assemble(
|
||||
const u32 num_tri_vertices = (is_strip ? (num_vertices - 2) / 2 : num_vertices / 4) * 6;
|
||||
|
||||
const std::size_t staging_size = num_tri_vertices * sizeof(u32);
|
||||
const auto staging = staging_buffer_pool.Request(device, staging_size, MemoryUsage::DeviceLocal);
|
||||
const auto staging = staging_buffer_pool.Request(staging_size, MemoryUsage::DeviceLocal);
|
||||
|
||||
compute_pass_descriptor_queue.Acquire(scheduler, 2);
|
||||
compute_pass_descriptor_queue.AddBuffer(src_buffer, src_offset, input_size);
|
||||
|
||||
@@ -852,7 +852,7 @@ public:
|
||||
|
||||
void PushUnsyncedQueries() override {
|
||||
CloseCounter();
|
||||
auto staging_ref = staging_pool.Request(device,
|
||||
auto staging_ref = staging_pool.Request(
|
||||
pending_flush_queries.size() * TFBQueryBank::QUERY_SIZE, MemoryUsage::Download, true);
|
||||
size_t offset_base = staging_ref.offset;
|
||||
for (auto q : pending_flush_queries) {
|
||||
@@ -1657,7 +1657,7 @@ void QueryCacheRuntime::SyncValues(std::span<SyncValuesType> values, VkBuffer ba
|
||||
impl->copies_setup.clear();
|
||||
impl->copies_setup.resize(impl->little_cache.size());
|
||||
if constexpr (SyncValuesType::GeneratesBaseBuffer) {
|
||||
ref = impl->staging_pool.Request(impl->device, total_size, MemoryUsage::Upload);
|
||||
ref = impl->staging_pool.Request(total_size, MemoryUsage::Upload);
|
||||
size_t current_offset = ref.offset;
|
||||
size_t accumulated_size = 0;
|
||||
for (size_t i = 0; i < values.size(); i++) {
|
||||
|
||||
@@ -25,14 +25,29 @@ namespace {
|
||||
|
||||
using namespace Common::Literals;
|
||||
|
||||
size_t GetStreamBufferSize(const Device& device, size_t max_stream_buffer_size, size_t max_alignment) {
|
||||
// Maximum potential alignment of a Vulkan buffer
|
||||
constexpr VkDeviceSize MAX_ALIGNMENT = 256;
|
||||
|
||||
// Stream buffer size in bytes
|
||||
// *NIX drivers are more sensitive to increased buffers for streaming.
|
||||
// Windows ones however, can intake bigger buffers and generally do not OOM.
|
||||
// - GTX 960 on Windows will not OOM with 256mib
|
||||
// - GT 1030 on ^NIX will OOM with 256mib
|
||||
#if defined(__FreeBSD__)
|
||||
constexpr VkDeviceSize MAX_STREAM_BUFFER_SIZE = 128_MiB;
|
||||
#else
|
||||
constexpr VkDeviceSize MAX_STREAM_BUFFER_SIZE = 256_MiB;
|
||||
#endif
|
||||
|
||||
size_t GetStreamBufferSize(const Device& device) {
|
||||
if (!device.HasDebuggingToolAttached()) {
|
||||
return max_stream_buffer_size;
|
||||
return MAX_STREAM_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
VkDeviceSize size{0};
|
||||
bool has_device_local_host_visible_heap{};
|
||||
ForEachDeviceLocalHostVisibleHeap(device, [&size, &has_device_local_host_visible_heap](size_t index, VkMemoryHeap& heap) {
|
||||
ForEachDeviceLocalHostVisibleHeap(device, [&size, &has_device_local_host_visible_heap](
|
||||
size_t index, VkMemoryHeap& heap) {
|
||||
has_device_local_host_visible_heap = true;
|
||||
size = (std::max)(size, heap.size);
|
||||
});
|
||||
@@ -40,27 +55,28 @@ size_t GetStreamBufferSize(const Device& device, size_t max_stream_buffer_size,
|
||||
// If rebar is not supported, cut the max heap size to 40%. This will allow 2 captures to be
|
||||
// loaded at the same time in RenderDoc. If rebar is supported, this shouldn't be an issue
|
||||
// as the heap will be much larger.
|
||||
if (size <= max_stream_buffer_size) {
|
||||
if (size <= MAX_STREAM_BUFFER_SIZE) {
|
||||
size = size * 40 / 100;
|
||||
}
|
||||
} else {
|
||||
size = max_stream_buffer_size;
|
||||
size = MAX_STREAM_BUFFER_SIZE;
|
||||
}
|
||||
return (std::min)(Common::AlignUp(size, max_alignment), max_stream_buffer_size);
|
||||
return (std::min)(Common::AlignUp(size, MAX_ALIGNMENT), MAX_STREAM_BUFFER_SIZE);
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
StagingBufferPool::StagingBufferPool(const Device& device, MemoryAllocator& memory_allocator_, Scheduler& scheduler_)
|
||||
: memory_allocator{memory_allocator_}, scheduler{scheduler_}
|
||||
, stream_buffer_size{GetStreamBufferSize(device, 256_MiB, 256)}
|
||||
{
|
||||
StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& memory_allocator_,
|
||||
Scheduler& scheduler_)
|
||||
: device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_},
|
||||
stream_buffer_size{GetStreamBufferSize(device)}, region_size{stream_buffer_size /
|
||||
StagingBufferPool::NUM_SYNCS} {
|
||||
VkBufferCreateInfo stream_ci = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.size = stream_buffer_size,
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
|
||||
| VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.queueFamilyIndexCount = 0,
|
||||
.pQueueFamilyIndices = nullptr,
|
||||
@@ -71,20 +87,7 @@ StagingBufferPool::StagingBufferPool(const Device& device, MemoryAllocator& memo
|
||||
if (device.IsBufferDeviceAddressSupported()) {
|
||||
stream_ci.usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
|
||||
}
|
||||
// *BSD drivers are more sensitive to increased buffers for streaming.
|
||||
// Windows ones however, can intake bigger buffers and generally do not OOM.
|
||||
// - GTX 960 on Windows will not OOM with 256mib
|
||||
// - GT 1030 on ^BSD will OOM with 256mib
|
||||
// This doesn't seem to be, however, universally true
|
||||
try {
|
||||
stream_buffer = memory_allocator.CreateBuffer(stream_ci, MemoryUsage::Stream);
|
||||
} catch (vk::Exception& e) {
|
||||
LOG_ERROR(Render_Vulkan, "Can't fit {} bytes buffer, halving", stream_ci.size);
|
||||
stream_buffer_size = GetStreamBufferSize(device, 128_MiB, 256);
|
||||
stream_ci.size = stream_buffer_size;
|
||||
stream_buffer = memory_allocator.CreateBuffer(stream_ci, MemoryUsage::Stream);
|
||||
}
|
||||
region_size = stream_buffer_size / StagingBufferPool::NUM_SYNCS;
|
||||
stream_buffer = memory_allocator.CreateBuffer(stream_ci, MemoryUsage::Stream);
|
||||
if (device.HasDebuggingToolAttached()) {
|
||||
stream_buffer.SetObjectNameEXT("Stream Buffer");
|
||||
}
|
||||
@@ -97,10 +100,11 @@ StagingBufferPool::StagingBufferPool(const Device& device, MemoryAllocator& memo
|
||||
|
||||
StagingBufferPool::~StagingBufferPool() = default;
|
||||
|
||||
StagingBufferRef StagingBufferPool::Request(const Device& device, size_t size, MemoryUsage usage, bool deferred) {
|
||||
return (!deferred && usage == MemoryUsage::Upload && size <= region_size)
|
||||
? GetStreamBuffer(device, size)
|
||||
: GetStagingBuffer(device, size, usage, deferred);
|
||||
StagingBufferRef StagingBufferPool::Request(size_t size, MemoryUsage usage, bool deferred) {
|
||||
if (!deferred && usage == MemoryUsage::Upload && size <= region_size) {
|
||||
return GetStreamBuffer(size);
|
||||
}
|
||||
return GetStagingBuffer(size, usage, deferred);
|
||||
}
|
||||
|
||||
void StagingBufferPool::FreeDeferred(StagingBufferRef& ref) {
|
||||
@@ -123,10 +127,11 @@ void StagingBufferPool::TickFrame() {
|
||||
ReleaseCache(MemoryUsage::Download);
|
||||
}
|
||||
|
||||
StagingBufferRef StagingBufferPool::GetStreamBuffer(const Device& device, size_t size) {
|
||||
if (AreRegionsActive(Region(free_iterator) + 1, (std::min)(Region(iterator + size) + 1, NUM_SYNCS))) {
|
||||
StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) {
|
||||
if (AreRegionsActive(Region(free_iterator) + 1,
|
||||
(std::min)(Region(iterator + size) + 1, NUM_SYNCS))) {
|
||||
// Avoid waiting for the previous usages to be free
|
||||
return GetStagingBuffer(device, size, MemoryUsage::Upload);
|
||||
return GetStagingBuffer(size, MemoryUsage::Upload);
|
||||
}
|
||||
const u64 current_tick = scheduler.CurrentTick();
|
||||
std::fill(sync_ticks.begin() + Region(used_iterator), sync_ticks.begin() + Region(iterator),
|
||||
@@ -135,14 +140,15 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(const Device& device, size_t
|
||||
free_iterator = (std::max)(free_iterator, iterator + size);
|
||||
|
||||
if (iterator + size >= stream_buffer_size) {
|
||||
std::fill(sync_ticks.begin() + Region(used_iterator), sync_ticks.begin() + NUM_SYNCS, current_tick);
|
||||
std::fill(sync_ticks.begin() + Region(used_iterator), sync_ticks.begin() + NUM_SYNCS,
|
||||
current_tick);
|
||||
used_iterator = 0;
|
||||
iterator = 0;
|
||||
free_iterator = size;
|
||||
|
||||
if (AreRegionsActive(0, Region(size) + 1)) {
|
||||
// Avoid waiting for the previous usages to be free
|
||||
return GetStagingBuffer(device, size, MemoryUsage::Upload);
|
||||
return GetStagingBuffer(size, MemoryUsage::Upload);
|
||||
}
|
||||
}
|
||||
const size_t offset = iterator;
|
||||
@@ -150,7 +156,7 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(const Device& device, size_t
|
||||
return StagingBufferRef{
|
||||
.buffer = *stream_buffer,
|
||||
.device_address = stream_buffer_address,
|
||||
.offset = VkDeviceSize(offset),
|
||||
.offset = static_cast<VkDeviceSize>(offset),
|
||||
.mapped_span = stream_pointer.subspan(offset, size),
|
||||
.usage{},
|
||||
.log2_level{},
|
||||
@@ -160,18 +166,21 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(const Device& device, size_t
|
||||
|
||||
bool StagingBufferPool::AreRegionsActive(size_t region_begin, size_t region_end) const {
|
||||
const u64 gpu_tick = scheduler.GetMasterSemaphore().KnownGpuTick();
|
||||
return std::any_of(sync_ticks.begin() + region_begin, sync_ticks.begin() + region_end, [gpu_tick](u64 sync_tick) {
|
||||
return gpu_tick < sync_tick;
|
||||
});
|
||||
return std::any_of(sync_ticks.begin() + region_begin, sync_ticks.begin() + region_end,
|
||||
[gpu_tick](u64 sync_tick) { return gpu_tick < sync_tick; });
|
||||
};
|
||||
|
||||
StagingBufferRef StagingBufferPool::GetStagingBuffer(const Device& device, size_t size, MemoryUsage usage, bool deferred) {
|
||||
if (const std::optional<StagingBufferRef> ref = TryGetReservedBuffer(size, usage, deferred))
|
||||
StagingBufferRef StagingBufferPool::GetStagingBuffer(size_t size, MemoryUsage usage,
|
||||
bool deferred) {
|
||||
if (const std::optional<StagingBufferRef> ref = TryGetReservedBuffer(size, usage, deferred)) {
|
||||
return *ref;
|
||||
return CreateStagingBuffer(device, size, usage, deferred);
|
||||
}
|
||||
return CreateStagingBuffer(size, usage, deferred);
|
||||
}
|
||||
|
||||
std::optional<StagingBufferRef> StagingBufferPool::TryGetReservedBuffer(size_t size, MemoryUsage usage, bool deferred) {
|
||||
std::optional<StagingBufferRef> StagingBufferPool::TryGetReservedBuffer(size_t size,
|
||||
MemoryUsage usage,
|
||||
bool deferred) {
|
||||
StagingBuffers& cache_level = GetCache(usage)[Common::Log2Ceil(size)];
|
||||
|
||||
const auto is_free = [this](const StagingBuffer& entry) {
|
||||
@@ -193,7 +202,7 @@ std::optional<StagingBufferRef> StagingBufferPool::TryGetReservedBuffer(size_t s
|
||||
return it->Ref();
|
||||
}
|
||||
|
||||
StagingBufferRef StagingBufferPool::CreateStagingBuffer(const Device& device, size_t size, MemoryUsage usage, bool deferred) {
|
||||
StagingBufferRef StagingBufferPool::CreateStagingBuffer(size_t size, MemoryUsage usage, bool deferred) {
|
||||
auto const log2_size = Common::Log2Ceil<u32>(u32(size));
|
||||
VkBufferCreateInfo buffer_ci = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
|
||||
@@ -33,10 +33,11 @@ class StagingBufferPool {
|
||||
public:
|
||||
static constexpr size_t NUM_SYNCS = 16;
|
||||
|
||||
explicit StagingBufferPool(const Device& device, MemoryAllocator& memory_allocator, Scheduler& scheduler);
|
||||
explicit StagingBufferPool(const Device& device, MemoryAllocator& memory_allocator,
|
||||
Scheduler& scheduler);
|
||||
~StagingBufferPool();
|
||||
|
||||
StagingBufferRef Request(const Device& device, size_t size, MemoryUsage usage, bool deferred = false);
|
||||
StagingBufferRef Request(size_t size, MemoryUsage usage, bool deferred = false);
|
||||
void FreeDeferred(StagingBufferRef& ref);
|
||||
|
||||
[[nodiscard]] VkBuffer StreamBuf() const noexcept {
|
||||
@@ -83,18 +84,27 @@ private:
|
||||
static constexpr size_t NUM_LEVELS = sizeof(size_t) * CHAR_BIT;
|
||||
using StagingBuffersCache = std::array<StagingBuffers, NUM_LEVELS>;
|
||||
|
||||
StagingBufferRef GetStreamBuffer(const Device& device, size_t size);
|
||||
StagingBufferRef GetStreamBuffer(size_t size);
|
||||
|
||||
bool AreRegionsActive(size_t region_begin, size_t region_end) const;
|
||||
StagingBufferRef GetStagingBuffer(const Device& device, size_t size, MemoryUsage usage, bool deferred = false);
|
||||
std::optional<StagingBufferRef> TryGetReservedBuffer(size_t size, MemoryUsage usage, bool deferred);
|
||||
StagingBufferRef CreateStagingBuffer(const Device& device, size_t size, MemoryUsage usage, bool deferred);
|
||||
|
||||
StagingBufferRef GetStagingBuffer(size_t size, MemoryUsage usage, bool deferred = false);
|
||||
|
||||
std::optional<StagingBufferRef> TryGetReservedBuffer(size_t size, MemoryUsage usage,
|
||||
bool deferred);
|
||||
|
||||
StagingBufferRef CreateStagingBuffer(size_t size, MemoryUsage usage, bool deferred);
|
||||
|
||||
StagingBuffersCache& GetCache(MemoryUsage usage);
|
||||
|
||||
void ReleaseCache(MemoryUsage usage);
|
||||
|
||||
void ReleaseLevel(StagingBuffersCache& cache, size_t log2);
|
||||
size_t Region(size_t iter) const noexcept {
|
||||
return iter / region_size;
|
||||
}
|
||||
|
||||
const Device& device;
|
||||
MemoryAllocator& memory_allocator;
|
||||
Scheduler& scheduler;
|
||||
|
||||
|
||||
@@ -975,11 +975,11 @@ void TextureCacheRuntime::Finish() {
|
||||
}
|
||||
|
||||
StagingBufferRef TextureCacheRuntime::UploadStagingBuffer(size_t size, bool deferred) {
|
||||
return staging_buffer_pool.Request(device, size, MemoryUsage::Upload, deferred);
|
||||
return staging_buffer_pool.Request(size, MemoryUsage::Upload, deferred);
|
||||
}
|
||||
|
||||
StagingBufferRef TextureCacheRuntime::DownloadStagingBuffer(size_t size, bool deferred) {
|
||||
return staging_buffer_pool.Request(device, size, MemoryUsage::Download, deferred);
|
||||
return staging_buffer_pool.Request(size, MemoryUsage::Download, deferred);
|
||||
}
|
||||
|
||||
void TextureCacheRuntime::FreeDeferredStagingBuffer(StagingBufferRef& ref) {
|
||||
|
||||
@@ -459,8 +459,20 @@ Instance Instance::Create(u32 version, Span<const char*> layers, Span<const char
|
||||
#else
|
||||
constexpr VkFlags ci_flags{};
|
||||
#endif
|
||||
// DO NOT TOUCH, breaks RNDA3!!
|
||||
// Don't know why, but gloom + yellow line glitch appears
|
||||
// DO NOT TOUCH OR CHANGE THE ENGINE NAME/APPLICATION NAME, breaks RNDA3!!
|
||||
// AMD drivers have fixes for Yuzu
|
||||
// if remove => gloom + yellow line glitch appears
|
||||
#ifdef __ANDROID__
|
||||
const VkApplicationInfo application_info{
|
||||
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||
.pNext = nullptr,
|
||||
.pApplicationName = "PUBGMobile",
|
||||
.applicationVersion = VK_MAKE_VERSION(1, 7, 0),
|
||||
.pEngineName = "UnrealEngine",
|
||||
.engineVersion = VK_MAKE_VERSION(4, 23, 0),
|
||||
.apiVersion = VK_API_VERSION_1_3,
|
||||
};
|
||||
#else
|
||||
const VkApplicationInfo application_info{
|
||||
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -470,6 +482,7 @@ Instance Instance::Create(u32 version, Span<const char*> layers, Span<const char
|
||||
.engineVersion = VK_MAKE_VERSION(1, 3, 0),
|
||||
.apiVersion = VK_API_VERSION_1_3,
|
||||
};
|
||||
#endif
|
||||
const VkInstanceCreateInfo ci{
|
||||
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
|
||||
Reference in New Issue
Block a user