diff --git a/source/blender/draw/intern/draw_cache.cc b/source/blender/draw/intern/draw_cache.cc index 15774ef14d3..49bb55115d9 100644 --- a/source/blender/draw/intern/draw_cache.cc +++ b/source/blender/draw/intern/draw_cache.cc @@ -102,10 +102,6 @@ struct VertShaded { /* Batch's only (freed as an array). */ static struct DRWShapeCache { - blender::gpu::Batch *drw_procedural_verts; - blender::gpu::Batch *drw_procedural_lines; - blender::gpu::Batch *drw_procedural_tris; - blender::gpu::Batch *drw_procedural_tri_strips; blender::gpu::Batch *drw_cursor; blender::gpu::Batch *drw_cursor_only_circle; blender::gpu::Batch *drw_quad; @@ -125,71 +121,6 @@ void DRW_shape_cache_free() /** \} */ -/* -------------------------------------------------------------------- */ -/** \name Procedural Batches - * \{ */ - -blender::gpu::Batch *drw_cache_procedural_points_get() -{ - if (!SHC.drw_procedural_verts) { - /* TODO(fclem): get rid of this dummy VBO. */ - GPUVertFormat format = {0}; - GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(format); - GPU_vertbuf_data_alloc(*vbo, 1); - - SHC.drw_procedural_verts = GPU_batch_create_ex( - GPU_PRIM_POINTS, vbo, nullptr, GPU_BATCH_OWNS_VBO); - } - return SHC.drw_procedural_verts; -} - -blender::gpu::Batch *drw_cache_procedural_lines_get() -{ - if (!SHC.drw_procedural_lines) { - /* TODO(fclem): get rid of this dummy VBO. */ - GPUVertFormat format = {0}; - GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(format); - GPU_vertbuf_data_alloc(*vbo, 1); - - SHC.drw_procedural_lines = GPU_batch_create_ex( - GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO); - } - return SHC.drw_procedural_lines; -} - -blender::gpu::Batch *drw_cache_procedural_triangles_get() -{ - if (!SHC.drw_procedural_tris) { - /* TODO(fclem): get rid of this dummy VBO. */ - GPUVertFormat format = {0}; - GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(format); - GPU_vertbuf_data_alloc(*vbo, 1); - - SHC.drw_procedural_tris = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, nullptr, GPU_BATCH_OWNS_VBO); - } - return SHC.drw_procedural_tris; -} - -blender::gpu::Batch *drw_cache_procedural_triangle_strips_get() -{ - if (!SHC.drw_procedural_tri_strips) { - /* TODO(fclem): get rid of this dummy VBO. */ - GPUVertFormat format = {0}; - GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(format); - GPU_vertbuf_data_alloc(*vbo, 1); - - SHC.drw_procedural_tri_strips = GPU_batch_create_ex( - GPU_PRIM_TRI_STRIP, vbo, nullptr, GPU_BATCH_OWNS_VBO); - } - return SHC.drw_procedural_tri_strips; -} - -/** \} */ - /* -------------------------------------------------------------------- */ /** \name Helper functions * \{ */ diff --git a/source/blender/draw/intern/draw_command.cc b/source/blender/draw/intern/draw_command.cc index 4a5344894c6..9407db6a353 100644 --- a/source/blender/draw/intern/draw_command.cc +++ b/source/blender/draw/intern/draw_command.cc @@ -25,13 +25,13 @@ static gpu::Batch *procedural_batch_get(GPUPrimType primitive) { switch (primitive) { case GPU_PRIM_POINTS: - return drw_cache_procedural_points_get(); + return GPU_batch_procedural_points_get(); case GPU_PRIM_LINES: - return drw_cache_procedural_lines_get(); + return GPU_batch_procedural_lines_get(); case GPU_PRIM_TRIS: - return drw_cache_procedural_triangles_get(); + return GPU_batch_procedural_triangles_get(); case GPU_PRIM_TRI_STRIP: - return drw_cache_procedural_triangle_strips_get(); + return GPU_batch_procedural_triangle_strips_get(); default: /* Add new one as needed. */ BLI_assert_unreachable(); diff --git a/source/blender/draw/intern/draw_debug.cc b/source/blender/draw/intern/draw_debug.cc index 57b6fb31f8c..595522238b5 100644 --- a/source/blender/draw/intern/draw_debug.cc +++ b/source/blender/draw/intern/draw_debug.cc @@ -240,7 +240,7 @@ void DebugDraw::display_lines() command::StateSet::set(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); - gpu::Batch *batch = drw_cache_procedural_lines_get(); + gpu::Batch *batch = GPU_batch_procedural_lines_get(); GPUShader *shader = DRW_shader_debug_draw_display_get(); GPU_batch_set_shader(batch, shader); GPU_shader_uniform_mat4(shader, "persmat", persmat.ptr()); diff --git a/source/blender/draw/intern/draw_pass.hh b/source/blender/draw/intern/draw_pass.hh index 59e7318e32a..c8c361fc71a 100644 --- a/source/blender/draw/intern/draw_pass.hh +++ b/source/blender/draw/intern/draw_pass.hh @@ -617,13 +617,13 @@ template inline gpu::Batch *PassBase::procedural_batch_get(GPUPrimTy { switch (primitive) { case GPU_PRIM_POINTS: - return drw_cache_procedural_points_get(); + return GPU_batch_procedural_points_get(); case GPU_PRIM_LINES: - return drw_cache_procedural_lines_get(); + return GPU_batch_procedural_lines_get(); case GPU_PRIM_TRIS: - return drw_cache_procedural_triangles_get(); + return GPU_batch_procedural_triangles_get(); case GPU_PRIM_TRI_STRIP: - return drw_cache_procedural_triangle_strips_get(); + return GPU_batch_procedural_triangle_strips_get(); default: /* Add new one as needed. */ BLI_assert_unreachable(); diff --git a/source/blender/gpu/GPU_batch.hh b/source/blender/gpu/GPU_batch.hh index 0dd03b6d450..01c7554fe44 100644 --- a/source/blender/gpu/GPU_batch.hh +++ b/source/blender/gpu/GPU_batch.hh @@ -432,6 +432,40 @@ blender::IndexRange GPU_batch_draw_expanded_parameter_get(GPUPrimType input_prim /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Procedural drawing + * + * A drawcall always need a batch to be issued. + * These are dummy batches that contains no vertex data and can be used to render geometry + * without per vertex inputs. + * \{ */ + +/** + * Batch with no attributes, suited for rendering procedural geometry. + * IMPORTANT: The returned batch is only valid for the current context. + */ +blender::gpu::Batch *GPU_batch_procedural_points_get(); + +/** + * Batch with no attributes, suited for rendering procedural geometry. + * IMPORTANT: The returned batch is only valid for the current context. + */ +blender::gpu::Batch *GPU_batch_procedural_lines_get(); + +/** + * Batch with no attributes, suited for rendering procedural geometry. + * IMPORTANT: The returned batch is only valid for the current context. + */ +blender::gpu::Batch *GPU_batch_procedural_triangles_get(); + +/** + * Batch with no attributes, suited for rendering procedural geometry. + * IMPORTANT: The returned batch is only valid for the current context. + */ +blender::gpu::Batch *GPU_batch_procedural_triangle_strips_get(); + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Module init/exit * \{ */ diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc index c92f95c17a8..0277e62d877 100644 --- a/source/blender/gpu/intern/gpu_batch.cc +++ b/source/blender/gpu/intern/gpu_batch.cc @@ -385,7 +385,7 @@ static void polyline_draw_workaround( GPU_batch_bind_as_resources(batch, batch->shader); blender::IndexRange range = GPU_batch_draw_expanded_parameter_get( batch->prim_type, GPU_PRIM_TRIS, vertex_count, vertex_first, 2); - Batch *tri_batch = Context::get()->polyline_batch_get(); + Batch *tri_batch = Context::get()->procedural_triangles_batch_get(); GPU_batch_set_shader(tri_batch, batch->shader); int vert_stride_count[3] = {(batch->prim_type == GPU_PRIM_LINES) ? 2 : 1, vertex_count, 0}; @@ -521,6 +521,26 @@ void GPU_batch_program_set_imm_shader(Batch *batch) GPU_batch_set_shader(batch, immGetShader()); } +blender::gpu::Batch *GPU_batch_procedural_points_get() +{ + return blender::gpu::Context::get()->procedural_points_batch_get(); +} + +blender::gpu::Batch *GPU_batch_procedural_lines_get() +{ + return blender::gpu::Context::get()->procedural_lines_batch_get(); +} + +blender::gpu::Batch *GPU_batch_procedural_triangles_get() +{ + return blender::gpu::Context::get()->procedural_triangles_batch_get(); +} + +blender::gpu::Batch *GPU_batch_procedural_triangle_strips_get() +{ + return blender::gpu::Context::get()->procedural_triangle_strips_batch_get(); +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc index 52a226d4a77..aebd6890a83 100644 --- a/source/blender/gpu/intern/gpu_context.cc +++ b/source/blender/gpu/intern/gpu_context.cc @@ -80,7 +80,11 @@ Context::~Context() BLI_assert(back_right == nullptr); GPU_matrix_state_discard(matrix_state); - GPU_BATCH_DISCARD_SAFE(polyline_batch); + GPU_BATCH_DISCARD_SAFE(procedural_points_batch); + GPU_BATCH_DISCARD_SAFE(procedural_lines_batch); + GPU_BATCH_DISCARD_SAFE(procedural_triangles_batch); + GPU_BATCH_DISCARD_SAFE(procedural_triangle_strips_batch); + GPU_VERTBUF_DISCARD_SAFE(dummy_vbo); delete texture_pool; delete state_manager; delete imm; @@ -109,20 +113,59 @@ Context *Context::get() return active_ctx; } -Batch *Context::polyline_batch_get() +VertBuf *Context::dummy_vbo_get() { - if (polyline_batch) { - return polyline_batch; + if (this->dummy_vbo) { + return this->dummy_vbo; } /* TODO(fclem): get rid of this dummy VBO. */ GPUVertFormat format = {0}; GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(format); - GPU_vertbuf_data_alloc(*vbo, 1); + this->dummy_vbo = GPU_vertbuf_create_with_format(format); + GPU_vertbuf_data_alloc(*this->dummy_vbo, 1); + return this->dummy_vbo; +} - polyline_batch = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, nullptr, GPU_BATCH_OWNS_VBO); - return polyline_batch; +Batch *Context::procedural_points_batch_get() +{ + if (procedural_points_batch) { + return procedural_points_batch; + } + + procedural_points_batch = GPU_batch_create(GPU_PRIM_POINTS, dummy_vbo_get(), nullptr); + return procedural_points_batch; +} + +Batch *Context::procedural_lines_batch_get() +{ + if (procedural_lines_batch) { + return procedural_lines_batch; + } + + procedural_lines_batch = GPU_batch_create(GPU_PRIM_LINES, dummy_vbo_get(), nullptr); + return procedural_lines_batch; +} + +Batch *Context::procedural_triangles_batch_get() +{ + if (procedural_triangles_batch) { + return procedural_triangles_batch; + } + + procedural_triangles_batch = GPU_batch_create(GPU_PRIM_TRIS, dummy_vbo_get(), nullptr); + return procedural_triangles_batch; +} + +Batch *Context::procedural_triangle_strips_batch_get() +{ + if (procedural_triangle_strips_batch) { + return procedural_triangle_strips_batch; + } + + procedural_triangle_strips_batch = GPU_batch_create( + GPU_PRIM_TRI_STRIP, dummy_vbo_get(), nullptr); + return procedural_triangle_strips_batch; } } // namespace blender::gpu diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh index 4b895189dd3..2f2fad15ef8 100644 --- a/source/blender/gpu/intern/gpu_context_private.hh +++ b/source/blender/gpu/intern/gpu_context_private.hh @@ -65,8 +65,13 @@ class Context { /* Used as a stack. Each render_begin/end pair will push pop from the stack. */ Vector printf_buf; - /** Dummy triangle batch for polyline workaround. */ - Batch *polyline_batch = nullptr; + /** Dummy VBO to feed the procedural batches. */ + VertBuf *dummy_vbo = nullptr; + /** Dummy batches for procedural geometry rendering. */ + Batch *procedural_points_batch = nullptr; + Batch *procedural_lines_batch = nullptr; + Batch *procedural_triangles_batch = nullptr; + Batch *procedural_triangle_strips_batch = nullptr; /** Texture pool used to recycle temporary texture (or render target) memory. */ TexturePool *texture_pool = nullptr; @@ -113,7 +118,11 @@ class Context { bool is_active_on_thread(); - Batch *polyline_batch_get(); + VertBuf *dummy_vbo_get(); + Batch *procedural_points_batch_get(); + Batch *procedural_lines_batch_get(); + Batch *procedural_triangles_batch_get(); + Batch *procedural_triangle_strips_batch_get(); /* When using `--debug-gpu`, assert that the shader fragments write to all the writable * attachments of the bound frame-buffer. */ diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc index 53969824670..b7c130ff43b 100644 --- a/source/blender/gpu/intern/gpu_immediate.cc +++ b/source/blender/gpu/intern/gpu_immediate.cc @@ -284,7 +284,7 @@ void Immediate::polyline_draw_workaround(uint64_t offset) /* Check compatible input primitive. */ BLI_assert(ELEM(imm->prim_type, GPU_PRIM_LINES, GPU_PRIM_LINE_STRIP, GPU_PRIM_LINE_LOOP)); - Batch *tri_batch = Context::get()->polyline_batch_get(); + Batch *tri_batch = Context::get()->procedural_triangles_batch_get(); GPU_batch_set_shader(tri_batch, imm->shader); BLI_assert(offset % 4 == 0);