Mesh: Draw: Replace extractor abstraction for face dots index buffer

Part of #116901.
Very similar to 07eac30070.
This commit is contained in:
Hans Goudey
2024-06-01 09:55:30 -04:00
committed by Hans Goudey
parent 28c41b1d42
commit ef91db222e
3 changed files with 72 additions and 81 deletions

View File

@@ -659,7 +659,6 @@ void mesh_buffer_cache_create_requested(TaskGraph &task_graph,
}
EXTRACT_ADD_REQUESTED(vbo, attr_viewer);
EXTRACT_ADD_REQUESTED(ibo, fdots);
EXTRACT_ADD_REQUESTED(ibo, lines_paint_mask);
EXTRACT_ADD_REQUESTED(ibo, lines_adjacency);
EXTRACT_ADD_REQUESTED(ibo, edituv_tris);
@@ -671,12 +670,13 @@ void mesh_buffer_cache_create_requested(TaskGraph &task_graph,
if (extractors.is_empty() && !DRW_ibo_requested(buffers.ibo.lines) &&
!DRW_ibo_requested(buffers.ibo.lines_loose) && !DRW_ibo_requested(buffers.ibo.tris) &&
!DRW_ibo_requested(buffers.ibo.points) && !DRW_vbo_requested(buffers.vbo.pos) &&
!DRW_vbo_requested(buffers.vbo.nor) && !DRW_vbo_requested(buffers.vbo.vnor) &&
!DRW_vbo_requested(buffers.vbo.fdots_nor) && !DRW_vbo_requested(buffers.vbo.tan) &&
!DRW_vbo_requested(buffers.vbo.edit_data) && !DRW_vbo_requested(buffers.vbo.face_idx) &&
!DRW_vbo_requested(buffers.vbo.edge_idx) && !DRW_vbo_requested(buffers.vbo.vert_idx) &&
!DRW_vbo_requested(buffers.vbo.fdot_idx) && !DRW_vbo_requested(buffers.vbo.weights))
!DRW_ibo_requested(buffers.ibo.points) && !DRW_ibo_requested(buffers.ibo.fdots) &&
!DRW_vbo_requested(buffers.vbo.pos) && !DRW_vbo_requested(buffers.vbo.nor) &&
!DRW_vbo_requested(buffers.vbo.vnor) && !DRW_vbo_requested(buffers.vbo.fdots_nor) &&
!DRW_vbo_requested(buffers.vbo.tan) && !DRW_vbo_requested(buffers.vbo.edit_data) &&
!DRW_vbo_requested(buffers.vbo.face_idx) && !DRW_vbo_requested(buffers.vbo.edge_idx) &&
!DRW_vbo_requested(buffers.vbo.vert_idx) && !DRW_vbo_requested(buffers.vbo.fdot_idx) &&
!DRW_vbo_requested(buffers.vbo.weights))
{
return;
}
@@ -826,6 +826,21 @@ void mesh_buffer_cache_create_requested(TaskGraph &task_graph,
[](void *task_data) { delete static_cast<TaskData *>(task_data); });
BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
}
if (DRW_ibo_requested(buffers.ibo.fdots)) {
struct TaskData {
MeshRenderData &mr;
MeshBufferList &buffers;
};
TaskNode *task_node = BLI_task_graph_node_create(
&task_graph,
[](void *__restrict task_data) {
const TaskData &data = *static_cast<TaskData *>(task_data);
extract_face_dots(data.mr, *data.buffers.ibo.fdots);
},
new TaskData{*mr, buffers},
[](void *task_data) { delete static_cast<TaskData *>(task_data); });
BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
}
if (DRW_vbo_requested(buffers.vbo.edit_data)) {
struct TaskData {
MeshRenderData &mr;

View File

@@ -427,7 +427,8 @@ void extract_weights_subdiv(const MeshRenderData &mr,
const MeshBatchCache &cache,
gpu::VertBuf &vbo);
extern const MeshExtract extract_fdots;
void extract_face_dots(const MeshRenderData &mr, gpu::IndexBuf &face_dots);
extern const MeshExtract extract_lines_paint_mask;
extern const MeshExtract extract_lines_adjacency;
extern const MeshExtract extract_edituv_tris;

View File

@@ -11,88 +11,63 @@
#include "extract_mesh.hh"
namespace blender::draw {
/* ---------------------------------------------------------------------- */
/** \name Extract Face-dots Indices
* \{ */
static void extract_fdots_init(const MeshRenderData &mr,
MeshBatchCache & /*cache*/,
void * /*buf*/,
void *tls_data)
static IndexMask calc_face_visibility_mesh(const MeshRenderData &mr, IndexMaskMemory &memory)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(tls_data);
GPU_indexbuf_init(elb, GPU_PRIM_POINTS, mr.faces_num, mr.faces_num);
}
static void extract_fdots_iter_face_bm(const MeshRenderData & /*mr*/,
const BMFace *f,
const int f_index,
void *_userdata)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
GPU_indexbuf_set_point_vert(elb, f_index, f_index);
IndexMask visible(mr.faces_num);
if (!mr.hide_poly.is_empty()) {
visible = IndexMask::from_bools_inverse(visible, mr.hide_poly, memory);
}
else {
GPU_indexbuf_set_point_restart(elb, f_index);
}
}
static void extract_fdots_iter_face_mesh(const MeshRenderData &mr,
const int face_index,
void *_userdata)
{
const bool hidden = mr.use_hide && !mr.hide_poly.is_empty() && mr.hide_poly[face_index];
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
if (mr.use_subsurf_fdots) {
const OffsetIndices faces = mr.faces;
const Span<int> corner_verts = mr.corner_verts;
const BitSpan facedot_tags = mr.mesh->runtime->subsurf_face_dot_tags;
visible = IndexMask::from_predicate(visible, GrainSize(4096), memory, [&](const int i) {
const Span<int> face_verts = corner_verts.slice(faces[i]);
return std::any_of(face_verts.begin(), face_verts.end(), [&](const int vert) {
return facedot_tags[vert];
});
});
}
return visible;
}
for (const int corner : mr.faces[face_index]) {
const int vert = mr.corner_verts[corner];
if (facedot_tags[vert] && !hidden) {
GPU_indexbuf_set_point_vert(elb, face_index, face_index);
return;
}
}
GPU_indexbuf_set_point_restart(elb, face_index);
static void index_mask_to_ibo(const IndexMask &mask, gpu::IndexBuf &ibo)
{
const int max_index = mask.min_array_size();
GPUIndexBufBuilder builder;
GPU_indexbuf_init(&builder, GPU_PRIM_POINTS, mask.size(), max_index);
MutableSpan<uint> data = GPU_indexbuf_get_data(&builder);
mask.to_indices<int>(data.cast<int>());
GPU_indexbuf_build_in_place_ex(&builder, 0, max_index, false, &ibo);
}
static void extract_face_dots_mesh(const MeshRenderData &mr, gpu::IndexBuf &face_dots)
{
IndexMaskMemory memory;
const IndexMask visible_faces = calc_face_visibility_mesh(mr, memory);
index_mask_to_ibo(visible_faces, face_dots);
}
static void extract_face_dots_bm(const MeshRenderData &mr, gpu::IndexBuf &face_dots)
{
BMesh &bm = *mr.bm;
IndexMaskMemory memory;
const IndexMask visible_faces = IndexMask::from_predicate(
IndexRange(bm.totface), GrainSize(4096), memory, [&](const int i) {
return !BM_elem_flag_test_bool(BM_face_at_index(&bm, i), BM_ELEM_HIDDEN);
});
index_mask_to_ibo(visible_faces, face_dots);
}
void extract_face_dots(const MeshRenderData &mr, gpu::IndexBuf &face_dots)
{
if (mr.extract_type == MR_EXTRACT_MESH) {
extract_face_dots_mesh(mr, face_dots);
}
else {
if (!hidden) {
GPU_indexbuf_set_point_vert(elb, face_index, face_index);
}
else {
GPU_indexbuf_set_point_restart(elb, face_index);
}
extract_face_dots_bm(mr, face_dots);
}
}
static void extract_fdots_finish(const MeshRenderData & /*mr*/,
MeshBatchCache & /*cache*/,
void *buf,
void *_userdata)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
gpu::IndexBuf *ibo = static_cast<gpu::IndexBuf *>(buf);
GPU_indexbuf_build_in_place(elb, ibo);
}
constexpr MeshExtract create_extractor_fdots()
{
MeshExtract extractor = {nullptr};
extractor.init = extract_fdots_init;
extractor.iter_face_bm = extract_fdots_iter_face_bm;
extractor.iter_face_mesh = extract_fdots_iter_face_mesh;
extractor.finish = extract_fdots_finish;
extractor.data_type = MR_DATA_NONE;
extractor.data_size = sizeof(GPUIndexBufBuilder);
extractor.use_threading = false;
extractor.mesh_buffer_offset = offsetof(MeshBufferList, ibo.fdots);
return extractor;
}
/** \} */
const MeshExtract extract_fdots = create_extractor_fdots();
} // namespace blender::draw