diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2019-05-11 18:45:20 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2019-05-14 11:57:03 +0300 |
commit | 754ecd61aa28345dd474ca901b8ca60ecbd4e88a (patch) | |
tree | f67860bdf2289cc180d9224829e4805b9ac2d07a /source/blender | |
parent | 8406fabc87446238a1168df5d57470c84edad85f (diff) |
DRW: Change Procedural function to use a GPUBatch
This is in order to have VAO handled by thoses batches instead of using a
common VAO. Even if the VAO has no importance in these case using a batch
will help when transitioning to Vulkan.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 51 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.h | 7 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_data.c | 18 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_exec.c | 32 |
4 files changed, 76 insertions, 32 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index e9896261004..c40e9772340 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -46,6 +46,9 @@ /* Batch's only (free'd as an array) */ static struct DRWShapeCache { + GPUBatch *drw_procedural_verts; + GPUBatch *drw_procedural_lines; + GPUBatch *drw_procedural_tris; GPUBatch *drw_single_vertice; GPUBatch *drw_cursor; GPUBatch *drw_cursor_only_circle; @@ -138,6 +141,54 @@ void DRW_shape_cache_reset(void) } /* -------------------------------------------------------------------- */ +/** \name Procedural Batches + * \{ */ + +GPUBatch *drw_cache_procedural_points_get(void) +{ + 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); + GPUVertBuf *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, NULL, GPU_BATCH_OWNS_VBO); + } + return SHC.drw_procedural_verts; +} + +GPUBatch *drw_cache_procedural_lines_get(void) +{ + 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); + GPUVertBuf *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, NULL, GPU_BATCH_OWNS_VBO); + } + return SHC.drw_procedural_lines; +} + +GPUBatch *drw_cache_procedural_triangles_get(void) +{ + 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); + GPUVertBuf *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, NULL, GPU_BATCH_OWNS_VBO); + } + return SHC.drw_procedural_tris; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Helper functions * \{ */ diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index ae765775929..8dff65175ec 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -152,8 +152,8 @@ typedef struct DRWCall { uint count; } instances; struct { /* type == DRW_CALL_PROCEDURAL */ + GPUBatch *geometry; uint vert_count; - GPUPrimType prim_type; } procedural; }; @@ -438,6 +438,11 @@ void drw_debug_init(void); void drw_batch_cache_validate(Object *ob); void drw_batch_cache_generate_requested(struct Object *ob); +/* Procedural Drawing */ +GPUBatch *drw_cache_procedural_points_get(void); +GPUBatch *drw_cache_procedural_lines_get(void); +GPUBatch *drw_cache_procedural_triangles_get(void); + extern struct GPUVertFormat *g_pos_format; #endif /* __DRAW_MANAGER_H__ */ diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 75dcf6e7796..3a6a7300cea 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -487,19 +487,18 @@ void DRW_shgroup_call_range_add( } static void drw_shgroup_call_procedural_add_ex(DRWShadingGroup *shgroup, - GPUPrimType prim_type, + GPUBatch *geom, uint vert_count, - float (*obmat)[4], - Object *ob) + float (*obmat)[4]) { BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM)); DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls); BLI_LINKS_APPEND(&shgroup->calls, call); - call->state = drw_call_state_object(shgroup, ob ? ob->obmat : obmat, ob); + call->state = drw_call_state_object(shgroup, obmat, NULL); call->type = DRW_CALL_PROCEDURAL; - call->procedural.prim_type = prim_type; + call->procedural.geometry = geom; call->procedural.vert_count = vert_count; #ifdef USE_GPU_SELECT call->select_id = DST.select_id; @@ -510,21 +509,24 @@ void DRW_shgroup_call_procedural_points_add(DRWShadingGroup *shgroup, uint point_len, float (*obmat)[4]) { - drw_shgroup_call_procedural_add_ex(shgroup, GPU_PRIM_POINTS, point_len, obmat, NULL); + struct GPUBatch *geom = drw_cache_procedural_points_get(); + drw_shgroup_call_procedural_add_ex(shgroup, geom, point_len, obmat); } void DRW_shgroup_call_procedural_lines_add(DRWShadingGroup *shgroup, uint line_count, float (*obmat)[4]) { - drw_shgroup_call_procedural_add_ex(shgroup, GPU_PRIM_LINES, line_count * 2, obmat, NULL); + struct GPUBatch *geom = drw_cache_procedural_lines_get(); + drw_shgroup_call_procedural_add_ex(shgroup, geom, line_count * 2, obmat); } void DRW_shgroup_call_procedural_triangles_add(DRWShadingGroup *shgroup, uint tria_count, float (*obmat)[4]) { - drw_shgroup_call_procedural_add_ex(shgroup, GPU_PRIM_TRIS, tria_count * 3, obmat, NULL); + struct GPUBatch *geom = drw_cache_procedural_triangles_get(); + drw_shgroup_call_procedural_add_ex(shgroup, geom, tria_count * 3, obmat); } /* These calls can be culled and are optimized for redraw */ diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index ef50e9d5910..b9d49df7947 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -858,18 +858,9 @@ static void draw_geometry_prepare(DRWShadingGroup *shgroup, DRWCall *call) } } -static void draw_geometry_execute_ex( +static void draw_geometry_execute( DRWShadingGroup *shgroup, GPUBatch *geom, uint start, uint count, bool draw_instance) { - /* Special case: empty drawcall, placement is done via shader, don't bind anything. */ - /* TODO use DRW_CALL_PROCEDURAL instead */ - if (geom == NULL) { - BLI_assert(shgroup->type == DRW_SHG_TRIANGLE_BATCH); /* Add other type if needed. */ - /* Shader is already bound. */ - GPU_draw_primitive(GPU_PRIM_TRIS, count); - return; - } - /* step 2 : bind vertex array & draw */ GPU_batch_program_set_no_use( geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader)); @@ -881,11 +872,6 @@ static void draw_geometry_execute_ex( geom->program_in_use = false; /* XXX hacking gawain */ } -static void draw_geometry_execute(DRWShadingGroup *shgroup, GPUBatch *geom) -{ - draw_geometry_execute_ex(shgroup, geom, 0, 0, false); -} - enum { BIND_NONE = 0, BIND_TEMP = 1, /* Release slot after this shading group. */ @@ -1223,7 +1209,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) if (shgroup->instance_geom != NULL) { GPU_SELECT_LOAD_IF_PICKSEL(shgroup->override_selectid); draw_geometry_prepare(shgroup, NULL); - draw_geometry_execute_ex(shgroup, shgroup->instance_geom, 0, 0, true); + draw_geometry_execute(shgroup, shgroup->instance_geom, 0, 0, true); } } else { @@ -1231,7 +1217,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) uint count, start; draw_geometry_prepare(shgroup, NULL); GPU_SELECT_LOAD_IF_PICKSEL_LIST (shgroup, start, count) { - draw_geometry_execute_ex(shgroup, shgroup->instance_geom, start, count, true); + draw_geometry_execute(shgroup, shgroup->instance_geom, start, count, true); } GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count); } @@ -1243,7 +1229,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) uint count, start; draw_geometry_prepare(shgroup, NULL); GPU_SELECT_LOAD_IF_PICKSEL_LIST (shgroup, start, count) { - draw_geometry_execute_ex(shgroup, shgroup->batch_geom, start, count, false); + draw_geometry_execute(shgroup, shgroup->batch_geom, start, count, false); } GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count); } @@ -1281,18 +1267,18 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) switch (call->type) { case DRW_CALL_SINGLE: - draw_geometry_execute(shgroup, call->single.geometry); + draw_geometry_execute(shgroup, call->single.geometry, 0, 0, false); break; case DRW_CALL_RANGE: - draw_geometry_execute_ex( + draw_geometry_execute( shgroup, call->range.geometry, call->range.start, call->range.count, false); break; case DRW_CALL_INSTANCES: - draw_geometry_execute_ex( - shgroup, call->instances.geometry, 0, call->instances.count, true); + draw_geometry_execute(shgroup, call->instances.geometry, 0, call->instances.count, true); break; case DRW_CALL_PROCEDURAL: - GPU_draw_primitive(call->procedural.prim_type, call->procedural.vert_count); + draw_geometry_execute( + shgroup, call->procedural.geometry, 0, call->procedural.vert_count, false); break; default: BLI_assert(0); |