From d638357d6f66dc7461d321819e4bf948a7aa4418 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 20 Nov 2023 15:48:06 +0100 Subject: [PATCH] Fix: Vulkan Multi Indirect Drawing Multi indirect drawing would bind an offset index buffer, but indirect drawing parameters also offset the index buffer so incorrect geometry was drawn. Fixes drawing of meshes with multiple materials. Pull Request: https://projects.blender.org/blender/blender/pulls/115190 --- source/blender/gpu/vulkan/vk_batch.cc | 3 ++- source/blender/gpu/vulkan/vk_command_buffers.cc | 8 +++----- source/blender/gpu/vulkan/vk_command_buffers.hh | 2 +- source/blender/gpu/vulkan/vk_index_buffer.cc | 13 +++---------- source/blender/gpu/vulkan/vk_index_buffer.hh | 2 +- 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_batch.cc b/source/blender/gpu/vulkan/vk_batch.cc index 6485a2eec96..a1767724d65 100644 --- a/source/blender/gpu/vulkan/vk_batch.cc +++ b/source/blender/gpu/vulkan/vk_batch.cc @@ -78,7 +78,8 @@ void VKBatch::multi_draw_indirect(GPUStorageBuf *indirect_buf, VKStorageBuffer &indirect_buffer = *unwrap(unwrap(indirect_buf)); VKContext &context = *VKContext::get(); - const bool draw_indexed = index_buffer_get() != nullptr; + VKIndexBuffer *index_buffer = index_buffer_get(); + const bool draw_indexed = index_buffer != nullptr; VKCommandBuffers &command_buffers = context.command_buffers_get(); if (draw_indexed) { command_buffers.draw_indexed_indirect(indirect_buffer, offset, count, stride); diff --git a/source/blender/gpu/vulkan/vk_command_buffers.cc b/source/blender/gpu/vulkan/vk_command_buffers.cc index 85e37941f3d..44c63055bf6 100644 --- a/source/blender/gpu/vulkan/vk_command_buffers.cc +++ b/source/blender/gpu/vulkan/vk_command_buffers.cc @@ -293,16 +293,14 @@ void VKCommandBuffers::bind(const uint32_t binding, command_buffer.command_recorded(); } -void VKCommandBuffers::bind(const VKBufferWithOffset &index_buffer, VkIndexType index_type) +void VKCommandBuffers::bind(const VKBuffer &index_buffer, VkIndexType index_type) { VKCommandBuffer &command_buffer = command_buffer_get(Type::Graphics); validate_framebuffer_exists(); ensure_active_framebuffer(); - vkCmdBindIndexBuffer(command_buffer.vk_command_buffer(), - index_buffer.buffer.vk_handle(), - index_buffer.offset, - index_type); + vkCmdBindIndexBuffer( + command_buffer.vk_command_buffer(), index_buffer.vk_handle(), 0, index_type); command_buffer.command_recorded(); } diff --git a/source/blender/gpu/vulkan/vk_command_buffers.hh b/source/blender/gpu/vulkan/vk_command_buffers.hh index d394c86a132..4c3f19f44dd 100644 --- a/source/blender/gpu/vulkan/vk_command_buffers.hh +++ b/source/blender/gpu/vulkan/vk_command_buffers.hh @@ -76,7 +76,7 @@ class VKCommandBuffers : public NonCopyable, NonMovable { void bind(const uint32_t binding, const VKBufferWithOffset &vertex_buffer); void bind(const uint32_t binding, const VkBuffer &vk_vertex_buffer, const VkDeviceSize offset); /* Bind the given buffer as an index buffer. */ - void bind(const VKBufferWithOffset &index_buffer, VkIndexType index_type); + void bind(const VKBuffer &index_buffer, VkIndexType index_type); void begin_render_pass(VKFrameBuffer &framebuffer); void end_render_pass(const VKFrameBuffer &framebuffer); diff --git a/source/blender/gpu/vulkan/vk_index_buffer.cc b/source/blender/gpu/vulkan/vk_index_buffer.cc index 7710b3e1709..cf02dec94cc 100644 --- a/source/blender/gpu/vulkan/vk_index_buffer.cc +++ b/source/blender/gpu/vulkan/vk_index_buffer.cc @@ -37,7 +37,7 @@ void VKIndexBuffer::upload_data() void VKIndexBuffer::bind(VKContext &context) { - context.command_buffers_get().bind(buffer_with_offset(), to_vk_index_type(index_type_)); + context.command_buffers_get().bind(buffer_get(), to_vk_index_type(index_type_)); } void VKIndexBuffer::bind_as_ssbo(uint binding) @@ -88,16 +88,9 @@ void VKIndexBuffer::allocate() debug::object_label(buffer_.vk_handle(), "IndexBuffer"); } -VKBufferWithOffset VKIndexBuffer::buffer_with_offset() +VKBuffer &VKIndexBuffer::buffer_get() { - VKIndexBuffer *src = unwrap(src_); - VKBufferWithOffset result{is_subrange_ ? src->buffer_ : buffer_, index_start_}; - - BLI_assert_msg(is_subrange_ || result.offset == 0, - "According to design index_start should always be zero when index buffer isn't " - "a subrange"); - - return result; + return is_subrange_ ? unwrap(src_)->buffer_ : buffer_; } } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_index_buffer.hh b/source/blender/gpu/vulkan/vk_index_buffer.hh index 06b971a639b..ec7ec8e34b2 100644 --- a/source/blender/gpu/vulkan/vk_index_buffer.hh +++ b/source/blender/gpu/vulkan/vk_index_buffer.hh @@ -40,7 +40,7 @@ class VKIndexBuffer : public IndexBuf, public VKBindableResource { void strip_restart_indices() override; void allocate(); void ensure_updated(); - VKBufferWithOffset buffer_with_offset(); + VKBuffer &buffer_get(); }; static inline VKIndexBuffer *unwrap(IndexBuf *index_buffer)