summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-01-17 03:16:15 -0300
committerGravatar ReinUsesLisp2021-02-13 02:17:24 -0300
commita02b4e1df662dcc2d2edd7712539eabf2eef5d89 (patch)
tree6311228f312d4d22a9776587a0bd8af5bbeff328 /src
parentvk_staging_buffer_pool: Add stream buffer for small uploads (diff)
downloadyuzu-a02b4e1df662dcc2d2edd7712539eabf2eef5d89.tar.gz
yuzu-a02b4e1df662dcc2d2edd7712539eabf2eef5d89.tar.xz
yuzu-a02b4e1df662dcc2d2edd7712539eabf2eef5d89.zip
buffer_cache: Skip cache on small uploads on Vulkan
Ports from OpenGL the optimization to skip small 3D uniform buffer uploads. This will take advantage of the previously introduced stream buffer. Fixes instances where the staging buffer offset was being ignored.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h17
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.h7
-rw-r--r--src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp3
3 files changed, 18 insertions, 9 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index d6399bf24..bd8507610 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -660,24 +660,25 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
660 const VAddr cpu_addr = binding.cpu_addr; 660 const VAddr cpu_addr = binding.cpu_addr;
661 const u32 size = binding.size; 661 const u32 size = binding.size;
662 Buffer& buffer = slot_buffers[binding.buffer_id]; 662 Buffer& buffer = slot_buffers[binding.buffer_id];
663 if constexpr (IS_OPENGL) { 663 if (size <= SKIP_CACHE_SIZE && !buffer.IsRegionGpuModified(cpu_addr, size)) {
664 if (size <= SKIP_CACHE_SIZE && !buffer.IsRegionGpuModified(cpu_addr, size)) { 664 if constexpr (IS_OPENGL) {
665 if (runtime.HasFastBufferSubData()) { 665 if (runtime.HasFastBufferSubData()) {
666 // Fast path for Nvidia 666 // Fast path for Nvidia
667 if (!HasFastUniformBufferBound(stage, binding_index)) { 667 if (!HasFastUniformBufferBound(stage, binding_index)) {
668 // We only have to bind when the currently bound buffer is not the fast version 668 // We only have to bind when the currently bound buffer is not the fast version
669 fast_bound_uniform_buffers[stage] |= 1U << binding_index;
670 runtime.BindFastUniformBuffer(stage, binding_index, size); 669 runtime.BindFastUniformBuffer(stage, binding_index, size);
671 } 670 }
672 const auto span = ImmediateBufferWithData(cpu_addr, size); 671 const auto span = ImmediateBufferWithData(cpu_addr, size);
673 runtime.PushFastUniformBuffer(stage, binding_index, span); 672 runtime.PushFastUniformBuffer(stage, binding_index, span);
674 } else { 673 return;
675 // Stream buffer path to avoid stalling on non-Nvidia drivers
676 const auto span = runtime.BindMappedUniformBuffer(stage, binding_index, size);
677 cpu_memory.ReadBlockUnsafe(cpu_addr, span.data(), size);
678 } 674 }
679 return;
680 } 675 }
676 fast_bound_uniform_buffers[stage] |= 1U << binding_index;
677
678 // Stream buffer path to avoid stalling on non-Nvidia drivers or Vulkan
679 const std::span<u8> span = runtime.BindMappedUniformBuffer(stage, binding_index, size);
680 cpu_memory.ReadBlockUnsafe(cpu_addr, span.data(), size);
681 return;
681 } 682 }
682 // Classic cached path 683 // Classic cached path
683 SynchronizeBuffer(buffer, cpu_addr, size); 684 SynchronizeBuffer(buffer, cpu_addr, size);
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h
index d232e1f2d..7ff7e0d55 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.h
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h
@@ -69,6 +69,13 @@ public:
69 69
70 void BindTransformFeedbackBuffer(u32 index, VkBuffer buffer, u32 offset, u32 size); 70 void BindTransformFeedbackBuffer(u32 index, VkBuffer buffer, u32 offset, u32 size);
71 71
72 std::span<u8> BindMappedUniformBuffer([[maybe_unused]] size_t stage,
73 [[maybe_unused]] u32 binding_index, u32 size) {
74 const StagingBufferRef ref = staging_pool.Request(size, MemoryUsage::Upload);
75 BindBuffer(ref.buffer, static_cast<u32>(ref.offset), size);
76 return ref.mapped_span;
77 }
78
72 void BindUniformBuffer(VkBuffer buffer, u32 offset, u32 size) { 79 void BindUniformBuffer(VkBuffer buffer, u32 offset, u32 size) {
73 BindBuffer(buffer, offset, size); 80 BindBuffer(buffer, offset, size);
74 } 81 }
diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
index 275d740b8..bc71202e2 100644
--- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
+++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
@@ -86,7 +86,8 @@ StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& mem
86 .pNext = nullptr, 86 .pNext = nullptr,
87 .flags = 0, 87 .flags = 0,
88 .size = STREAM_BUFFER_SIZE, 88 .size = STREAM_BUFFER_SIZE,
89 .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, 89 .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
90 VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
90 .sharingMode = VK_SHARING_MODE_EXCLUSIVE, 91 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
91 .queueFamilyIndexCount = 0, 92 .queueFamilyIndexCount = 0,
92 .pQueueFamilyIndices = nullptr, 93 .pQueueFamilyIndices = nullptr,