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:
@@ -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) \
|
||||
|
@@ -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 */
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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());
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user