GPU: UniformBuf: Add GPU_uniformbuf_clear_to_zero
This allows clearing the entire buffer directly on GPU.
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user