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
This commit is contained in:
parent
07b5e1bd80
commit
d638357d6f
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue