diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2022-05-15 16:20:27 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2022-05-15 16:22:47 +0300 |
commit | 3e989e8c8de6e80ace4713e5de685f94f672f287 (patch) | |
tree | 02acd2c4054771877c123ff65ee41a8b4f27a9d3 | |
parent | b44cec0eca8bb191abba3396dedd9a79e23386ef (diff) |
GPUVertBuf: Add support for binding as buffer texture
This is often needed and somehow cumbersome to set up. This will allow some
code simplifications.
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 6 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.h | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_data.c | 25 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_exec.c | 6 | ||||
-rw-r--r-- | source/blender/gpu/GPU_vertex_buffer.h | 1 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_vertex_buffer.cc | 5 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_vertex_buffer_private.hh | 1 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_vertex_buffer.cc | 14 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_vertex_buffer.hh | 5 |
9 files changed, 64 insertions, 1 deletions
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 8c840ac3875..279830b1adf 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -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) \ diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index 2d0837370b2..aa0c472be04 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -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 */ diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index b0d8017940f..161a097d154 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -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); diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 2c5b02f88a9..e7e0e0ce41f 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -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; diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h index fe6ed7eaf87..722ef878271 100644 --- a/source/blender/gpu/GPU_vertex_buffer.h +++ b/source/blender/gpu/GPU_vertex_buffer.h @@ -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); diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.cc b/source/blender/gpu/intern/gpu_vertex_buffer.cc index 13f409cfba5..f47970d48d1 100644 --- a/source/blender/gpu/intern/gpu_vertex_buffer.cc +++ b/source/blender/gpu/intern/gpu_vertex_buffer.cc @@ -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); diff --git a/source/blender/gpu/intern/gpu_vertex_buffer_private.hh b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh index e5b70de9dfa..7a0b53cf958 100644 --- a/source/blender/gpu/intern/gpu_vertex_buffer_private.hh +++ b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh @@ -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; diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.cc b/source/blender/gpu/opengl/gl_vertex_buffer.cc index a7a0c92431f..6942a220892 100644 --- a/source/blender/gpu/opengl/gl_vertex_buffer.cc +++ b/source/blender/gpu/opengl/gl_vertex_buffer.cc @@ -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()); diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.hh b/source/blender/gpu/opengl/gl_vertex_buffer.hh index 4c29c17dcf7..88d2a455778 100644 --- a/source/blender/gpu/opengl/gl_vertex_buffer.hh +++ b/source/blender/gpu/opengl/gl_vertex_buffer.hh @@ -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; |