Blender V4.3
vk_drawlist.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2022 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "GPU_batch.hh"
10
11#include "vk_batch.hh"
12#include "vk_common.hh"
13#include "vk_context.hh"
14#include "vk_drawlist.hh"
15#include "vk_index_buffer.hh"
16#include "vk_vertex_buffer.hh"
17
18namespace blender::gpu {
19
20VKDrawList::VKDrawList(int list_length) : length_(list_length) {}
21
22void VKDrawList::append(Batch *gpu_batch, int instance_first, int instance_count)
23{
24 /* Check for different batch. When batch is different the previous commands should be flushed to
25 * the gpu. */
26 VKBatch *batch = unwrap(gpu_batch);
27 if (batch_ != batch) {
28 submit();
29 batch_ = batch;
30 }
31
32 /* Record the new command */
33 VKContext &context = *VKContext::get();
34 const VKIndexBuffer *index_buffer = batch_->index_buffer_get();
35 const bool is_indexed = index_buffer != nullptr;
36 if (is_indexed) {
37 /* Don't record commands for invalid GPUBatches. */
38 if (index_buffer->index_len_get() == 0) {
39 return;
40 }
41
42 const bool new_buffer_needed = command_index_ == 0;
43 std::unique_ptr<VKBuffer> &buffer = tracked_resource_for(context, new_buffer_needed);
44 VkDrawIndexedIndirectCommand &command = get_command<VkDrawIndexedIndirectCommand>(*buffer);
45 command.firstIndex = index_buffer->index_base_get();
46 command.vertexOffset = index_buffer->index_start_get();
47 command.indexCount = index_buffer->index_len_get();
48 command.firstInstance = instance_first;
49 command.instanceCount = instance_count;
50 }
51 else {
52 const VKVertexBuffer *vertex_buffer = batch_->vertex_buffer_get(0);
53 /* Don't record commands for invalid GPUBatches. */
54 if (vertex_buffer == nullptr || vertex_buffer->vertex_len == 0) {
55 return;
56 }
57
58 const bool new_buffer_needed = command_index_ == 0;
59 std::unique_ptr<VKBuffer> &buffer = tracked_resource_for(context, new_buffer_needed);
60 VkDrawIndirectCommand &command = get_command<VkDrawIndirectCommand>(*buffer);
61 command.vertexCount = vertex_buffer->vertex_len;
62 command.instanceCount = instance_count;
63 command.firstVertex = 0;
64 command.firstInstance = instance_first;
65 }
66 command_index_++;
67
68 /* Submit commands when command buffer is full. */
69 if (command_index_ == length_) {
70 submit();
71 }
72}
73
75{
76 if (batch_ == nullptr || command_index_ == 0) {
77 command_index_ = 0;
78 batch_ = nullptr;
79 return;
80 }
81
82 const VKIndexBuffer *index_buffer = batch_->index_buffer_get();
83 const bool is_indexed = index_buffer != nullptr;
84 VKBuffer &buffer = *active_resource();
85 batch_->multi_draw_indirect(buffer.vk_handle(),
86 command_index_,
87 0,
88 is_indexed ? sizeof(VkDrawIndexedIndirectCommand) :
89 sizeof(VkDrawIndirectCommand));
90 command_index_ = 0;
91 batch_ = nullptr;
92}
93
94std::unique_ptr<VKBuffer> VKDrawList::create_resource(VKContext & /*context*/)
95{
96 const size_t bytes_needed = length_ * sizeof(VkDrawIndexedIndirectCommand);
97 std::unique_ptr<VKBuffer> result = std::make_unique<VKBuffer>();
98 result->create(bytes_needed, GPU_USAGE_DYNAMIC, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true);
99 debug::object_label(result->vk_handle(), "DrawList.Indirect");
100 return result;
101}
102
103} // namespace blender::gpu
@ GPU_USAGE_DYNAMIC
uint32_t index_start_get() const
uint32_t index_base_get() const
uint32_t index_len_get() const
void multi_draw_indirect(GPUStorageBuf *indirect_buf, int count, intptr_t offset, intptr_t stride) override
Definition vk_batch.cc:70
VKVertexBuffer * vertex_buffer_get(int index)
Definition vk_batch.cc:126
VKIndexBuffer * index_buffer_get()
Definition vk_batch.cc:136
VkBuffer vk_handle() const
Definition vk_buffer.hh:69
static VKContext * get()
Definition vk_context.hh:97
void append(Batch *batch, int instance_first, int instance_count) override
void submit() override
VKDrawList(int list_length)
std::unique_ptr< VKBuffer > create_resource(VKContext &context) override
std::unique_ptr< VKBuffer > & tracked_resource_for(VKContext &context, const bool is_dirty)
std::unique_ptr< VKBuffer > & active_resource()
struct @620::@622 batch
void object_label(GLenum type, GLuint object, const char *name)
Definition gl_debug.cc:344
static Context * unwrap(GPUContext *ctx)