Blender V4.5
vk_batch.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
8
9#include "vk_batch.hh"
10
12#include "vk_context.hh"
13#include "vk_framebuffer.hh"
14#include "vk_index_buffer.hh"
15#include "vk_state_manager.hh"
16#include "vk_storage_buffer.hh"
18#include "vk_vertex_buffer.hh"
19
20namespace blender::gpu {
21
22void VKBatch::draw(int vertex_first, int vertex_count, int instance_first, int instance_count)
23{
24 VKContext &context = *VKContext::get();
25 render_graph::VKResourceAccessInfo &resource_access_info = context.reset_and_get_access_info();
27 vao.update_bindings(context, *this);
28
29 VKIndexBuffer *index_buffer = index_buffer_get();
30 const bool draw_indexed = index_buffer != nullptr;
31
32 /* Upload geometry */
33 if (draw_indexed) {
34 index_buffer->upload_data();
35 }
36 context.active_framebuffer_get()->rendering_ensure(context);
37
38 if (draw_indexed) {
39 render_graph::VKDrawIndexedNode::CreateInfo draw_indexed(resource_access_info);
40 draw_indexed.node_data.index_count = vertex_count;
41 draw_indexed.node_data.instance_count = instance_count;
42 draw_indexed.node_data.first_index = index_buffer->index_start_get() + vertex_first;
43 draw_indexed.node_data.vertex_offset = index_buffer->index_base_get();
44 draw_indexed.node_data.first_instance = instance_first;
45
46 context.active_framebuffer_get()->vk_viewports_append(
47 draw_indexed.node_data.viewport_data.viewports);
48 context.active_framebuffer_get()->vk_render_areas_append(
49 draw_indexed.node_data.viewport_data.scissors);
50
51 draw_indexed.node_data.index_buffer.buffer = index_buffer->vk_handle();
52 draw_indexed.node_data.index_buffer.index_type = index_buffer->vk_index_type();
53 vao.bind(draw_indexed.node_data.vertex_buffers);
54 context.update_pipeline_data(prim_type, vao, draw_indexed.node_data.pipeline_data);
55
56 context.render_graph().add_node(draw_indexed);
57 }
58 else {
59 render_graph::VKDrawNode::CreateInfo draw(resource_access_info);
60 draw.node_data.vertex_count = vertex_count;
61 draw.node_data.instance_count = instance_count;
62 draw.node_data.first_vertex = vertex_first;
63 draw.node_data.first_instance = instance_first;
64 context.active_framebuffer_get()->vk_viewports_append(draw.node_data.viewport_data.viewports);
65 context.active_framebuffer_get()->vk_render_areas_append(
66 draw.node_data.viewport_data.scissors);
67
68 vao.bind(draw.node_data.vertex_buffers);
69 context.update_pipeline_data(prim_type, vao, draw.node_data.pipeline_data);
70
71 context.render_graph().add_node(draw);
72 }
73}
74
75void VKBatch::draw_indirect(GPUStorageBuf *indirect_buf, intptr_t offset)
76{
77 multi_draw_indirect(indirect_buf, 1, offset, 0);
78}
79
80void VKBatch::multi_draw_indirect(GPUStorageBuf *indirect_buf,
81 const int count,
82 const intptr_t offset,
83 const intptr_t stride)
84{
85 VKStorageBuffer &indirect_buffer = *unwrap(unwrap(indirect_buf));
86 multi_draw_indirect(indirect_buffer.vk_handle(), count, offset, stride);
87}
88
89void VKBatch::multi_draw_indirect(const VkBuffer indirect_buffer,
90 const int count,
91 const intptr_t offset,
92 const intptr_t stride)
93{
94 VKContext &context = *VKContext::get();
95 render_graph::VKResourceAccessInfo &resource_access_info = context.reset_and_get_access_info();
97 vao.update_bindings(context, *this);
98
99 VKIndexBuffer *index_buffer = index_buffer_get();
100 const bool draw_indexed = index_buffer != nullptr;
101
102 /* Upload geometry */
103 if (draw_indexed) {
104 index_buffer->upload_data();
105 }
106 context.active_framebuffer_get()->rendering_ensure(context);
107
108 if (draw_indexed) {
110 resource_access_info);
111 draw_indexed_indirect.node_data.indirect_buffer = indirect_buffer;
112 draw_indexed_indirect.node_data.offset = offset;
113 draw_indexed_indirect.node_data.draw_count = count;
114 draw_indexed_indirect.node_data.stride = stride;
115
116 context.active_framebuffer_get()->vk_viewports_append(
117 draw_indexed_indirect.node_data.viewport_data.viewports);
118 context.active_framebuffer_get()->vk_render_areas_append(
119 draw_indexed_indirect.node_data.viewport_data.scissors);
120
121 draw_indexed_indirect.node_data.index_buffer.buffer = index_buffer->vk_handle();
122 draw_indexed_indirect.node_data.index_buffer.index_type = index_buffer->vk_index_type();
123 vao.bind(draw_indexed_indirect.node_data.vertex_buffers);
124 context.update_pipeline_data(prim_type, vao, draw_indexed_indirect.node_data.pipeline_data);
125
126 context.render_graph().add_node(draw_indexed_indirect);
127 }
128 else {
130 draw.node_data.indirect_buffer = indirect_buffer;
131 draw.node_data.offset = offset;
132 draw.node_data.draw_count = count;
133 draw.node_data.stride = stride;
134 context.active_framebuffer_get()->vk_viewports_append(draw.node_data.viewport_data.viewports);
135 context.active_framebuffer_get()->vk_render_areas_append(
136 draw.node_data.viewport_data.scissors);
137
138 vao.bind(draw.node_data.vertex_buffers);
139 context.update_pipeline_data(prim_type, vao, draw.node_data.pipeline_data);
140
141 context.render_graph().add_node(draw);
142 }
143}
144
145} // namespace blender::gpu
uint32_t index_start_get() const
uint32_t index_base_get() const
void draw_indirect(GPUStorageBuf *indirect_buf, intptr_t offset) override
Definition vk_batch.cc:75
void multi_draw_indirect(GPUStorageBuf *indirect_buf, int count, intptr_t offset, intptr_t stride) override
Definition vk_batch.cc:80
VKIndexBuffer * index_buffer_get()
Definition vk_batch.hh:47
void draw(int vertex_first, int vertex_count, int instance_first, int instance_count) override
Definition vk_batch.cc:22
static VKContext * get()
VkIndexType vk_index_type() const
void update_bindings(const VKContext &context, VKBatch &batch)
void bind(render_graph::VKVertexBufferBindings &r_vertex_buffer_bindings) const
int count
static Context * unwrap(GPUContext *ctx)