DRW: Batch Cache: Mesh: Port more batches to batch request method

This commit is contained in:
2018-12-09 11:21:23 +01:00
parent 1d92888ee8
commit ae1f563899

View File

@@ -948,6 +948,22 @@ static MeshRenderData *mesh_render_data_create_ex(
return rdata;
}
/* Warning replace mesh pointer. */
#define MBC_GET_FINAL_MESH(mesh) do { \
/* Hack to show the final result. */ \
const bool use_em_final = ( \
(mesh)->edit_btmesh && \
(mesh)->edit_btmesh->mesh_eval_final && \
((mesh)->edit_btmesh->mesh_eval_final->runtime.is_original == false)); \
Mesh me_fake; \
if (use_em_final) { \
me_fake = *(mesh)->edit_btmesh->mesh_eval_final; \
me_fake.mat = (mesh)->mat; \
me_fake.totcol = (mesh)->totcol; \
(mesh) = &me_fake; \
} \
} while (0)
static void mesh_render_data_free(MeshRenderData *rdata)
{
if (rdata->is_orco_allocated) {
@@ -2001,13 +2017,27 @@ bool DRW_mesh_weight_state_compare(const struct DRW_MeshWeightState *a, const st
* \{ */
typedef struct MeshBatchCache {
GPUVertBuf *pos_in_order;
/* Vert buffers. */
GPUVertBuf *pos_and_nor;
/* Tesselated: (all verts specified for each triangles).
* Indices does not match the CPU data structure's. */
struct {
GPUVertBuf *pos_and_nor;
GPUVertBuf *wireframe_data;
} tess;
GPUBatch *all_verts;
GPUBatch *face_wireframe; /* Triangles for object mode wireframe. */
/* Indices buffers. */
GPUIndexBuf *edges_in_order;
GPUIndexBuf *edges_adjacency; /* Store edges with adjacent vertices. */
GPUIndexBuf *triangles_in_order;
GPUIndexBuf *ledges_in_order;
GPUBatch *all_verts;
GPUBatch *all_edges;
GPUBatch *all_triangles;
@@ -2049,8 +2079,6 @@ typedef struct MeshBatchCache {
GPUBatch *edge_detection;
GPUVertBuf *edges_face_overlay_data;
GPUBatch *edges_face_overlay;
/* Maybe have shaded_triangles_data split into pos_nor and uv_tangent
* to minimize data transfer for skinned mesh. */
@@ -2406,7 +2434,7 @@ static void mesh_batch_cache_clear(Mesh *me)
GPU_BATCH_DISCARD_SAFE(cache->all_edges);
GPU_BATCH_DISCARD_SAFE(cache->all_triangles);
GPU_VERTBUF_DISCARD_SAFE(cache->pos_in_order);
GPU_VERTBUF_DISCARD_SAFE(cache->pos_and_nor);
GPU_INDEXBUF_DISCARD_SAFE(cache->edges_in_order);
GPU_INDEXBUF_DISCARD_SAFE(cache->triangles_in_order);
GPU_INDEXBUF_DISCARD_SAFE(cache->ledges_in_order);
@@ -2457,8 +2485,9 @@ static void mesh_batch_cache_clear(Mesh *me)
GPU_INDEXBUF_DISCARD_SAFE(cache->edges_adjacency);
GPU_BATCH_DISCARD_SAFE(cache->edge_detection);
GPU_VERTBUF_DISCARD_SAFE(cache->edges_face_overlay_data);
GPU_BATCH_DISCARD_SAFE(cache->edges_face_overlay);
GPU_VERTBUF_DISCARD_SAFE(cache->tess.wireframe_data);
GPU_VERTBUF_DISCARD_SAFE(cache->tess.pos_and_nor);
GPU_BATCH_DISCARD_SAFE(cache->face_wireframe);
mesh_batch_cache_discard_shaded_tri(cache);
@@ -2795,13 +2824,8 @@ static GPUVertBuf *mesh_batch_cache_get_tri_uv_active(
return cache->tri_aligned_uv;
}
static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex(
MeshRenderData *rdata, const bool use_hide,
GPUVertBuf **r_vbo)
static void mesh_create_pos_and_nor_tess(MeshRenderData *rdata, GPUVertBuf *vbo, bool use_hide)
{
BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
if (*r_vbo == NULL) {
static GPUVertFormat format = { 0 };
static struct { uint pos, nor; } attr_id;
if (format.attr_len == 0) {
@@ -2810,10 +2834,9 @@ static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex(
GPU_vertformat_triple_load(&format);
}
GPU_vertbuf_init_with_format(vbo, &format);
const int tri_len = mesh_render_data_looptri_len_get_maybe_mapped(rdata);
GPUVertBuf *vbo = *r_vbo = GPU_vertbuf_create_with_format(&format);
const int vbo_len_capacity = tri_len * 3;
int vbo_len_used = 0;
GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
@@ -2997,6 +3020,17 @@ static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex(
GPU_vertbuf_data_resize(vbo, vbo_len_used);
}
}
static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex(
MeshRenderData *rdata, const bool use_hide,
GPUVertBuf **r_vbo)
{
BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
if (*r_vbo == NULL) {
*r_vbo = GPU_vertbuf_create(GPU_USAGE_STATIC);
mesh_create_pos_and_nor_tess(rdata, *r_vbo, use_hide);
}
return *r_vbo;
}
@@ -3672,12 +3706,12 @@ static GPUVertBuf *mesh_batch_cache_get_vert_pos_and_nor_in_order(
{
BLI_assert(rdata->types & MR_DATATYPE_VERT);
if (cache->pos_in_order == NULL) {
cache->pos_in_order = GPU_vertbuf_create(GPU_USAGE_STATIC);
mesh_create_pos_and_nor(rdata, cache->pos_in_order);
if (cache->pos_and_nor == NULL) {
cache->pos_and_nor = GPU_vertbuf_create(GPU_USAGE_STATIC);
mesh_create_pos_and_nor(rdata, cache->pos_and_nor);
}
return cache->pos_in_order;
return cache->pos_and_nor;
}
static GPUVertFormat *edit_mesh_overlay_pos_format(uint *r_pos_id)
@@ -4311,20 +4345,18 @@ static EdgeHash *create_looptri_edge_adjacency_hash(MeshRenderData *rdata, EdgeA
return eh;
}
static GPUVertBuf *mesh_batch_cache_create_edges_wireframe_data(MeshRenderData *rdata, MeshBatchCache *cache)
static void mesh_create_wireframe_data_tess(MeshRenderData *rdata, GPUVertBuf *vbo)
{
if (cache->edges_face_overlay_data != NULL) {
return cache->edges_face_overlay_data;
static uint data_id;
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
data_id = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
GPU_vertformat_triple_load(&format);
}
GPU_vertbuf_init_with_format(vbo, &format);
const int tri_len = mesh_render_data_looptri_len_get(rdata);
GPUVertFormat format = {0};
uint index_id = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
GPU_vertformat_triple_load(&format);
GPUVertBuf *vbo = cache->edges_face_overlay_data = GPU_vertbuf_create_with_format(&format);
int vbo_len_capacity = tri_len * 3;
GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
@@ -4399,13 +4431,12 @@ static GPUVertBuf *mesh_batch_cache_create_edges_wireframe_data(MeshRenderData *
}
for (int e = 0; e < 3; e++) {
GPU_vertbuf_attr_set(vbo, index_id, vidx++, &vdata[e]);
GPU_vertbuf_attr_set(vbo, data_id, vidx++, &vdata[e]);
}
}
BLI_edgehash_free(eh, NULL);
MEM_freeN(adj_data);
return vbo;
}
static GPUIndexBuf *mesh_batch_cache_get_triangles_in_order(MeshRenderData *rdata, MeshBatchCache *cache)
@@ -5069,33 +5100,7 @@ GPUBatch *DRW_mesh_batch_cache_get_edge_detection(Mesh *me, bool *r_is_manifold)
GPUBatch *DRW_mesh_batch_cache_get_wireframes_face(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
if (cache->edges_face_overlay == NULL) {
const int options = MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI | MR_DATATYPE_POLY;
/* Hack to show the final result. */
const bool use_em_final = (
me->edit_btmesh &&
me->edit_btmesh->mesh_eval_final &&
(me->edit_btmesh->mesh_eval_final->runtime.is_original == false));
Mesh me_fake;
if (use_em_final) {
me_fake = *me->edit_btmesh->mesh_eval_final;
me_fake.mat = me->mat;
me_fake.totcol = me->totcol;
me = &me_fake;
}
MeshRenderData *rdata = mesh_render_data_create(me, options);
cache->edges_face_overlay = GPU_batch_create(
GPU_PRIM_TRIS, mesh_batch_cache_create_edges_wireframe_data(rdata, cache), NULL);
GPU_batch_vertbuf_add(cache->edges_face_overlay, mesh_batch_cache_get_tri_pos_and_normals_final(rdata, cache, false));
mesh_render_data_free(rdata);
}
return cache->edges_face_overlay;
return DRW_batch_request(&cache->face_wireframe);
}
static void mesh_batch_cache_create_overlay_batches(Mesh *me)
@@ -6017,23 +6022,42 @@ void DRW_mesh_batch_cache_create_requested(Object *ob)
{
BLI_assert(ob->type == OB_MESH);
const bool use_hide = false; /* TODO */
Mesh *me = (Mesh *)ob->data;
MeshBatchCache *cache = mesh_batch_cache_get(me);
/* Init batches and request VBOs & IBOs */
if (DRW_batch_requested(cache->all_verts, GPU_PRIM_POINTS)) {
DRW_vbo_request(cache->all_verts, &cache->pos_in_order);
DRW_vbo_request(cache->all_verts, &cache->pos_and_nor);
}
if (DRW_batch_requested(cache->face_wireframe, GPU_PRIM_TRIS)) {
DRW_vbo_request(cache->face_wireframe, &cache->tess.wireframe_data);
DRW_vbo_request(cache->face_wireframe, &cache->tess.pos_and_nor);
}
/* Generate MeshRenderData flags */
int mr_flag = 0;
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->pos_in_order, MR_DATATYPE_VERT);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->pos_and_nor, MR_DATATYPE_VERT);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.pos_and_nor, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI | MR_DATATYPE_POLY);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.wireframe_data, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
Mesh *me_original = me;
MBC_GET_FINAL_MESH(me);
UNUSED_VARS(me_original);
MeshRenderData *rdata = mesh_render_data_create(me, mr_flag);
/* Generate VBOs */
if (DRW_vbo_requested(cache->pos_in_order)) {
mesh_create_pos_and_nor(rdata, cache->pos_in_order);
if (DRW_vbo_requested(cache->pos_and_nor)) {
mesh_create_pos_and_nor(rdata, cache->pos_and_nor);
}
if (DRW_vbo_requested(cache->tess.wireframe_data)) {
mesh_create_wireframe_data_tess(rdata, cache->tess.wireframe_data);
}
if (DRW_vbo_requested(cache->tess.pos_and_nor)) {
mesh_create_pos_and_nor_tess(rdata, cache->tess.pos_and_nor, use_hide);
}
mesh_render_data_free(rdata);