GPU subdiv: reduce memory usage for point IBO

The point IBO should only have data for coarse vertices (or in general,
the vertices in the original mesh). As it used for displaying the
vertices for selection in edit mode, and as it indexes into the VBOs for
the positions and edit data, it is itself only indexed by coarse/
original vertex index.

For the subdivision case, this would allocate space for the final
subdivision vertex and reallocate to make room for loose geometry,
although only the first coarse vertex count amount of data would be.

Now just allocate for the required memory. Also reuse index buffer APIs
instead of doing manual work.
This commit is contained in:
Kévin Dietrich 2022-01-24 18:42:37 +01:00
parent 90d61600fc
commit e2337b5342
2 changed files with 9 additions and 15 deletions

View File

@ -752,9 +752,10 @@ static bool draw_subdiv_topology_info_cb(const SubdivForeachContext *foreach_con
cache->subdiv_loop_poly_index = static_cast<int *>(
MEM_mallocN(cache->num_subdiv_loops * sizeof(int), "subdiv_loop_poly_index"));
const int num_coarse_vertices = ctx->coarse_mesh->totvert;
cache->point_indices = static_cast<int *>(
MEM_mallocN(cache->num_subdiv_verts * sizeof(int), "point_indices"));
for (int i = 0; i < num_vertices; i++) {
MEM_mallocN(num_coarse_vertices * sizeof(int), "point_indices"));
for (int i = 0; i < num_coarse_vertices; i++) {
cache->point_indices[i] = -1;
}

View File

@ -157,7 +157,7 @@ static void extract_points_finish(const MeshRenderData *UNUSED(mr),
}
static void extract_points_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *UNUSED(mr),
const MeshRenderData *mr,
struct MeshBatchCache *UNUSED(cache),
void *UNUSED(buffer),
void *data)
@ -165,9 +165,9 @@ static void extract_points_init_subdiv(const DRWSubdivCache *subdiv_cache,
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(data);
/* Copy the points as the data upload will free them. */
elb->data = (uint *)MEM_dupallocN(subdiv_cache->point_indices);
elb->index_len = subdiv_cache->num_subdiv_verts;
elb->index_len = mr->vert_len;
elb->index_min = 0;
elb->index_max = subdiv_cache->num_subdiv_loops - 1;
elb->index_max = subdiv_cache->num_subdiv_loops + mr->loop_loose_len;
elb->prim_type = GPU_PRIM_POINTS;
}
@ -184,9 +184,6 @@ static void extract_points_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(data);
elb->data = static_cast<uint32_t *>(
MEM_reallocN(elb->data, sizeof(uint) * (subdiv_cache->num_subdiv_loops + loop_loose_len)));
const Mesh *coarse_mesh = subdiv_cache->mesh;
const MEdge *coarse_edges = coarse_mesh->medge;
@ -195,22 +192,18 @@ static void extract_points_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
for (int i = 0; i < loose_geom->edge_len; i++) {
const MEdge *loose_edge = &coarse_edges[loose_geom->edges[i]];
if (elb->data[loose_edge->v1] == -1u) {
elb->data[loose_edge->v1] = offset;
GPU_indexbuf_set_point_vert(elb, loose_edge->v1, offset);
}
if (elb->data[loose_edge->v2] == -1u) {
elb->data[loose_edge->v2] = offset + 1;
GPU_indexbuf_set_point_vert(elb, loose_edge->v2, offset + 1);
}
elb->index_max += 2;
elb->index_len += 2;
offset += 2;
}
for (int i = 0; i < loose_geom->vert_len; i++) {
if (elb->data[loose_geom->verts[i]] == -1u) {
elb->data[loose_geom->verts[i]] = offset;
GPU_indexbuf_set_point_vert(elb, loose_geom->verts[i], offset);
}
elb->index_max += 1;
elb->index_len += 1;
offset += 1;
}
}