diff options
-rw-r--r-- | source/blender/draw/intern/draw_cache_extract.h | 5 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_extract_mesh.c | 70 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 3 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_inline.h | 6 | ||||
-rw-r--r-- | source/blender/gpu/GPU_element.h | 4 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_element.c | 10 |
6 files changed, 80 insertions, 18 deletions
diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h index b1eab3c73ae..7ee02c3c556 100644 --- a/source/blender/draw/intern/draw_cache_extract.h +++ b/source/blender/draw/intern/draw_cache_extract.h @@ -115,8 +115,9 @@ typedef struct MeshBufferCache { * Only need to be updated when topology changes. */ struct { /* Indices to vloops. */ - GPUIndexBuf *tris; /* Ordered per material. */ - GPUIndexBuf *lines; /* Loose edges last. */ + GPUIndexBuf *tris; /* Ordered per material. */ + GPUIndexBuf *lines; /* Loose edges last. */ + GPUIndexBuf *lines_loose; /* sub buffer of `lines` only containing the loose edges. */ GPUIndexBuf *points; GPUIndexBuf *fdots; /* 3D overlays. */ diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c index 2c6eb7e0b1d..06c2bfc301a 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.c +++ b/source/blender/draw/intern/draw_cache_extract_mesh.c @@ -634,21 +634,10 @@ static void extract_lines_ledge_mesh(const MeshRenderData *mr, GPU_indexbuf_set_line_restart(elb, edge_idx); } -static void extract_lines_finish(const MeshRenderData *mr, void *ibo, void *elb) +static void extract_lines_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *elb) { GPU_indexbuf_build_in_place(elb, ibo); MEM_freeN(elb); - /* HACK Create ibo subranges and assign them to GPUBatch. */ - if (mr->use_final_mesh && mr->cache->batch.loose_edges) { - BLI_assert(mr->cache->batch.loose_edges->elem == ibo); - /* Multiply by 2 because these are edges indices. */ - int start = mr->edge_len * 2; - int len = mr->edge_loose_len * 2; - GPUIndexBuf *sub_ibo = GPU_indexbuf_create_subrange(ibo, start, len); - /* WARNING: We modify the GPUBatch here! */ - GPU_batch_elembuf_set(mr->cache->batch.loose_edges, sub_ibo, true); - mr->cache->no_loose_wire = (len == 0); - } } static const MeshExtract extract_lines = { @@ -669,6 +658,56 @@ static const MeshExtract extract_lines = { /** \} */ /* ---------------------------------------------------------------------- */ +/** \name Extract Loose Edges Indices + * \{ */ + +static void *extract_lines_loose_init(const MeshRenderData *UNUSED(mr), void *UNUSED(buf)) +{ + return NULL; +} + +static void extract_lines_loose_ledge_mesh(const MeshRenderData *UNUSED(mr), + int UNUSED(e), + const MEdge *UNUSED(medge), + void *UNUSED(elb)) +{ + /* This function is intentionally empty. The existence of this functions ensures that + * `iter_type` `MR_ITER_LVERT` is set when initializing the `MeshRenderData` (See + * `mesh_extract_iter_type`). This flag ensures that `mr->edge_loose_len` field is filled. This + * field we use in the `extract_lines_loose_finish` function to create a subrange from the + * `ibo.lines`. */ +} + +static void extract_lines_loose_finish(const MeshRenderData *mr, + void *UNUSED(ibo), + void *UNUSED(elb)) +{ + /* Multiply by 2 because these are edges indices. */ + const int start = mr->edge_len * 2; + const int len = mr->edge_loose_len * 2; + GPU_indexbuf_create_subrange_in_place( + mr->cache->final.ibo.lines_loose, mr->cache->final.ibo.lines, start, len); + mr->cache->no_loose_wire = (len == 0); +} + +static const MeshExtract extract_lines_loose = { + extract_lines_loose_init, + NULL, + NULL, + NULL, + NULL, + NULL, + extract_lines_loose_ledge_mesh, + NULL, + NULL, + extract_lines_loose_finish, + 0, + false, +}; + +/** \} */ + +/* ---------------------------------------------------------------------- */ /** \name Extract Point Indices * \{ */ @@ -4370,6 +4409,7 @@ void mesh_buffer_cache_create_requested(MeshBatchCache *cache, TEST_ASSIGN(IBO, ibo, fdots); TEST_ASSIGN(IBO, ibo, lines_paint_mask); TEST_ASSIGN(IBO, ibo, lines_adjacency); + TEST_ASSIGN(IBO, ibo, lines_loose); TEST_ASSIGN(IBO, ibo, edituv_tris); TEST_ASSIGN(IBO, ibo, edituv_lines); TEST_ASSIGN(IBO, ibo, edituv_points); @@ -4451,6 +4491,12 @@ void mesh_buffer_cache_create_requested(MeshBatchCache *cache, BLI_task_pool_work_and_wait(task_pool); BLI_task_pool_free(task_pool); + /* The `lines_loose` is a sub buffer from `ibo.lines`. + * We don't use the extract mechanism due to potential synchronization issues.*/ + if (mbc.ibo.lines_loose) { + extract_task_create(NULL, mr, &extract_lines_loose, mbc.ibo.lines_loose, task_counters); + } + MEM_freeN(task_counters); mesh_render_data_free(mr); diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index dd6749638a7..7c7178eae85 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -1228,7 +1228,8 @@ void DRW_mesh_batch_cache_create_requested( DRW_vbo_request(cache->batch.all_edges, &mbufcache->vbo.pos_nor); } if (DRW_batch_requested(cache->batch.loose_edges, GPU_PRIM_LINES)) { - DRW_ibo_request(cache->batch.loose_edges, &mbufcache->ibo.lines); + DRW_ibo_request(NULL, &mbufcache->ibo.lines); + DRW_ibo_request(cache->batch.loose_edges, &mbufcache->ibo.lines_loose); DRW_vbo_request(cache->batch.loose_edges, &mbufcache->vbo.pos_nor); } if (DRW_batch_requested(cache->batch.edge_detection, GPU_PRIM_LINES_ADJ)) { diff --git a/source/blender/draw/intern/draw_cache_inline.h b/source/blender/draw/intern/draw_cache_inline.h index 12dc0a47a68..f14d23dafcf 100644 --- a/source/blender/draw/intern/draw_cache_inline.h +++ b/source/blender/draw/intern/draw_cache_inline.h @@ -72,8 +72,10 @@ BLI_INLINE void DRW_ibo_request(GPUBatch *batch, GPUIndexBuf **ibo) if (*ibo == NULL) { *ibo = MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf"); } - GPU_batch_vao_cache_clear(batch); - batch->elem = *ibo; + if (batch != NULL) { + GPU_batch_vao_cache_clear(batch); + batch->elem = *ibo; + } } BLI_INLINE bool DRW_ibo_requested(GPUIndexBuf *ibo) diff --git a/source/blender/gpu/GPU_element.h b/source/blender/gpu/GPU_element.h index 75caf4cbd6a..996ade3e0f6 100644 --- a/source/blender/gpu/GPU_element.h +++ b/source/blender/gpu/GPU_element.h @@ -90,6 +90,10 @@ void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *, GPUIndexBuf *); /* Create a subrange of an existing indexbuffer. */ GPUIndexBuf *GPU_indexbuf_create_subrange(GPUIndexBuf *ibo, uint start, uint length); +void GPU_indexbuf_create_subrange_in_place(GPUIndexBuf *r_ibo, + GPUIndexBuf *ibo, + uint start, + uint length); void GPU_indexbuf_discard(GPUIndexBuf *); diff --git a/source/blender/gpu/intern/gpu_element.c b/source/blender/gpu/intern/gpu_element.c index 518829d1c78..036588b4a48 100644 --- a/source/blender/gpu/intern/gpu_element.c +++ b/source/blender/gpu/intern/gpu_element.c @@ -242,6 +242,15 @@ void GPU_indexbuf_set_tri_restart(GPUIndexBufBuilder *builder, uint elem) GPUIndexBuf *GPU_indexbuf_create_subrange(GPUIndexBuf *elem_src, uint start, uint length) { GPUIndexBuf *elem = MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf"); + GPU_indexbuf_create_subrange_in_place(elem, elem_src, start, length); + return elem; +} + +void GPU_indexbuf_create_subrange_in_place(GPUIndexBuf *elem, + GPUIndexBuf *elem_src, + uint start, + uint length) +{ BLI_assert(elem_src && !elem_src->is_subrange); BLI_assert((length == 0) || (start + length <= elem_src->index_len)); #if GPU_TRACK_INDEX_RANGE @@ -253,7 +262,6 @@ GPUIndexBuf *GPU_indexbuf_create_subrange(GPUIndexBuf *elem_src, uint start, uin elem->src = elem_src; elem->index_start = start; elem->index_len = length; - return elem; } #if GPU_TRACK_INDEX_RANGE |