Cleanup: Rearrange code in in mesh draw position extraction

Extract mesh logic to a separate function, and reorder subdiv loose
geometry extraction function. This is mainly to make a future diff
clearer. Also rename a variable to use more typical naming.
This commit is contained in:
Hans Goudey
2024-05-22 10:30:29 -04:00
parent 9ae4f8a598
commit 556c321500
3 changed files with 79 additions and 76 deletions

View File

@@ -729,7 +729,6 @@ 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.points)) {
struct TaskData {
MeshRenderData &mr;

View File

@@ -330,12 +330,12 @@ template<typename GPUType> void convert_normals(Span<float3> src, MutableSpan<GP
template<typename T>
void extract_mesh_loose_edge_data(const Span<T> vert_data,
const Span<int2> edges,
const Span<int> loose_edge_indices,
const Span<int> loose_edges,
MutableSpan<T> gpu_data)
{
threading::parallel_for(loose_edge_indices.index_range(), 4096, [&](const IndexRange range) {
threading::parallel_for(loose_edges.index_range(), 4096, [&](const IndexRange range) {
for (const int i : range) {
const int2 edge = edges[loose_edge_indices[i]];
const int2 edge = edges[loose_edges[i]];
gpu_data[i * 2 + 0] = vert_data[edge[0]];
gpu_data[i * 2 + 1] = vert_data[edge[1]];
}

View File

@@ -18,6 +18,22 @@ 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);
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::memory_bandwidth_bound_task(
mr.vert_positions.size_in_bytes() + mr.corner_verts.size_in_bytes() +
vbo_data.size_in_bytes() + mr.loose_edges.size(),
[&]() {
array_utils::gather(mr.vert_positions, mr.corner_verts, corners_data);
extract_mesh_loose_edge_data(mr.vert_positions, mr.edges, mr.loose_edges, loose_edge_data);
array_utils::gather(mr.vert_positions, mr.loose_verts, loose_vert_data);
});
}
static void extract_pos_init(const MeshRenderData &mr,
MeshBatchCache & /*cache*/,
void *buf,
@@ -34,19 +50,7 @@ static void extract_pos_init(const MeshRenderData &mr,
MutableSpan vbo_data(static_cast<float3 *>(GPU_vertbuf_get_data(vbo)),
GPU_vertbuf_get_vertex_len(vbo));
if (mr.extract_type == MR_EXTRACT_MESH) {
threading::memory_bandwidth_bound_task(
mr.vert_positions.size_in_bytes() + mr.corner_verts.size_in_bytes() +
vbo_data.size_in_bytes() + mr.loose_edges.size(),
[&]() {
array_utils::gather(
mr.vert_positions, mr.corner_verts, vbo_data.take_front(mr.corner_verts.size()));
extract_mesh_loose_edge_data(mr.vert_positions,
mr.edges,
mr.loose_edges,
vbo_data.slice(mr.corners_num, mr.loose_edges.size() * 2));
array_utils::gather(
mr.vert_positions, mr.loose_verts, vbo_data.take_back(mr.loose_verts.size()));
});
extract_positions_mesh(mr, vbo_data);
}
else {
*static_cast<float3 **>(tls_data) = vbo_data.data();
@@ -127,6 +131,65 @@ 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*/)
{
const Span<int> loose_verts = mr.loose_verts;
const int loose_edges_num = mr.loose_edges.size();
if (loose_verts.is_empty() && loose_edges_num == 0) {
return;
}
gpu::VertBuf *vbo = static_cast<gpu::VertBuf *>(buffer);
/* TODO(@kevindietrich): replace this when compressed normals are supported. */
struct SubdivPosNorLoop {
float pos[3];
float nor[3];
float flag;
};
/* Make sure buffer is active for sending loose data. */
GPU_vertbuf_use(vbo);
const int resolution = subdiv_cache.resolution;
const Span<float3> cached_positions = subdiv_cache.loose_edge_positions;
const int verts_per_edge = subdiv_verts_per_coarse_edge(subdiv_cache);
const int edges_per_edge = subdiv_edges_per_coarse_edge(subdiv_cache);
const int loose_geom_start = subdiv_cache.num_subdiv_loops;
SubdivPosNorLoop edge_data[2];
memset(edge_data, 0, sizeof(SubdivPosNorLoop) * 2);
for (const int i : IndexRange(loose_edges_num)) {
const int edge_offset = loose_geom_start + i * verts_per_edge;
const Span<float3> positions = cached_positions.slice(i * resolution, resolution);
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,
(edge_offset + edge * 2) * sizeof(SubdivPosNorLoop),
sizeof(SubdivPosNorLoop) * 2,
&edge_data);
}
}
const int loose_verts_start = loose_geom_start + loose_edges_num * verts_per_edge;
const Span<float3> positions = mr.vert_positions;
SubdivPosNorLoop vert_data;
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,
(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,
@@ -219,65 +282,6 @@ static void extract_pos_init_subdiv(const DRWSubdivCache &subdiv_cache,
GPU_vertbuf_discard(flags_buffer);
}
static void extract_pos_loose_geom_subdiv(const DRWSubdivCache &subdiv_cache,
const MeshRenderData &mr,
void *buffer,
void * /*data*/)
{
const Span<int> loose_verts = mr.loose_verts;
const int loose_edges_num = mr.loose_edges.size();
if (loose_verts.is_empty() && loose_edges_num == 0) {
return;
}
gpu::VertBuf *vbo = static_cast<gpu::VertBuf *>(buffer);
/* TODO(@kevindietrich): replace this when compressed normals are supported. */
struct SubdivPosNorLoop {
float pos[3];
float nor[3];
float flag;
};
/* Make sure buffer is active for sending loose data. */
GPU_vertbuf_use(vbo);
const int resolution = subdiv_cache.resolution;
const Span<float3> cached_positions = subdiv_cache.loose_edge_positions;
const int verts_per_edge = subdiv_verts_per_coarse_edge(subdiv_cache);
const int edges_per_edge = subdiv_edges_per_coarse_edge(subdiv_cache);
const int loose_geom_start = subdiv_cache.num_subdiv_loops;
SubdivPosNorLoop edge_data[2];
memset(edge_data, 0, sizeof(SubdivPosNorLoop) * 2);
for (const int i : IndexRange(loose_edges_num)) {
const int edge_offset = loose_geom_start + i * verts_per_edge;
const Span<float3> positions = cached_positions.slice(i * resolution, resolution);
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,
(edge_offset + edge * 2) * sizeof(SubdivPosNorLoop),
sizeof(SubdivPosNorLoop) * 2,
&edge_data);
}
}
const int loose_verts_start = loose_geom_start + loose_edges_num * verts_per_edge;
const Span<float3> positions = mr.vert_positions;
SubdivPosNorLoop vert_data;
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,
(loose_verts_start + i) * sizeof(SubdivPosNorLoop),
sizeof(SubdivPosNorLoop),
&vert_data);
}
}
constexpr MeshExtract create_extractor_pos()
{
MeshExtract extractor = {nullptr};