diff options
-rw-r--r-- | source/blender/draw/intern/draw_cache_extract.h | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_extract_mesh.c | 6 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 35 |
3 files changed, 19 insertions, 24 deletions
diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h index 2094da0328b..a0679ba6442 100644 --- a/source/blender/draw/intern/draw_cache_extract.h +++ b/source/blender/draw/intern/draw_cache_extract.h @@ -142,6 +142,8 @@ typedef struct MeshBufferCache { GPUIndexBuf *edituv_points; GPUIndexBuf *edituv_fdots; } ibo; + /* Index buffer per material. These are subranges of `ibo.tris` */ + GPUIndexBuf **tris_per_mat; } MeshBufferCache; typedef enum DRWBatchFlag { diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c index 0d0fadee1a4..c1f1c8b77e3 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.c +++ b/source/blender/draw/intern/draw_cache_extract_mesh.c @@ -901,19 +901,19 @@ static void extract_tris_finish(const MeshRenderData *mr, { MeshExtract_Tri_Data *data = _data; GPU_indexbuf_build_in_place(&data->elb, ibo); + /* HACK: Create ibo sub-ranges and assign them to each #GPUBatch. */ /* The `surface_per_mat` tests are there when object shading type is set to Wire or Bounds. In * these cases there isn't a surface per material. */ if (mr->use_final_mesh && cache->surface_per_mat && cache->surface_per_mat[0]) { + MeshBufferCache *mbc = &cache->final; for (int i = 0; i < mr->mat_len; i++) { /* Multiply by 3 because these are triangle indices. */ const int mat_start = data->tri_mat_start[i]; const int mat_end = data->tri_mat_end[i]; const int start = mat_start * 3; const int len = (mat_end - mat_start) * 3; - GPUIndexBuf *sub_ibo = GPU_indexbuf_create_subrange(ibo, start, len); - /* WARNING: We modify the #GPUBatch here! */ - GPU_batch_elembuf_set(cache->surface_per_mat[i], sub_ibo, true); + GPU_indexbuf_create_subrange_in_place(mbc->tris_per_mat[i], ibo, start, len); } } MEM_freeN(data->tri_mat_start); diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 64879f438e3..0da132a8cab 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -496,6 +496,10 @@ static void mesh_batch_cache_init(Mesh *me) cache->mat_len = mesh_render_mat_len_get(me); cache->surface_per_mat = MEM_callocN(sizeof(*cache->surface_per_mat) * cache->mat_len, __func__); + FOREACH_MESH_BUFFER_CACHE (cache, mbufcache) { + mbufcache->tris_per_mat = MEM_callocN(sizeof(*mbufcache->tris_per_mat) * cache->mat_len, + __func__); + } cache->is_dirty = false; cache->batch_ready = 0; @@ -703,6 +707,15 @@ static void mesh_batch_cache_clear(Mesh *me) for (int i = 0; i < sizeof(mbufcache->ibo) / sizeof(void *); i++) { GPU_INDEXBUF_DISCARD_SAFE(ibos[i]); } + + BLI_assert((mbufcache->tris_per_mat != NULL) || (cache->mat_len == 0)); + BLI_assert((mbufcache->tris_per_mat != NULL) && (cache->mat_len > 0)); + if (mbufcache->tris_per_mat) { + for (int i = 0; i < cache->mat_len; i++) { + GPU_INDEXBUF_DISCARD_SAFE(mbufcache->tris_per_mat[i]); + } + MEM_SAFE_FREE(mbufcache->tris_per_mat); + } } for (int i = 0; i < sizeof(cache->batch) / sizeof(void *); i++) { GPUBatch **batch = (GPUBatch **)&cache->batch; @@ -1168,7 +1181,6 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, const bool use_hide) { BLI_assert(task_graph); - GPUIndexBuf **saved_elem_ranges = NULL; const ToolSettings *ts = NULL; if (scene) { ts = scene->toolsettings; @@ -1254,17 +1266,6 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.vcol); } } - /* XXX save element buffer to avoid recreating them. - * This is only if the cd_needed changes so it is ok to keep them.*/ - if (cache->surface_per_mat[0] && cache->surface_per_mat[0]->elem) { - saved_elem_ranges = MEM_callocN(sizeof(saved_elem_ranges) * cache->mat_len, __func__); - for (int i = 0; i < cache->mat_len; i++) { - saved_elem_ranges[i] = cache->surface_per_mat[i]->elem; - /* Avoid deletion as the batch is owner. */ - cache->surface_per_mat[i]->elem = NULL; - cache->surface_per_mat[i]->flag &= ~GPU_BATCH_OWNS_INDEX; - } - } /* We can't discard batches at this point as they have been * referenced for drawing. Just clear them in place. */ for (int i = 0; i < cache->mat_len; i++) { @@ -1389,13 +1390,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, /* Per Material */ for (int i = 0; i < cache->mat_len; i++) { if (DRW_batch_requested(cache->surface_per_mat[i], GPU_PRIM_TRIS)) { - if (saved_elem_ranges && saved_elem_ranges[i]) { - /* XXX assign old element buffer range (it did not change).*/ - GPU_batch_elembuf_set(cache->surface_per_mat[i], saved_elem_ranges[i], true); - } - else { - DRW_ibo_request(cache->surface_per_mat[i], &mbufcache->ibo.tris); - } + DRW_ibo_request(cache->surface_per_mat[i], &mbufcache->tris_per_mat[i]); /* Order matters. First ones override latest VBO's attributes. */ DRW_vbo_request(cache->surface_per_mat[i], &mbufcache->vbo.lnor); DRW_vbo_request(cache->surface_per_mat[i], &mbufcache->vbo.pos_nor); @@ -1414,8 +1409,6 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, } } - MEM_SAFE_FREE(saved_elem_ranges); - mbufcache = (do_cage) ? &cache->cage : &cache->final; /* Edit Mesh */ |