From 924f01f5833b3b3921c2fe148e08f46519d13a07 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Sat, 29 Nov 2025 18:20:54 -0400 Subject: [PATCH] [vk] BufferCache NullBuffer handling [POSSIBLE REVERT] --- .../renderer_vulkan/vk_buffer_cache.cpp | 39 +++++++++++++++---- .../renderer_vulkan/vk_buffer_cache.h | 5 +++ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 1e974223c8..62983ac78f 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp @@ -664,22 +664,41 @@ void BufferCacheRuntime::ReserveNullBuffer() { } } +VkBufferUsageFlags BufferCacheRuntime::NullBufferUsageFlags() const { + VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | + VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | + VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; + if (device.IsExtTransformFeedbackSupported()) { + usage |= VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT; + } + return usage; +} + +void BufferCacheRuntime::RefreshNullBuffer() { + if (!null_buffer) { + return; + } + scheduler.Finish(); + null_buffer.reset(); + null_buffer = CreateNullBuffer(); +} + vk::Buffer BufferCacheRuntime::CreateNullBuffer() { VkBufferCreateInfo create_info{ .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .pNext = nullptr, .flags = 0, .size = 4, - .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | - VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, + .usage = NullBufferUsageFlags(), .sharingMode = VK_SHARING_MODE_EXCLUSIVE, .queueFamilyIndexCount = 0, .pQueueFamilyIndices = nullptr, }; - if (device.IsExtTransformFeedbackSupported()) { - create_info.usage |= VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT; - } vk::Buffer ret = memory_allocator.CreateBuffer(create_info, MemoryUsage::DeviceLocal); + null_buffer_usage_flags = create_info.usage; if (device.HasDebuggingToolAttached()) { ret.SetObjectNameEXT("Null buffer"); } @@ -690,6 +709,10 @@ vk::Buffer BufferCacheRuntime::CreateNullBuffer() { }); return ret; -} - -} // namespace Vulkan + const VkBufferUsageFlags expected_usage = NullBufferUsageFlags(); + if (null_buffer && null_buffer_usage_flags != expected_usage) { + RefreshNullBuffer(); + } + if (!null_buffer) { + null_buffer = CreateNullBuffer(); + } diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h index d5d806fc69..66eb2bceb1 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.h +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h @@ -131,6 +131,9 @@ public: void BindTransformFeedbackBuffers(VideoCommon::HostBindings& bindings); + /// Forces destruction and recreation of the shared null buffer so new usage flags take effect. + void RefreshNullBuffer(); + std::span BindMappedUniformBuffer([[maybe_unused]] size_t stage, [[maybe_unused]] u32 binding_index, u32 size) { @@ -168,6 +171,7 @@ private: void ReserveNullBuffer(); vk::Buffer CreateNullBuffer(); + VkBufferUsageFlags NullBufferUsageFlags() const; const Device& device; MemoryAllocator& memory_allocator; @@ -179,6 +183,7 @@ private: std::shared_ptr quad_strip_index_buffer; vk::Buffer null_buffer; + VkBufferUsageFlags null_buffer_usage_flags = 0; std::unique_ptr uint8_pass; QuadIndexedPass quad_index_pass;