GPU: Add procedural drawcall in gpu::Batch
This allows to store a number of vertex to draw per batch without specifying any attribute. This allows to create batches that are empty but still holds the amount of geometry to produce. Needed for new curve drawing #142969. Pull Request: https://projects.blender.org/blender/blender/pulls/143052
This commit is contained in:
committed by
Clément Foucault
parent
614b6508d4
commit
b6076e4d80
@@ -84,6 +84,8 @@ class Batch {
|
||||
blender::gpu::IndexBuf *elem;
|
||||
/** Resource ID attribute workaround. */
|
||||
GPUStorageBuf *resource_id_buf;
|
||||
/** Number of vertices to draw for procedural drawcalls. */
|
||||
int32_t procedural_vertices;
|
||||
/** Bookkeeping. */
|
||||
eGPUBatchFlag flag;
|
||||
/** Type of geometry to draw. */
|
||||
@@ -142,6 +144,9 @@ blender::gpu::Batch *GPU_batch_create_ex(GPUPrimType primitive_type,
|
||||
blender::gpu::VertBuf *vertex_buf,
|
||||
blender::gpu::IndexBuf *index_buf,
|
||||
eGPUBatchFlag owns_flag);
|
||||
|
||||
blender::gpu::Batch *GPU_batch_create_procedural(GPUPrimType primitive_type, int32_t vertex_count);
|
||||
|
||||
/**
|
||||
* Creates a #blender::gpu::Batch without buffer ownership.
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,7 @@ void GPU_batch_zero(Batch *batch)
|
||||
batch->flag = eGPUBatchFlag(0);
|
||||
batch->prim_type = GPUPrimType(0);
|
||||
batch->shader = nullptr;
|
||||
batch->procedural_vertices = 0;
|
||||
}
|
||||
|
||||
Batch *GPU_batch_calloc()
|
||||
@@ -80,6 +81,24 @@ void GPU_batch_init_ex(Batch *batch,
|
||||
batch->prim_type = primitive_type;
|
||||
batch->flag = owns_flag | GPU_BATCH_INIT | GPU_BATCH_DIRTY;
|
||||
batch->shader = nullptr;
|
||||
batch->procedural_vertices = 0;
|
||||
}
|
||||
|
||||
Batch *GPU_batch_create_procedural(GPUPrimType primitive_type, int32_t vertex_count)
|
||||
{
|
||||
Batch *batch = GPU_batch_calloc();
|
||||
for (auto &v : batch->verts) {
|
||||
v = nullptr;
|
||||
}
|
||||
for (auto &v : batch->inst) {
|
||||
v = nullptr;
|
||||
}
|
||||
batch->elem = nullptr;
|
||||
batch->prim_type = primitive_type;
|
||||
batch->flag = GPU_BATCH_INIT | GPU_BATCH_DIRTY;
|
||||
batch->shader = nullptr;
|
||||
batch->procedural_vertices = vertex_count;
|
||||
return batch;
|
||||
}
|
||||
|
||||
void GPU_batch_copy(Batch *batch_dst, Batch *batch_src)
|
||||
@@ -92,6 +111,7 @@ void GPU_batch_copy(Batch *batch_dst, Batch *batch_src)
|
||||
for (int v = 1; v < GPU_BATCH_VBO_MAX_LEN; v++) {
|
||||
batch_dst->verts[v] = batch_src->verts[v];
|
||||
}
|
||||
batch_dst->procedural_vertices = batch_src->procedural_vertices;
|
||||
}
|
||||
|
||||
void GPU_batch_clear(Batch *batch)
|
||||
@@ -114,6 +134,7 @@ void GPU_batch_clear(Batch *batch)
|
||||
}
|
||||
}
|
||||
batch->flag = GPU_BATCH_INVALID;
|
||||
batch->procedural_vertices = 0;
|
||||
}
|
||||
|
||||
void GPU_batch_discard(Batch *batch)
|
||||
@@ -461,7 +482,10 @@ void GPU_batch_draw_advanced(
|
||||
Context::get()->assert_framebuffer_shader_compatibility(Context::get()->shader);
|
||||
|
||||
if (vertex_count == 0) {
|
||||
if (batch->elem) {
|
||||
if (batch->procedural_vertices > 0) {
|
||||
vertex_count = batch->procedural_vertices;
|
||||
}
|
||||
else if (batch->elem) {
|
||||
vertex_count = batch->elem_()->index_len_get();
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -289,17 +289,13 @@ static void test_framebuffer_multi_viewport()
|
||||
GPUShader *shader = GPU_shader_create_from_info(
|
||||
reinterpret_cast<GPUShaderCreateInfo *>(&create_info));
|
||||
|
||||
/* TODO(fclem): remove this boilerplate. */
|
||||
GPUVertFormat format{};
|
||||
GPU_vertformat_attr_add(&format, "dummy", VertAttrType::UINT_32);
|
||||
VertBuf *verts = GPU_vertbuf_create_with_format(format);
|
||||
GPU_vertbuf_data_alloc(*verts, 3);
|
||||
Batch *batch = GPU_batch_create_ex(GPU_PRIM_TRIS, verts, nullptr, GPU_BATCH_OWNS_VBO);
|
||||
int tri_count = size.x * size.y * layers;
|
||||
|
||||
Batch *batch = GPU_batch_create_procedural(GPU_PRIM_TRIS, tri_count * 3);
|
||||
|
||||
GPU_batch_set_shader(batch, shader);
|
||||
|
||||
int tri_count = size.x * size.y * layers;
|
||||
GPU_batch_draw_advanced(batch, 0, tri_count * 3, 0, 1);
|
||||
GPU_batch_draw(batch);
|
||||
|
||||
GPU_batch_discard(batch);
|
||||
|
||||
@@ -370,12 +366,7 @@ static void test_framebuffer_subpass_input()
|
||||
GPUShader *shader_read = GPU_shader_create_from_info(
|
||||
reinterpret_cast<GPUShaderCreateInfo *>(&create_info_read));
|
||||
|
||||
/* TODO(fclem): remove this boilerplate. */
|
||||
GPUVertFormat format{};
|
||||
GPU_vertformat_attr_add(&format, "dummy", VertAttrType::UINT_32);
|
||||
VertBuf *verts = GPU_vertbuf_create_with_format(format);
|
||||
GPU_vertbuf_data_alloc(*verts, 3);
|
||||
Batch *batch = GPU_batch_create_ex(GPU_PRIM_TRIS, verts, nullptr, GPU_BATCH_OWNS_VBO);
|
||||
Batch *batch = GPU_batch_create_procedural(GPU_PRIM_TRIS, 3);
|
||||
|
||||
/* Metal Raster Order Group does not need that. */
|
||||
GPU_framebuffer_subpass_transition(
|
||||
|
||||
@@ -374,15 +374,10 @@ static void gpu_shader_lib_test(const char *test_src_name, const char *additiona
|
||||
GPU_framebuffer_ensure_config(&fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(tex)});
|
||||
GPU_framebuffer_bind(fb);
|
||||
|
||||
/* TODO(fclem): remove this boilerplate. */
|
||||
GPUVertFormat format{};
|
||||
GPU_vertformat_attr_add(&format, "dummy", VertAttrType::UINT_32);
|
||||
VertBuf *verts = GPU_vertbuf_create_with_format(format);
|
||||
GPU_vertbuf_data_alloc(*verts, 3);
|
||||
Batch *batch = GPU_batch_create_ex(GPU_PRIM_TRIS, verts, nullptr, GPU_BATCH_OWNS_VBO);
|
||||
Batch *batch = GPU_batch_create_procedural(GPU_PRIM_TRIS, 3);
|
||||
|
||||
GPU_batch_set_shader(batch, shader);
|
||||
GPU_batch_draw_advanced(batch, 0, 3, 0, 1);
|
||||
GPU_batch_draw(batch);
|
||||
|
||||
GPU_batch_discard(batch);
|
||||
|
||||
|
||||
@@ -97,13 +97,8 @@ struct ShaderSpecializationConst {
|
||||
GPU_framebuffer_default_size(fb, 1, 1);
|
||||
GPU_framebuffer_bind(fb);
|
||||
|
||||
/* TODO(fclem): remove this boilerplate. */
|
||||
GPUVertFormat format{};
|
||||
GPU_vertformat_attr_add(&format, "dummy", VertAttrType::UINT_32);
|
||||
VertBuf *verts = GPU_vertbuf_create_with_format(format);
|
||||
Batch *batch = GPU_batch_create_procedural(GPU_PRIM_POINTS, 1);
|
||||
|
||||
GPU_vertbuf_data_alloc(*verts, 1);
|
||||
Batch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, verts, nullptr, GPU_BATCH_OWNS_VBO);
|
||||
GPU_batch_set_shader(batch, shader, &constants);
|
||||
GPU_batch_draw_advanced(batch, 0, 1, 0, 1);
|
||||
GPU_batch_discard(batch);
|
||||
|
||||
Reference in New Issue
Block a user