diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-09-07 02:20:55 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-09-07 14:59:51 +0300 |
commit | c38debd39fac1e3d44b84e8092419da34f0b613d (patch) | |
tree | bba08fc983f7e18025f4e09fa346737053ba4ed0 /source/blender/gpu/opengl | |
parent | bb2aeb4504907cab1cf8c4afc4dd1d6495c940e4 (diff) |
GPUVertBuf: GL Backend Isolation
Part of the Vulkan port T68990
This makes a few changes in how the data is being handled by the
backend to allow more flexibility in the future.
The overall code logic is left unchanged.
Diffstat (limited to 'source/blender/gpu/opengl')
-rw-r--r-- | source/blender/gpu/opengl/gl_shader.cc | 4 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_texture.cc | 4 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_vertex_array.cc | 4 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_vertex_buffer.cc | 69 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_vertex_buffer.hh | 15 |
5 files changed, 75 insertions, 21 deletions
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index 1d74400bc4c..9136a1d9714 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -270,9 +270,9 @@ bool GLShader::transform_feedback_enable(GPUVertBuf *buf_) GLVertBuf *buf = static_cast<GLVertBuf *>(unwrap(buf_)); - BLI_assert(buf->vbo_id != 0); + BLI_assert(buf->vbo_id_ != 0); - glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf->vbo_id); + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf->vbo_id_); switch (transform_feedback_type_) { case GPU_SHADER_TFB_POINTS: diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc index 6151a2fc73e..6cff97215e8 100644 --- a/source/blender/gpu/opengl/gl_texture.cc +++ b/source/blender/gpu/opengl/gl_texture.cc @@ -120,10 +120,10 @@ bool GLTexture::init_internal(GPUVertBuf *vbo) GLenum internal_format = to_gl_internal_format(format_); if (GLEW_ARB_direct_state_access) { - glTextureBuffer(tex_id_, internal_format, gl_vbo->vbo_id); + glTextureBuffer(tex_id_, internal_format, gl_vbo->vbo_id_); } else { - glTexBuffer(target_, internal_format, gl_vbo->vbo_id); + glTexBuffer(target_, internal_format, gl_vbo->vbo_id_); } #ifndef __APPLE__ diff --git a/source/blender/gpu/opengl/gl_vertex_array.cc b/source/blender/gpu/opengl/gl_vertex_array.cc index 463dc18cc60..4e49828d39d 100644 --- a/source/blender/gpu/opengl/gl_vertex_array.cc +++ b/source/blender/gpu/opengl/gl_vertex_array.cc @@ -122,7 +122,7 @@ void GLVertArray::update_bindings(const GLuint vao, for (int v = GPU_BATCH_VBO_MAX_LEN - 1; v > -1; v--) { GLVertBuf *vbo = batch->verts_(v); if (vbo) { - GPU_vertbuf_use(batch->verts[v]); + vbo->bind(); attr_mask &= ~vbo_bind(interface, &vbo->format, 0, vbo->vertex_len, false); } } @@ -130,7 +130,7 @@ void GLVertArray::update_bindings(const GLuint vao, for (int v = GPU_BATCH_INST_VBO_MAX_LEN - 1; v > -1; v--) { GLVertBuf *vbo = batch->inst_(v); if (vbo) { - GPU_vertbuf_use(batch->inst[v]); + vbo->bind(); attr_mask &= ~vbo_bind(interface, &vbo->format, base_instance, vbo->vertex_len, true); } } diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.cc b/source/blender/gpu/opengl/gl_vertex_buffer.cc index ee9e0a0b0c9..66ff1f36cef 100644 --- a/source/blender/gpu/opengl/gl_vertex_buffer.cc +++ b/source/blender/gpu/opengl/gl_vertex_buffer.cc @@ -27,30 +27,83 @@ namespace blender::gpu { -void GLVertBuf::bind(void) +void GLVertBuf::acquire_data(void) { + /* Discard previous data if any. */ + MEM_SAFE_FREE(data); + data = (uchar *)MEM_mallocN(sizeof(uchar) * this->size_alloc_get(), __func__); } -void GLVertBuf::upload_data(void) +void GLVertBuf::resize_data(void) { + data = (uchar *)MEM_reallocN(data, sizeof(uchar) * this->size_alloc_get()); } -uchar *GLVertBuf::acquire_data(void) +void GLVertBuf::release_data(void) { - return nullptr; + if (vbo_id_ != 0) { + GLBackend::get()->buf_free(vbo_id_); + vbo_id_ = 0; + memory_usage -= vbo_size_; + } + + MEM_SAFE_FREE(data); } -uchar *GLVertBuf::resize_data(void) +void GLVertBuf::duplicate_data(VertBuf *dst_) { - return nullptr; + BLI_assert(GPU_context_active_get() != NULL); + GLVertBuf *src = this; + GLVertBuf *dst = static_cast<GLVertBuf *>(dst_); + + if (src->vbo_id_ != 0) { + dst->vbo_size_ = src->size_used_get(); + + glGenBuffers(1, &dst->vbo_id_); + glBindBuffer(GL_COPY_WRITE_BUFFER, dst->vbo_id_); + glBufferData(GL_COPY_WRITE_BUFFER, dst->vbo_size_, NULL, to_gl(dst->usage_)); + + glBindBuffer(GL_COPY_READ_BUFFER, src->vbo_id_); + + glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, dst->vbo_size_); + + memory_usage += dst->vbo_size_; + } + + if (data != nullptr) { + dst->data = (uchar *)MEM_dupallocN(src->data); + } } -void GLVertBuf::release_data(void) +void GLVertBuf::upload_data(void) { + this->bind(); } -void GLVertBuf::duplicate_data(VertBuf *) +void GLVertBuf::bind(void) { + BLI_assert(GPU_context_active_get() != NULL); + + if (vbo_id_ == 0) { + glGenBuffers(1, &vbo_id_); + } + + glBindBuffer(GL_ARRAY_BUFFER, vbo_id_); + + if (flag & GPU_VERTBUF_DATA_DIRTY) { + vbo_size_ = this->size_used_get(); + /* Orphan the vbo to avoid sync then upload data. */ + glBufferData(GL_ARRAY_BUFFER, vbo_size_, NULL, to_gl(usage_)); + glBufferSubData(GL_ARRAY_BUFFER, 0, vbo_size_, data); + + memory_usage += vbo_size_; + + if (usage_ == GPU_USAGE_STATIC) { + MEM_SAFE_FREE(data); + } + flag &= ~GPU_VERTBUF_DATA_DIRTY; + flag |= GPU_VERTBUF_DATA_UPLOADED; + } } } // namespace blender::gpu
\ No newline at end of file diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.hh b/source/blender/gpu/opengl/gl_vertex_buffer.hh index 76c5e86a1c7..eee5222f467 100644 --- a/source/blender/gpu/opengl/gl_vertex_buffer.hh +++ b/source/blender/gpu/opengl/gl_vertex_buffer.hh @@ -37,19 +37,20 @@ class GLVertBuf : public VertBuf { friend class GLShader; /* For transform feedback. */ private: - // GLuint vbo_id_ = 0; + /** OpenGL buffer handle. Init on first upload. Immutable after that. */ + GLuint vbo_id_ = 0; /** Size on the GPU. */ - // size_t vbo_size_ = 0; + size_t vbo_size_ = 0; public: void bind(void); protected: - uchar *acquire_data(void); - uchar *resize_data(void); - void release_data(void); - void upload_data(void); - void duplicate_data(VertBuf *dst); + void acquire_data(void) override; + void resize_data(void) override; + void release_data(void) override; + void upload_data(void) override; + void duplicate_data(VertBuf *dst) override; MEM_CXX_CLASS_ALLOC_FUNCS("GLVertBuf"); }; |