From 7986ee58de0286e7b1cf08d1d2a449b896b5a888 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 24 Nov 2025 23:39:56 +0300 Subject: [PATCH] vk: Allow buffer creation to fail gracefully if placement is not possible --- rpcs3/Emu/RSX/VK/vkutils/buffer_object.cpp | 27 ++++++++++++++++++---- rpcs3/Emu/RSX/VK/vkutils/buffer_object.h | 24 +++++++++++++++++-- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/vkutils/buffer_object.cpp b/rpcs3/Emu/RSX/VK/vkutils/buffer_object.cpp index 4d7c5237cc..daf60ad03c 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/buffer_object.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/buffer_object.cpp @@ -39,11 +39,20 @@ namespace vk return false; } - buffer::buffer(const vk::render_device& dev, u64 size, const memory_type_info& memory_type, u32 access_flags, VkBufferUsageFlags usage, VkBufferCreateFlags flags, vmm_allocation_pool allocation_pool) + buffer::buffer( + const vk::render_device& dev, + u64 size, + const memory_type_info& memory_type, + u32 access_flags, + VkBufferUsageFlags usage, + VkBufferCreateFlags flags, + vmm_allocation_pool allocation_pool) : m_device(dev) { + const bool nullable = !!(flags & VK_BUFFER_CREATE_ALLOW_NULL_RPCS3); + info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - info.flags = flags; + info.flags = flags & ~VK_BUFFER_CREATE_SPECIAL_FLAGS_RPCS3; info.size = size; info.usage = usage; info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; @@ -60,8 +69,18 @@ namespace vk fmt::throw_exception("No compatible memory type was found!"); } - memory = std::make_unique(m_device, memory_reqs.size, memory_reqs.alignment, allocation_type_info, allocation_pool); - vkBindBufferMemory(dev, value, memory->get_vk_device_memory(), memory->get_vk_device_memory_offset()); + memory = std::make_unique(m_device, memory_reqs.size, memory_reqs.alignment, allocation_type_info, allocation_pool, nullable); + if (auto device_memory = memory->get_vk_device_memory(); + device_memory != VK_NULL_HANDLE) + { + vkBindBufferMemory(dev, value, device_memory, memory->get_vk_device_memory_offset()); + } + else + { + ensure(nullable); + vkDestroyBuffer(m_device, value, nullptr); + value = VK_NULL_HANDLE; + } } buffer::buffer(const vk::render_device& dev, VkBufferUsageFlags usage, void* host_pointer, u64 size) diff --git a/rpcs3/Emu/RSX/VK/vkutils/buffer_object.h b/rpcs3/Emu/RSX/VK/vkutils/buffer_object.h index c74cb1aaa5..ba5309749a 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/buffer_object.h +++ b/rpcs3/Emu/RSX/VK/vkutils/buffer_object.h @@ -7,6 +7,13 @@ namespace vk { + enum : u32 + { + VK_BUFFER_CREATE_ALLOW_NULL_RPCS3 = 0x80000000, + + VK_BUFFER_CREATE_SPECIAL_FLAGS_RPCS3 = (VK_BUFFER_CREATE_ALLOW_NULL_RPCS3) + }; + struct buffer_view : public unique_resource { VkBufferView value; @@ -30,8 +37,21 @@ namespace vk VkBufferCreateInfo info = {}; std::unique_ptr memory; - buffer(const vk::render_device& dev, u64 size, const memory_type_info& memory_type, u32 access_flags, VkBufferUsageFlags usage, VkBufferCreateFlags flags, vmm_allocation_pool allocation_pool); - buffer(const vk::render_device& dev, VkBufferUsageFlags usage, void* host_pointer, u64 size); + buffer( + const vk::render_device& dev, + u64 size, + const memory_type_info& memory_type, + u32 access_flags, + VkBufferUsageFlags usage, + VkBufferCreateFlags flags, + vmm_allocation_pool allocation_pool); + + buffer( + const vk::render_device& dev, + VkBufferUsageFlags usage, + void* host_pointer, + u64 size); + ~buffer(); void* map(u64 offset, u64 size);