1
1

GPUVertBuf: Add support for binding as buffer texture

This is often needed and somehow cumbersome to set up. This will allow some
code simplifications.
This commit is contained in:
2022-05-15 15:20:27 +02:00
parent b44cec0eca
commit 3e989e8c8d
9 changed files with 64 additions and 1 deletions

View File

@@ -623,6 +623,12 @@ void DRW_shgroup_vertex_buffer_ex(DRWShadingGroup *shgroup,
void DRW_shgroup_vertex_buffer_ref_ex(DRWShadingGroup *shgroup,
const char *name,
struct GPUVertBuf **vertex_buffer DRW_DEBUG_FILE_LINE_ARGS);
void DRW_shgroup_buffer_texture_ex(DRWShadingGroup *shgroup,
const char *name,
struct GPUVertBuf *vertex_buffer);
void DRW_shgroup_buffer_texture_ref_ex(DRWShadingGroup *shgroup,
const char *name,
struct GPUVertBuf **vertex_buffer);
#ifdef DRW_UNUSED_RESOURCE_TRACKING
# define DRW_shgroup_vertex_buffer(shgroup, name, vert) \

View File

@@ -319,6 +319,8 @@ typedef enum {
DRW_UNIFORM_STORAGE_BLOCK,
DRW_UNIFORM_STORAGE_BLOCK_REF,
DRW_UNIFORM_TFEEDBACK_TARGET,
DRW_UNIFORM_VERTEX_BUFFER_AS_TEXTURE,
DRW_UNIFORM_VERTEX_BUFFER_AS_TEXTURE_REF,
DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE,
DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE_REF,
/** Per drawcall uniforms/UBO */

View File

@@ -547,6 +547,29 @@ void DRW_shgroup_vertex_buffer_ref_ex(DRWShadingGroup *shgroup,
shgroup, location, DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE_REF, vertex_buffer, 0, 0, 1);
}
void DRW_shgroup_buffer_texture_ex(DRWShadingGroup *shgroup,
const char *name,
GPUVertBuf *vertex_buffer)
{
int location = GPU_shader_get_ssbo(shgroup->shader, name);
if (location == -1) {
return;
}
drw_shgroup_uniform_create_ex(
shgroup, location, DRW_UNIFORM_VERTEX_BUFFER_AS_TEXTURE, vertex_buffer, 0, 0, 1);
}
void DRW_shgroup_buffer_texture_ref_ex(DRWShadingGroup *shgroup,
const char *name,
GPUVertBuf **vertex_buffer)
{
int location = GPU_shader_get_ssbo(shgroup->shader, name);
if (location == -1) {
return;
}
drw_shgroup_uniform_create_ex(
shgroup, location, DRW_UNIFORM_VERTEX_BUFFER_AS_TEXTURE_REF, vertex_buffer, 0, 0, 1);
}
/** \} */
/* -------------------------------------------------------------------- */
@@ -624,7 +647,7 @@ static void drw_call_obinfos_init(DRWObjectInfos *ob_infos, Object *ob)
drw_call_calc_orco(ob, ob_infos->orcotexfac);
/* Random float value. */
uint random = (DST.dupli_source) ?
DST.dupli_source->random_id :
DST.dupli_source->random_id :
/* TODO(fclem): this is rather costly to do at runtime. Maybe we can
* put it in ob->runtime and make depsgraph ensure it is up to date. */
BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0);

View File

@@ -693,6 +693,12 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup,
*use_tfeedback = GPU_shader_transform_feedback_enable(shgroup->shader,
((GPUVertBuf *)uni->pvalue));
break;
case DRW_UNIFORM_VERTEX_BUFFER_AS_TEXTURE_REF:
GPU_vertbuf_bind_as_texture(*uni->vertbuf_ref, uni->location);
break;
case DRW_UNIFORM_VERTEX_BUFFER_AS_TEXTURE:
GPU_vertbuf_bind_as_texture(uni->vertbuf, uni->location);
break;
case DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE_REF:
GPU_vertbuf_bind_as_ssbo(*uni->vertbuf_ref, uni->location);
break;

View File

@@ -165,6 +165,7 @@ void GPU_vertbuf_tag_dirty(GPUVertBuf *verts);
*/
void GPU_vertbuf_use(GPUVertBuf *);
void GPU_vertbuf_bind_as_ssbo(struct GPUVertBuf *verts, int binding);
void GPU_vertbuf_bind_as_texture(struct GPUVertBuf *verts, int binding);
void GPU_vertbuf_wrap_handle(GPUVertBuf *verts, uint64_t handle);

View File

@@ -328,6 +328,11 @@ void GPU_vertbuf_bind_as_ssbo(struct GPUVertBuf *verts, int binding)
unwrap(verts)->bind_as_ssbo(binding);
}
void GPU_vertbuf_bind_as_texture(struct GPUVertBuf *verts, int binding)
{
unwrap(verts)->bind_as_texture(binding);
}
void GPU_vertbuf_update_sub(GPUVertBuf *verts, uint start, uint len, const void *data)
{
unwrap(verts)->update_sub(start, len, data);

View File

@@ -51,6 +51,7 @@ class VertBuf {
void resize(uint vert_len);
void upload();
virtual void bind_as_ssbo(uint binding) = 0;
virtual void bind_as_texture(uint binding) = 0;
virtual void wrap_handle(uint64_t handle) = 0;

View File

@@ -5,6 +5,8 @@
* \ingroup gpu
*/
#include "GPU_texture.h"
#include "gl_context.hh"
#include "gl_vertex_buffer.hh"
@@ -38,6 +40,7 @@ void GLVertBuf::release_data()
}
if (vbo_id_ != 0) {
GPU_TEXTURE_FREE_SAFE(buffer_texture_);
GLContext::buf_free(vbo_id_);
vbo_id_ = 0;
memory_usage -= vbo_size_;
@@ -51,6 +54,7 @@ void GLVertBuf::duplicate_data(VertBuf *dst_)
BLI_assert(GLContext::get() != nullptr);
GLVertBuf *src = this;
GLVertBuf *dst = static_cast<GLVertBuf *>(dst_);
dst->buffer_texture_ = nullptr;
if (src->vbo_id_ != 0) {
dst->vbo_size_ = src->size_used_get();
@@ -111,6 +115,16 @@ void GLVertBuf::bind_as_ssbo(uint binding)
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, vbo_id_);
}
void GLVertBuf::bind_as_texture(uint binding)
{
bind();
BLI_assert(vbo_id_ != 0);
if (buffer_texture_ == nullptr) {
buffer_texture_ = GPU_texture_create_from_vertbuf("vertbuf_as_texture", wrap(this));
}
GPU_texture_bind(buffer_texture_, binding);
}
const void *GLVertBuf::read() const
{
BLI_assert(is_active());

View File

@@ -11,6 +11,8 @@
#include "glew-mx.h"
#include "GPU_texture.h"
#include "gpu_vertex_buffer_private.hh"
namespace blender {
@@ -23,6 +25,8 @@ class GLVertBuf : public VertBuf {
private:
/** OpenGL buffer handle. Init on first upload. Immutable after that. */
GLuint vbo_id_ = 0;
/** Texture used if the buffer is bound as buffer texture. Init on first use. */
struct ::GPUTexture *buffer_texture_ = nullptr;
/** Defines whether the buffer handle is wrapped by this GLVertBuf, i.e. we do not own it and
* should not free it. */
bool is_wrapper_ = false;
@@ -46,6 +50,7 @@ class GLVertBuf : public VertBuf {
void upload_data() override;
void duplicate_data(VertBuf *dst) override;
void bind_as_ssbo(uint binding) override;
void bind_as_texture(uint binding) override;
private:
bool is_active() const;