diff --git a/source/blender/gpu/GPU_uniform_buffer.h b/source/blender/gpu/GPU_uniform_buffer.h index 448f416281b..f3319a594f7 100644 --- a/source/blender/gpu/GPU_uniform_buffer.h +++ b/source/blender/gpu/GPU_uniform_buffer.h @@ -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" diff --git a/source/blender/gpu/intern/gpu_uniform_buffer.cc b/source/blender/gpu/intern/gpu_uniform_buffer.cc index e2681a40d16..5d9e2af631e 100644 --- a/source/blender/gpu/intern/gpu_uniform_buffer.cc +++ b/source/blender/gpu/intern/gpu_uniform_buffer.cc @@ -233,4 +233,9 @@ void GPU_uniformbuf_unbind_all() /* FIXME */ } +void GPU_uniformbuf_clear_to_zero(GPUUniformBuf *ubo) +{ + unwrap(ubo)->clear_to_zero(); +} + /** \} */ diff --git a/source/blender/gpu/intern/gpu_uniform_buffer_private.hh b/source/blender/gpu/intern/gpu_uniform_buffer_private.hh index 5280f6f866c..5848e88fb72 100644 --- a/source/blender/gpu/intern/gpu_uniform_buffer_private.hh +++ b/source/blender/gpu/intern/gpu_uniform_buffer_private.hh @@ -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; diff --git a/source/blender/gpu/metal/mtl_uniform_buffer.mm b/source/blender/gpu/metal/mtl_uniform_buffer.mm index 133f156c0c9..dc57a0b19c6 100644 --- a/source/blender/gpu/metal/mtl_uniform_buffer.mm +++ b/source/blender/gpu/metal/mtl_uniform_buffer.mm @@ -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) { diff --git a/source/blender/gpu/opengl/gl_uniform_buffer.cc b/source/blender/gpu/opengl/gl_uniform_buffer.cc index 42e92520e4f..8007e6a4ec0 100644 --- a/source/blender/gpu/opengl/gl_uniform_buffer.cc +++ b/source/blender/gpu/opengl/gl_uniform_buffer.cc @@ -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); + } +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/gpu/opengl/gl_uniform_buffer.hh b/source/blender/gpu/opengl/gl_uniform_buffer.hh index a008164b70f..71297d1b1ec 100644 --- a/source/blender/gpu/opengl/gl_uniform_buffer.hh +++ b/source/blender/gpu/opengl/gl_uniform_buffer.hh @@ -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; diff --git a/source/blender/gpu/vulkan/vk_uniform_buffer.cc b/source/blender/gpu/vulkan/vk_uniform_buffer.cc index 5225f545178..89bbdc3264f 100644 --- a/source/blender/gpu/vulkan/vk_uniform_buffer.cc +++ b/source/blender/gpu/vulkan/vk_uniform_buffer.cc @@ -13,6 +13,10 @@ void VKUniformBuffer::update(const void * /*data*/) { } +void VKUniformBuffer::clear_to_zero() +{ +} + void VKUniformBuffer::bind(int /*slot*/) { } diff --git a/source/blender/gpu/vulkan/vk_uniform_buffer.hh b/source/blender/gpu/vulkan/vk_uniform_buffer.hh index 9959496921d..1a4978782f2 100644 --- a/source/blender/gpu/vulkan/vk_uniform_buffer.hh +++ b/source/blender/gpu/vulkan/vk_uniform_buffer.hh @@ -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;