Files
test2/source/blender/gpu/vulkan/vk_drawlist.cc
Jeroen Bakker 7fcc4e5374 Vulkan: Add Render graph support to VKDrawList
Resources of the draw list were overwritten, before used. Fixed by
using resource tracking.

Pull Request: https://projects.blender.org/blender/blender/pulls/124024
2024-07-02 09:20:34 +02:00

104 lines
3.3 KiB
C++

/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup gpu
*/
#include "GPU_batch.hh"
#include "vk_batch.hh"
#include "vk_common.hh"
#include "vk_context.hh"
#include "vk_drawlist.hh"
#include "vk_index_buffer.hh"
#include "vk_vertex_buffer.hh"
namespace blender::gpu {
VKDrawList::VKDrawList(int list_length) : length_(list_length) {}
void VKDrawList::append(Batch *gpu_batch, int instance_first, int instance_count)
{
/* Check for different batch. When batch is different the previous commands should be flushed to
* the gpu. */
VKBatch *batch = unwrap(gpu_batch);
if (batch_ != batch) {
submit();
batch_ = batch;
}
/* Record the new command */
VKContext &context = *VKContext::get();
const VKIndexBuffer *index_buffer = batch_->index_buffer_get();
const bool is_indexed = index_buffer != nullptr;
if (is_indexed) {
/* Don't record commands for invalid GPUBatches. */
if (index_buffer->index_len_get() == 0) {
return;
}
const bool new_buffer_needed = command_index_ == 0;
std::unique_ptr<VKBuffer> &buffer = tracked_resource_for(context, new_buffer_needed);
VkDrawIndexedIndirectCommand &command = get_command<VkDrawIndexedIndirectCommand>(*buffer);
command.firstIndex = index_buffer->index_base_get();
command.vertexOffset = index_buffer->index_start_get();
command.indexCount = index_buffer->index_len_get();
command.firstInstance = instance_first;
command.instanceCount = instance_count;
}
else {
const VKVertexBuffer *vertex_buffer = batch_->vertex_buffer_get(0);
/* Don't record commands for invalid GPUBatches. */
if (vertex_buffer == nullptr || vertex_buffer->vertex_len == 0) {
return;
}
const bool new_buffer_needed = command_index_ == 0;
std::unique_ptr<VKBuffer> &buffer = tracked_resource_for(context, new_buffer_needed);
VkDrawIndirectCommand &command = get_command<VkDrawIndirectCommand>(*buffer);
command.vertexCount = vertex_buffer->vertex_len;
command.instanceCount = instance_count;
command.firstVertex = 0;
command.firstInstance = instance_first;
}
command_index_++;
/* Submit commands when command buffer is full. */
if (command_index_ == length_) {
submit();
}
}
void VKDrawList::submit()
{
if (batch_ == nullptr || command_index_ == 0) {
command_index_ = 0;
batch_ = nullptr;
return;
}
const VKIndexBuffer *index_buffer = batch_->index_buffer_get();
const bool is_indexed = index_buffer != nullptr;
VKBuffer &buffer = *active_resource();
batch_->multi_draw_indirect(buffer.vk_handle(),
command_index_,
0,
is_indexed ? sizeof(VkDrawIndexedIndirectCommand) :
sizeof(VkDrawIndirectCommand));
command_index_ = 0;
batch_ = nullptr;
}
std::unique_ptr<VKBuffer> VKDrawList::create_resource(VKContext & /*context*/)
{
const size_t bytes_needed = length_ * sizeof(VkDrawIndexedIndirectCommand);
std::unique_ptr<VKBuffer> result = std::make_unique<VKBuffer>();
result->create(bytes_needed, GPU_USAGE_DYNAMIC, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true);
debug::object_label(result->vk_handle(), "DrawList.Indirect");
return result;
}
} // namespace blender::gpu