GPU: UniformBuf: Add GPU_uniformbuf_clear_to_zero

This allows clearing the entire buffer directly on GPU.
This commit is contained in:
Clément Foucault
2022-11-15 20:15:04 +01:00
parent b8fd474bb1
commit a9a5f7ce17
8 changed files with 52 additions and 0 deletions
+2
View File
@@ -43,6 +43,8 @@ void GPU_uniformbuf_bind_as_ssbo(GPUUniformBuf *ubo, int slot);
void GPU_uniformbuf_unbind(GPUUniformBuf *ubo);
void GPU_uniformbuf_unbind_all(void);
void GPU_uniformbuf_clear_to_zero(GPUUniformBuf *ubo);
#define GPU_UBO_BLOCK_NAME "node_tree"
#define GPU_ATTRIBUTE_UBO_BLOCK_NAME "unf_attrs"
#define GPU_LAYER_ATTRIBUTE_UBO_BLOCK_NAME "drw_layer_attrs"
@@ -233,4 +233,9 @@ void GPU_uniformbuf_unbind_all()
/* FIXME */
}
void GPU_uniformbuf_clear_to_zero(GPUUniformBuf *ubo)
{
unwrap(ubo)->clear_to_zero();
}
/** \} */
@@ -38,6 +38,7 @@ class UniformBuf {
virtual ~UniformBuf();
virtual void update(const void *data) = 0;
virtual void clear_to_zero() = 0;
virtual void bind(int slot) = 0;
virtual void bind_as_ssbo(int slot) = 0;
virtual void unbind() = 0;
@@ -81,6 +81,14 @@ void MTLUniformBuf::update(const void *data)
}
}
void MTLUniformBuf::clear_to_zero()
{
/* TODO(fclem): Avoid another allocation and just do the clear on the GPU if possible. */
void *clear_data = calloc(size_in_bytes_);
this->update(clear_data);
free(clear_data);
}
void MTLUniformBuf::bind(int slot)
{
if (slot < 0) {
@@ -10,6 +10,7 @@
#include "gpu_context_private.hh"
#include "gl_debug.hh"
#include "gl_texture.hh"
#include "gl_uniform_buffer.hh"
namespace blender::gpu {
@@ -56,6 +57,35 @@ void GLUniformBuf::update(const void *data)
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
void GLUniformBuf::clear_to_zero()
{
if (ubo_id_ == 0) {
this->init();
}
uint32_t data = 0;
eGPUTextureFormat internal_format = GPU_R32UI;
eGPUDataFormat data_format = GPU_DATA_UINT;
if (GLContext::direct_state_access_support) {
glClearNamedBufferData(ubo_id_,
to_gl_internal_format(internal_format),
to_gl_data_format(internal_format),
to_gl(data_format),
&data);
}
else {
/* WATCH(@fclem): This should be ok since we only use clear outside of drawing functions. */
glBindBuffer(GL_UNIFORM_BUFFER, ubo_id_);
glClearBufferData(GL_UNIFORM_BUFFER,
to_gl_internal_format(internal_format),
to_gl_data_format(internal_format),
to_gl(data_format),
&data);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
}
/** \} */
/* -------------------------------------------------------------------- */
@@ -29,6 +29,7 @@ class GLUniformBuf : public UniformBuf {
~GLUniformBuf();
void update(const void *data) override;
void clear_to_zero() override;
void bind(int slot) override;
void bind_as_ssbo(int slot) override;
void unbind() override;
@@ -13,6 +13,10 @@ void VKUniformBuffer::update(const void * /*data*/)
{
}
void VKUniformBuffer::clear_to_zero()
{
}
void VKUniformBuffer::bind(int /*slot*/)
{
}
@@ -18,6 +18,7 @@ class VKUniformBuffer : public UniformBuf {
}
void update(const void *data) override;
void clear_to_zero() override;
void bind(int slot) override;
void bind_as_ssbo(int slot) override;
void unbind() override;