Revert "Draw: Avoid temporary copy for mesh triangulation index buffer"

This reverts commit 108ab1df2d.

This causes issues when duplicating objects that I don't have time
to investigate right now.
This commit is contained in:
Hans Goudey
2024-05-23 23:16:06 -04:00
parent 701acd01b1
commit da1ea4cdd1
6 changed files with 16 additions and 44 deletions

View File

@@ -23,14 +23,7 @@ static void extract_tris_mesh(const MeshRenderData &mr,
const Span<int3> corner_tris = mr.mesh->corner_tris();
if (!face_sorted.face_tri_offsets) {
/* There are no hidden faces and no reordering is necessary to group triangles with the same
* material. The corner indices from #Mesh::corner_tris() can be copied directly to the GPU
* without the usual CPU-side copy owned by the index buffer. Crucially, this assumes that the
* data is uploaded to the GPU *before* the dependency graph's evaluated state is cleared (and
* with it, the evaluated mesh's triangulation data).
*
* Eventually these local copies should be completely removed, and code should write directly
* to GPU memory, but even then it could be helpful to know that the data already exists
* contiguously, owned elsewhere by Blender. */
* material. The corner indices from #Mesh::corner_tris() can be copied directly to the GPU. */
BLI_assert(face_sorted.visible_tris_num == corner_tris.size());
GPU_indexbuf_build_in_place_from_memory(&ibo,
GPU_PRIM_TRIS,

View File

@@ -53,8 +53,6 @@ class IndexBuf {
bool is_subrange_ = false;
/** True if buffer only contains restart indices. */
bool is_empty_ = false;
/** #data_ is read-only, not owned by an index buffer. */
bool reference_data_ = false;
union {
/** Mapped buffer data. non-NULL indicates not yet sent to VRAM. */
@@ -72,8 +70,7 @@ class IndexBuf {
uint min_index,
uint max_index,
GPUPrimType prim_type,
bool uses_restart_indices,
bool reference_data);
bool uses_restart_indices);
void init_subrange(IndexBuf *elem_src, uint start, uint length);
void init_build_on_device(uint index_len);

View File

@@ -315,15 +315,13 @@ void IndexBuf::init(uint indices_len,
uint min_index,
uint max_index,
GPUPrimType prim_type,
bool uses_restart_indices,
bool reference_data)
bool uses_restart_indices)
{
is_init_ = true;
data_ = indices;
index_start_ = 0;
index_len_ = indices_len;
is_empty_ = min_index > max_index;
reference_data_ = reference_data;
/* Patch index buffer to remove restart indices from
* non-restart-compatible primitive types. Restart indices
@@ -494,8 +492,7 @@ void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *builder, IndexBuf *elem)
builder->index_min,
builder->index_max,
builder->prim_type,
builder->uses_restart_indices,
false);
builder->uses_restart_indices);
builder->data = nullptr;
}
@@ -513,8 +510,7 @@ void GPU_indexbuf_build_in_place_ex(GPUIndexBufBuilder *builder,
index_min,
index_max,
builder->prim_type,
uses_restart_indices,
false);
uses_restart_indices);
builder->data = nullptr;
}
@@ -526,16 +522,15 @@ void GPU_indexbuf_build_in_place_from_memory(IndexBuf *ibo,
const int32_t index_max,
const bool uses_restart_indices)
{
/* If restart indices are used, they need to be stripped on Metal which would require a copy. */
BLI_assert(!uses_restart_indices);
const uint32_t indices_num = data_len * indices_per_primitive(prim_type);
ibo->init(indices_num,
const_cast<uint32_t *>(data),
index_min,
index_max,
prim_type,
uses_restart_indices,
true);
/* TODO: The need for this copy is meant to be temporary. The data should be uploaded directly to
* the GPU here rather than copied to an array owned by the IBO first. */
uint32_t *copy = static_cast<uint32_t *>(
MEM_malloc_arrayN(indices_num, sizeof(uint32_t), __func__));
threading::memory_bandwidth_bound_task(sizeof(uint32_t) * indices_num * 2, [&]() {
array_utils::copy(Span(data, indices_num), MutableSpan(copy, indices_num));
});
ibo->init(indices_num, copy, index_min, index_max, prim_type, uses_restart_indices);
}
void GPU_indexbuf_create_subrange_in_place(IndexBuf *elem,

View File

@@ -139,10 +139,7 @@ void MTLIndexBuf::upload_data()
}
/* No need to keep copy of data_ in system memory. */
if (reference_data_) {
data_ = nullptr;
}
else {
if (data_) {
MEM_SAFE_FREE(data_);
}
}

View File

@@ -36,12 +36,7 @@ void GLIndexBuf::bind()
/* Sends data to GPU. */
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data_, GL_STATIC_DRAW);
/* No need to keep copy of data in system memory. */
if (reference_data_) {
data_ = nullptr;
}
else {
MEM_SAFE_FREE(data_);
}
MEM_SAFE_FREE(data_);
}
}

View File

@@ -33,12 +33,7 @@ void VKIndexBuffer::ensure_updated()
VKStagingBuffer staging_buffer(buffer_, VKStagingBuffer::Direction::HostToDevice);
staging_buffer.host_buffer_get().update(data_);
staging_buffer.copy_to_device(context);
if (reference_data_) {
data_ = nullptr;
}
else {
MEM_SAFE_FREE(data_);
}
MEM_SAFE_FREE(data_);
}
void VKIndexBuffer::upload_data()