7becc38a3c introduced new text rendering.
In the refactoring the vertex buffer was replaced by a more shallow
storage buffer. However the refactoring removed one optimization that
the vulkan backend uses, namely the actual amount of bytes that is being
used by the draw call. This resulted in overly large data transfers.
For example in the text editor the texts are rendered one glyph at a
time. But the storage buffer would always upload the data for 1024
glyphs.
This PR allows the usage size of a storage buffer to be set to ensure
that the data transfers are limited.
The implementation wasn't added to OpenGL as it draws incorrectly.
Issue detected during the research of !146956 That PR will implement
better data streaming inside the Vulkan backend and also requires
to know the actual usage size of the buffer to detect what data can
be grouped together.
Pull Request: https://projects.blender.org/blender/blender/pulls/146958
142 lines
3.2 KiB
C++
142 lines
3.2 KiB
C++
/* SPDX-FileCopyrightText: 2022 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
#include <cstring>
|
|
|
|
#include "BLI_string.h"
|
|
|
|
#include "BKE_global.hh"
|
|
|
|
#include "gpu_backend.hh"
|
|
|
|
#include "GPU_storage_buffer.hh"
|
|
#include "GPU_vertex_buffer.hh" /* For GPUUsageType. */
|
|
|
|
#include "gpu_context_private.hh"
|
|
#include "gpu_storage_buffer_private.hh"
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Creation & Deletion
|
|
* \{ */
|
|
|
|
namespace blender::gpu {
|
|
|
|
StorageBuf::StorageBuf(size_t size, const char *name)
|
|
{
|
|
size_in_bytes_ = usage_size_in_bytes_ = size;
|
|
STRNCPY(name_, name);
|
|
}
|
|
|
|
StorageBuf::~StorageBuf()
|
|
{
|
|
MEM_SAFE_FREE(data_);
|
|
}
|
|
|
|
void StorageBuf::usage_size_set(size_t usage_size)
|
|
{
|
|
BLI_assert(usage_size <= size_in_bytes_);
|
|
usage_size_in_bytes_ = usage_size;
|
|
}
|
|
|
|
} // namespace blender::gpu
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name C-API
|
|
* \{ */
|
|
|
|
using namespace blender::gpu;
|
|
|
|
blender::gpu::StorageBuf *GPU_storagebuf_create_ex(size_t size,
|
|
const void *data,
|
|
GPUUsageType usage,
|
|
const char *name)
|
|
{
|
|
StorageBuf *ssbo = GPUBackend::get()->storagebuf_alloc(size, usage, name);
|
|
/* Direct init. */
|
|
if (data != nullptr) {
|
|
ssbo->update(data);
|
|
}
|
|
else if (G.debug & G_DEBUG_GPU) {
|
|
/* Fill the buffer with poison values.
|
|
* (NaN for floats, -1 for `int` and "max value" for `uint`). */
|
|
blender::Vector<uchar> uninitialized_data(size, 0xFF);
|
|
ssbo->update(uninitialized_data.data());
|
|
}
|
|
|
|
return ssbo;
|
|
}
|
|
|
|
void GPU_storagebuf_free(blender::gpu::StorageBuf *ssbo)
|
|
{
|
|
delete ssbo;
|
|
}
|
|
|
|
void GPU_storagebuf_usage_size_set(blender::gpu::StorageBuf *ssbo, size_t usage_size)
|
|
{
|
|
ssbo->usage_size_set(usage_size);
|
|
}
|
|
|
|
void GPU_storagebuf_update(blender::gpu::StorageBuf *ssbo, const void *data)
|
|
{
|
|
ssbo->update(data);
|
|
}
|
|
|
|
void GPU_storagebuf_bind(blender::gpu::StorageBuf *ssbo, int slot)
|
|
{
|
|
ssbo->bind(slot);
|
|
}
|
|
|
|
void GPU_storagebuf_unbind(blender::gpu::StorageBuf *ssbo)
|
|
{
|
|
ssbo->unbind();
|
|
}
|
|
|
|
void GPU_storagebuf_debug_unbind_all()
|
|
{
|
|
Context::get()->debug_unbind_all_ssbo();
|
|
}
|
|
|
|
void GPU_storagebuf_clear_to_zero(blender::gpu::StorageBuf *ssbo)
|
|
{
|
|
GPU_storagebuf_clear(ssbo, 0);
|
|
}
|
|
|
|
void GPU_storagebuf_clear(blender::gpu::StorageBuf *ssbo, uint32_t clear_value)
|
|
{
|
|
ssbo->clear(clear_value);
|
|
}
|
|
|
|
void GPU_storagebuf_copy_sub_from_vertbuf(blender::gpu::StorageBuf *ssbo,
|
|
blender::gpu::VertBuf *src,
|
|
uint dst_offset,
|
|
uint src_offset,
|
|
uint copy_size)
|
|
{
|
|
ssbo->copy_sub(src, dst_offset, src_offset, copy_size);
|
|
}
|
|
|
|
void GPU_storagebuf_sync_to_host(blender::gpu::StorageBuf *ssbo)
|
|
{
|
|
ssbo->async_flush_to_host();
|
|
}
|
|
|
|
void GPU_storagebuf_read(blender::gpu::StorageBuf *ssbo, void *data)
|
|
{
|
|
ssbo->read(data);
|
|
}
|
|
|
|
void GPU_storagebuf_sync_as_indirect_buffer(blender::gpu::StorageBuf *ssbo)
|
|
{
|
|
ssbo->sync_as_indirect_buffer();
|
|
}
|
|
|
|
/** \} */
|