Draw: Replace extractor abstraction for mesh positions extraction
Part of #116901. The remaining change was to change the BMesh iteration to not use the extractor callbacks.
This commit is contained in:
@@ -616,7 +616,6 @@ void mesh_buffer_cache_create_requested(TaskGraph &task_graph,
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
EXTRACT_ADD_REQUESTED(vbo, pos);
|
||||
EXTRACT_ADD_REQUESTED(vbo, nor);
|
||||
EXTRACT_ADD_REQUESTED(vbo, uv);
|
||||
EXTRACT_ADD_REQUESTED(vbo, tan);
|
||||
@@ -656,7 +655,7 @@ 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_ibo_requested(buffers.ibo.points) && !DRW_vbo_requested(buffers.vbo.pos))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -692,6 +691,21 @@ void mesh_buffer_cache_create_requested(TaskGraph &task_graph,
|
||||
/* Simple heuristic. */
|
||||
const bool use_thread = (mr->corners_num + mr->loose_indices_num) > MIN_RANGE_LEN;
|
||||
|
||||
if (DRW_vbo_requested(buffers.vbo.pos)) {
|
||||
struct TaskData {
|
||||
MeshRenderData &mr;
|
||||
MeshBufferCache &mbc;
|
||||
};
|
||||
TaskNode *task_node = BLI_task_graph_node_create(
|
||||
&task_graph,
|
||||
[](void *__restrict task_data) {
|
||||
const TaskData &data = *static_cast<TaskData *>(task_data);
|
||||
extract_positions(data.mr, *data.mbc.buff.vbo.pos);
|
||||
},
|
||||
new TaskData{*mr, mbc},
|
||||
[](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.tris)) {
|
||||
struct TaskData {
|
||||
MeshRenderData &mr;
|
||||
@@ -833,11 +847,6 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Orcos are extracted at the same time as positions. */
|
||||
if (DRW_vbo_requested(buffers.vbo.pos) || DRW_vbo_requested(buffers.vbo.orco)) {
|
||||
extractors.append(&extract_pos);
|
||||
}
|
||||
|
||||
EXTRACT_ADD_REQUESTED(vbo, nor);
|
||||
for (int i = 0; i < GPU_MAX_ATTR; i++) {
|
||||
EXTRACT_ADD_REQUESTED(vbo, attr[i]);
|
||||
@@ -873,7 +882,8 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
|
||||
|
||||
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_ibo_requested(buffers.ibo.points) && !DRW_vbo_requested(buffers.vbo.pos) &&
|
||||
!DRW_vbo_requested(buffers.vbo.orco))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -883,6 +893,9 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
|
||||
mr, mbc, MR_ITER_LOOSE_EDGE | MR_ITER_LOOSE_VERT, MR_DATA_LOOSE_GEOM);
|
||||
DRW_subdivide_loose_geom(subdiv_cache, mbc);
|
||||
|
||||
if (DRW_vbo_requested(buffers.vbo.pos) || DRW_vbo_requested(buffers.vbo.orco)) {
|
||||
extract_positions_subdiv(subdiv_cache, mr, *buffers.vbo.pos, buffers.vbo.orco);
|
||||
}
|
||||
if (DRW_ibo_requested(buffers.ibo.lines) || DRW_ibo_requested(buffers.ibo.lines_loose)) {
|
||||
extract_lines_subdiv(
|
||||
subdiv_cache, mr, buffers.ibo.lines, buffers.ibo.lines_loose, cache.no_loose_wire);
|
||||
|
||||
@@ -342,6 +342,12 @@ void extract_mesh_loose_edge_data(const Span<T> vert_data,
|
||||
});
|
||||
}
|
||||
|
||||
void extract_positions(const MeshRenderData &mr, gpu::VertBuf &vbo);
|
||||
void extract_positions_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
const MeshRenderData &mr,
|
||||
gpu::VertBuf &vbo,
|
||||
gpu::VertBuf *orco_vbo);
|
||||
|
||||
void extract_tris(const MeshRenderData &mr,
|
||||
const SortedFaceData &face_sorted,
|
||||
MeshBatchCache &cache,
|
||||
@@ -372,7 +378,6 @@ extern const MeshExtract extract_edituv_tris;
|
||||
extern const MeshExtract extract_edituv_lines;
|
||||
extern const MeshExtract extract_edituv_points;
|
||||
extern const MeshExtract extract_edituv_fdots;
|
||||
extern const MeshExtract extract_pos;
|
||||
extern const MeshExtract extract_nor_hq;
|
||||
extern const MeshExtract extract_nor;
|
||||
extern const MeshExtract extract_uv;
|
||||
|
||||
@@ -14,10 +14,6 @@
|
||||
|
||||
namespace blender::draw {
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name Extract Position and Vertex Normal
|
||||
* \{ */
|
||||
|
||||
static void extract_positions_mesh(const MeshRenderData &mr, MutableSpan<float3> vbo_data)
|
||||
{
|
||||
MutableSpan corners_data = vbo_data.take_front(mr.corners_num);
|
||||
@@ -34,65 +30,62 @@ static void extract_positions_mesh(const MeshRenderData &mr, MutableSpan<float3>
|
||||
});
|
||||
}
|
||||
|
||||
static void extract_pos_init(const MeshRenderData &mr,
|
||||
MeshBatchCache & /*cache*/,
|
||||
void *buf,
|
||||
void *tls_data)
|
||||
static void extract_positions_bm(const MeshRenderData &mr, MutableSpan<float3> vbo_data)
|
||||
{
|
||||
const BMesh &bm = *mr.bm;
|
||||
MutableSpan corners_data = vbo_data.take_front(mr.corners_num);
|
||||
MutableSpan loose_edge_data = vbo_data.slice(mr.corners_num, mr.loose_edges.size() * 2);
|
||||
MutableSpan loose_vert_data = vbo_data.take_back(mr.loose_verts.size());
|
||||
|
||||
threading::parallel_for(IndexRange(bm.totface), 2048, [&](const IndexRange range) {
|
||||
for (const int face_index : range) {
|
||||
const BMFace &face = *BM_face_at_index(&const_cast<BMesh &>(bm), face_index);
|
||||
const BMLoop *loop = BM_FACE_FIRST_LOOP(&face);
|
||||
for ([[maybe_unused]] const int i : IndexRange(face.len)) {
|
||||
const int index = BM_elem_index_get(loop);
|
||||
corners_data[index] = bm_vert_co_get(mr, loop->v);
|
||||
loop = loop->next;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const Span<int> loose_edges = mr.loose_edges;
|
||||
threading::parallel_for(loose_edges.index_range(), 4096, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
const BMEdge &edge = *BM_edge_at_index(&const_cast<BMesh &>(bm), loose_edges[i]);
|
||||
loose_edge_data[i * 2 + 0] = bm_vert_co_get(mr, edge.v1);
|
||||
loose_edge_data[i * 2 + 1] = bm_vert_co_get(mr, edge.v2);
|
||||
}
|
||||
});
|
||||
|
||||
const Span<int> loose_verts = mr.loose_verts;
|
||||
threading::parallel_for(loose_verts.index_range(), 2048, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
const BMVert &vert = *BM_vert_at_index(&const_cast<BMesh &>(bm), loose_verts[i]);
|
||||
loose_vert_data[i] = bm_vert_co_get(mr, &vert);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void extract_positions(const MeshRenderData &mr, gpu::VertBuf &vbo)
|
||||
{
|
||||
gpu::VertBuf *vbo = static_cast<gpu::VertBuf *>(buf);
|
||||
static GPUVertFormat format = {0};
|
||||
if (format.attr_len == 0) {
|
||||
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
}
|
||||
GPU_vertbuf_init_with_format(vbo, &format);
|
||||
GPU_vertbuf_data_alloc(vbo, mr.corners_num + mr.loose_indices_num);
|
||||
GPU_vertbuf_init_with_format(&vbo, &format);
|
||||
GPU_vertbuf_data_alloc(&vbo, mr.corners_num + mr.loose_indices_num);
|
||||
|
||||
MutableSpan vbo_data(static_cast<float3 *>(GPU_vertbuf_get_data(vbo)),
|
||||
GPU_vertbuf_get_vertex_len(vbo));
|
||||
MutableSpan vbo_data(static_cast<float3 *>(GPU_vertbuf_get_data(&vbo)),
|
||||
GPU_vertbuf_get_vertex_len(&vbo));
|
||||
if (mr.extract_type == MR_EXTRACT_MESH) {
|
||||
extract_positions_mesh(mr, vbo_data);
|
||||
}
|
||||
else {
|
||||
*static_cast<float3 **>(tls_data) = vbo_data.data();
|
||||
extract_positions_bm(mr, vbo_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void extract_pos_iter_face_bm(const MeshRenderData &mr,
|
||||
const BMFace *f,
|
||||
const int /*f_index*/,
|
||||
void *_data)
|
||||
{
|
||||
float3 *data = *static_cast<float3 **>(_data);
|
||||
BMLoop *l_iter, *l_first;
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
const int l_index = BM_elem_index_get(l_iter);
|
||||
data[l_index] = bm_vert_co_get(mr, l_iter->v);
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
}
|
||||
|
||||
static void extract_pos_iter_loose_edge_bm(const MeshRenderData &mr,
|
||||
const BMEdge *eed,
|
||||
const int loose_edge_i,
|
||||
void *_data)
|
||||
{
|
||||
float3 *data = *static_cast<float3 **>(_data);
|
||||
int index = mr.corners_num + loose_edge_i * 2;
|
||||
data[index + 0] = bm_vert_co_get(mr, eed->v1);
|
||||
data[index + 1] = bm_vert_co_get(mr, eed->v2);
|
||||
}
|
||||
|
||||
static void extract_pos_iter_loose_vert_bm(const MeshRenderData &mr,
|
||||
const BMVert *eve,
|
||||
const int loose_vert_i,
|
||||
void *_data)
|
||||
{
|
||||
float3 *data = *static_cast<float3 **>(_data);
|
||||
const int offset = mr.corners_num + (mr.loose_edges_num * 2);
|
||||
const int index = offset + loose_vert_i;
|
||||
data[index] = bm_vert_co_get(mr, eve);
|
||||
}
|
||||
|
||||
static GPUVertFormat *get_normals_format()
|
||||
{
|
||||
static GPUVertFormat format = {0};
|
||||
@@ -131,10 +124,9 @@ static void extract_vertex_flags(const MeshRenderData &mr, char *flags)
|
||||
}
|
||||
}
|
||||
|
||||
static void extract_pos_loose_geom_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
const MeshRenderData &mr,
|
||||
void *buffer,
|
||||
void * /*data*/)
|
||||
static void extract_loose_positions_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
const MeshRenderData &mr,
|
||||
gpu::VertBuf &vbo)
|
||||
{
|
||||
const Span<int> loose_verts = mr.loose_verts;
|
||||
const int loose_edges_num = mr.loose_edges.size();
|
||||
@@ -142,8 +134,6 @@ static void extract_pos_loose_geom_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
return;
|
||||
}
|
||||
|
||||
gpu::VertBuf *vbo = static_cast<gpu::VertBuf *>(buffer);
|
||||
|
||||
/* TODO(@kevindietrich): replace this when compressed normals are supported. */
|
||||
struct SubdivPosNorLoop {
|
||||
float pos[3];
|
||||
@@ -152,7 +142,7 @@ static void extract_pos_loose_geom_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
};
|
||||
|
||||
/* Make sure buffer is active for sending loose data. */
|
||||
GPU_vertbuf_use(vbo);
|
||||
GPU_vertbuf_use(&vbo);
|
||||
|
||||
const int resolution = subdiv_cache.resolution;
|
||||
const Span<float3> cached_positions = subdiv_cache.loose_edge_positions;
|
||||
@@ -169,7 +159,7 @@ static void extract_pos_loose_geom_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
for (const int edge : IndexRange(edges_per_edge)) {
|
||||
copy_v3_v3(edge_data[0].pos, positions[edge + 0]);
|
||||
copy_v3_v3(edge_data[1].pos, positions[edge + 1]);
|
||||
GPU_vertbuf_update_sub(vbo,
|
||||
GPU_vertbuf_update_sub(&vbo,
|
||||
(edge_offset + edge * 2) * sizeof(SubdivPosNorLoop),
|
||||
sizeof(SubdivPosNorLoop) * 2,
|
||||
&edge_data);
|
||||
@@ -183,24 +173,20 @@ static void extract_pos_loose_geom_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
memset(&vert_data, 0, sizeof(SubdivPosNorLoop));
|
||||
for (const int i : loose_verts.index_range()) {
|
||||
copy_v3_v3(vert_data.pos, positions[loose_verts[i]]);
|
||||
GPU_vertbuf_update_sub(vbo,
|
||||
GPU_vertbuf_update_sub(&vbo,
|
||||
(loose_verts_start + i) * sizeof(SubdivPosNorLoop),
|
||||
sizeof(SubdivPosNorLoop),
|
||||
&vert_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void extract_pos_init_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
const MeshRenderData &mr,
|
||||
MeshBatchCache &cache,
|
||||
void *buffer,
|
||||
void * /*data*/)
|
||||
void extract_positions_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
const MeshRenderData &mr,
|
||||
gpu::VertBuf &vbo,
|
||||
gpu::VertBuf *orco_vbo)
|
||||
{
|
||||
gpu::VertBuf *vbo = static_cast<gpu::VertBuf *>(buffer);
|
||||
|
||||
/* Initialize the vertex buffer, it was already allocated. */
|
||||
GPU_vertbuf_init_build_on_device(
|
||||
vbo, draw_subdiv_get_pos_nor_format(), subdiv_full_vbo_size(mr, subdiv_cache));
|
||||
&vbo, draw_subdiv_get_pos_nor_format(), subdiv_full_vbo_size(mr, subdiv_cache));
|
||||
|
||||
if (subdiv_cache.num_subdiv_loops == 0) {
|
||||
return;
|
||||
@@ -217,8 +203,6 @@ static void extract_pos_init_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
extract_vertex_flags(mr, flags);
|
||||
GPU_vertbuf_tag_dirty(flags_buffer);
|
||||
|
||||
gpu::VertBuf *orco_vbo = cache.final.buff.vbo.orco;
|
||||
|
||||
if (orco_vbo) {
|
||||
static GPUVertFormat format = {0};
|
||||
if (format.attr_len == 0) {
|
||||
@@ -231,7 +215,7 @@ static void extract_pos_init_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
GPU_vertbuf_init_build_on_device(orco_vbo, &format, subdiv_cache.num_subdiv_loops);
|
||||
}
|
||||
|
||||
draw_subdiv_extract_pos_nor(subdiv_cache, flags_buffer, vbo, orco_vbo);
|
||||
draw_subdiv_extract_pos_nor(subdiv_cache, flags_buffer, &vbo, orco_vbo);
|
||||
|
||||
if (subdiv_cache.use_custom_loop_normals) {
|
||||
const Mesh *coarse_mesh = subdiv_cache.mesh;
|
||||
@@ -252,7 +236,7 @@ static void extract_pos_init_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
draw_subdiv_interp_custom_data(
|
||||
subdiv_cache, src_custom_normals, dst_custom_normals, GPU_COMP_F32, 3, 0);
|
||||
|
||||
draw_subdiv_finalize_custom_normals(subdiv_cache, dst_custom_normals, vbo);
|
||||
draw_subdiv_finalize_custom_normals(subdiv_cache, dst_custom_normals, &vbo);
|
||||
|
||||
GPU_vertbuf_discard(src_custom_normals);
|
||||
GPU_vertbuf_discard(dst_custom_normals);
|
||||
@@ -267,39 +251,21 @@ static void extract_pos_init_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
vert_normals, get_normals_format(), subdiv_cache.num_subdiv_verts);
|
||||
|
||||
draw_subdiv_accumulate_normals(subdiv_cache,
|
||||
vbo,
|
||||
&vbo,
|
||||
subdiv_cache.subdiv_vertex_face_adjacency_offsets,
|
||||
subdiv_cache.subdiv_vertex_face_adjacency,
|
||||
subdiv_loop_subdiv_vert_index,
|
||||
vert_normals);
|
||||
|
||||
draw_subdiv_finalize_normals(subdiv_cache, vert_normals, subdiv_loop_subdiv_vert_index, vbo);
|
||||
draw_subdiv_finalize_normals(subdiv_cache, vert_normals, subdiv_loop_subdiv_vert_index, &vbo);
|
||||
|
||||
GPU_vertbuf_discard(vert_normals);
|
||||
GPU_vertbuf_discard(subdiv_loop_subdiv_vert_index);
|
||||
}
|
||||
|
||||
GPU_vertbuf_discard(flags_buffer);
|
||||
|
||||
extract_loose_positions_subdiv(subdiv_cache, mr, vbo);
|
||||
}
|
||||
|
||||
constexpr MeshExtract create_extractor_pos()
|
||||
{
|
||||
MeshExtract extractor = {nullptr};
|
||||
extractor.init = extract_pos_init;
|
||||
extractor.iter_face_bm = extract_pos_iter_face_bm;
|
||||
extractor.iter_loose_edge_bm = extract_pos_iter_loose_edge_bm;
|
||||
extractor.iter_loose_vert_bm = extract_pos_iter_loose_vert_bm;
|
||||
extractor.init_subdiv = extract_pos_init_subdiv;
|
||||
extractor.iter_loose_geom_subdiv = extract_pos_loose_geom_subdiv;
|
||||
extractor.data_type = MR_DATA_NONE;
|
||||
extractor.data_size = sizeof(float3 *);
|
||||
extractor.use_threading = true;
|
||||
extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.pos);
|
||||
return extractor;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
const MeshExtract extract_pos = create_extractor_pos();
|
||||
|
||||
} // namespace blender::draw
|
||||
|
||||
Reference in New Issue
Block a user