diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-09-06 03:46:51 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-09-06 23:13:06 +0300 |
commit | 4ea93029c65fd4cdb8b707494855120c0f792952 (patch) | |
tree | a02801daaaf0f0a4e1bb7be84d34e27759b32a36 /source/blender/gpu/opengl | |
parent | 84d67bd0a937e842618ee7843958f3147ba6af58 (diff) |
GPUIndexBuf: GL backend Isolation
This is part of the Vulkan backend task T68990.
There is no real change, only making some code re-organisation.
This also make the IndexBuf completely abstract from outside the
GPU module.
Diffstat (limited to 'source/blender/gpu/opengl')
-rw-r--r-- | source/blender/gpu/opengl/gl_backend.hh | 6 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_batch.cc | 28 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_batch.hh | 8 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_drawlist.cc | 37 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_drawlist.hh | 2 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_index_buffer.cc | 62 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_index_buffer.hh | 68 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_vertex_array.cc | 3 |
8 files changed, 169 insertions, 45 deletions
diff --git a/source/blender/gpu/opengl/gl_backend.hh b/source/blender/gpu/opengl/gl_backend.hh index f769d9c1cfe..a31a4a45f56 100644 --- a/source/blender/gpu/opengl/gl_backend.hh +++ b/source/blender/gpu/opengl/gl_backend.hh @@ -31,6 +31,7 @@ #include "gl_context.hh" #include "gl_drawlist.hh" #include "gl_framebuffer.hh" +#include "gl_index_buffer.hh" #include "gl_shader.hh" #include "gl_texture.hh" #include "gl_uniform_buffer.hh" @@ -82,6 +83,11 @@ class GLBackend : public GPUBackend { return new GLFrameBuffer(name); }; + IndexBuf *indexbuf_alloc(void) + { + return new GLIndexBuf(); + }; + Shader *shader_alloc(const char *name) { return new GLShader(name); diff --git a/source/blender/gpu/opengl/gl_batch.cc b/source/blender/gpu/opengl/gl_batch.cc index bb7d5654efd..c735d02500b 100644 --- a/source/blender/gpu/opengl/gl_batch.cc +++ b/source/blender/gpu/opengl/gl_batch.cc @@ -34,12 +34,14 @@ #include "gpu_batch_private.hh" #include "gpu_shader_private.hh" -#include "gl_batch.hh" #include "gl_context.hh" #include "gl_debug.hh" +#include "gl_index_buffer.hh" #include "gl_primitive.hh" #include "gl_vertex_array.hh" +#include "gl_batch.hh" + using namespace blender::gpu; /* -------------------------------------------------------------------- */ @@ -295,14 +297,6 @@ GLBatch::~GLBatch() /** \name Drawing * \{ */ -#if GPU_TRACK_INDEX_RANGE -# define BASE_INDEX(el) ((el)->base_index) -# define INDEX_TYPE(el) ((el)->gl_index_type) -#else -# define BASE_INDEX(el) 0 -# define INDEX_TYPE(el) GL_UNSIGNED_INT -#endif - void GLBatch::bind(int i_first) { GPU_context_active_get()->state_manager->apply_state(); @@ -315,7 +309,7 @@ void GLBatch::bind(int i_first) #if GPU_TRACK_INDEX_RANGE /* Can be removed if GL 4.3 is required. */ if (!GLEW_ARB_ES3_compatibility && (elem != NULL)) { - glPrimitiveRestartIndex((elem->index_type == GPU_INDEX_U16) ? 0xFFFFu : 0xFFFFFFFFu); + glPrimitiveRestartIndex(this->gl_elem()->restart_index()); } #endif @@ -340,16 +334,10 @@ void GLBatch::draw(int v_first, int v_count, int i_first, int i_count) GLenum gl_type = to_gl(prim_type); if (elem) { - const GPUIndexBuf *el = elem; - GLenum index_type = INDEX_TYPE(el); - GLint base_index = BASE_INDEX(el); - void *v_first_ofs = (GLuint *)0 + v_first + el->index_start; - -#if GPU_TRACK_INDEX_RANGE - if (el->index_type == GPU_INDEX_U16) { - v_first_ofs = (GLushort *)0 + v_first + el->index_start; - } -#endif + const GLIndexBuf *el = this->gl_elem(); + GLenum index_type = to_gl(el->index_type_); + GLint base_index = el->index_base_; + void *v_first_ofs = el->offset_ptr(v_first); if (GPU_arb_base_instance_is_supported()) { glDrawElementsInstancedBaseVertexBaseInstance( diff --git a/source/blender/gpu/opengl/gl_batch.hh b/source/blender/gpu/opengl/gl_batch.hh index 9399148c68d..e6d9542fc3b 100644 --- a/source/blender/gpu/opengl/gl_batch.hh +++ b/source/blender/gpu/opengl/gl_batch.hh @@ -30,6 +30,8 @@ #include "gpu_batch_private.hh" +#include "gl_index_buffer.hh" + #include "glew-mx.h" namespace blender { @@ -99,6 +101,12 @@ class GLBatch : public Batch { void draw(int v_first, int v_count, int i_first, int i_count) override; void bind(int i_first); + /* Convenience getters. */ + GLIndexBuf *gl_elem(void) + { + return static_cast<GLIndexBuf *>(unwrap(elem)); + } + MEM_CXX_CLASS_ALLOC_FUNCS("GLBatch"); }; diff --git a/source/blender/gpu/opengl/gl_drawlist.cc b/source/blender/gpu/opengl/gl_drawlist.cc index 35fecc859b8..9670e580819 100644 --- a/source/blender/gpu/opengl/gl_drawlist.cc +++ b/source/blender/gpu/opengl/gl_drawlist.cc @@ -42,15 +42,6 @@ #define USE_MULTI_DRAW_INDIRECT 1 -/* TODO remove. */ -#if GPU_TRACK_INDEX_RANGE -# define BASE_INDEX(el) ((el)->base_index) -# define INDEX_TYPE(el) ((el)->gl_index_type) -#else -# define BASE_INDEX(el) 0 -# define INDEX_TYPE(el) GL_UNSIGNED_INT -#endif - using namespace blender::gpu; typedef struct GLDrawCommand { @@ -129,11 +120,11 @@ void GLDrawList::init(void) command_offset_ = 0; } -void GLDrawList::append(GPUBatch *batch, int i_first, int i_count) +void GLDrawList::append(GPUBatch *gpu_batch, int i_first, int i_count) { /* Fallback when MultiDrawIndirect is not supported/enabled. */ if (MDI_DISABLED) { - GPU_batch_draw_advanced(batch, 0, 0, i_first, i_count); + GPU_batch_draw_advanced(gpu_batch, 0, 0, i_first, i_count); return; } @@ -141,14 +132,16 @@ void GLDrawList::append(GPUBatch *batch, int i_first, int i_count) this->init(); } + GLBatch *batch = static_cast<GLBatch *>(gpu_batch); if (batch != batch_) { // BLI_assert(batch->flag | GPU_BATCH_INIT); this->submit(); batch_ = batch; /* Cached for faster access. */ - base_index_ = batch->elem ? BASE_INDEX(batch->elem) : UINT_MAX; - v_first_ = batch->elem ? batch->elem->index_start : 0; - v_count_ = batch->elem ? batch->elem->index_len : batch->verts[0]->vertex_len; + GLIndexBuf *el = batch_->gl_elem(); + base_index_ = el ? el->index_base_ : UINT_MAX; + v_first_ = el ? el->index_start_ : 0; + v_count_ = el ? el->index_len_ : batch->verts[0]->vertex_len; } if (v_count_ == 0) { @@ -191,12 +184,9 @@ void GLDrawList::submit(void) BLI_assert(data_); BLI_assert(GPU_context_active_get()->shader != NULL); - GLBatch *batch = static_cast<GLBatch *>(batch_); - /* Only do multi-draw indirect if doing more than 2 drawcall. This avoids the overhead of * buffer mapping if scene is not very instance friendly. BUT we also need to take into - * account the - * case where only a few instances are needed to finish filling a call buffer. */ + * account the case where only a few instances are needed to finish filling a call buffer. */ const bool is_finishing_a_buffer = (command_offset_ >= data_size_); if (command_len_ > 2 || is_finishing_a_buffer) { GLenum prim = to_gl(batch_->prim_type); @@ -208,10 +198,11 @@ void GLDrawList::submit(void) data_ = NULL; /* Unmapped */ data_offset_ += command_offset_; - batch->bind(0); + batch_->bind(0); if (MDI_INDEXED) { - glMultiDrawElementsIndirect(prim, INDEX_TYPE(batch_->elem), offset, command_len_, 0); + GLenum gl_type = to_gl(batch_->gl_elem()->index_type_); + glMultiDrawElementsIndirect(prim, gl_type, offset, command_len_, 0); } else { glMultiDrawArraysIndirect(prim, offset, command_len_, 0); @@ -223,8 +214,8 @@ void GLDrawList::submit(void) GLDrawCommandIndexed *cmd = (GLDrawCommandIndexed *)data_; for (int i = 0; i < command_len_; i++, cmd++) { /* Index start was already added. Avoid counting it twice. */ - cmd->v_first -= batch->elem->index_start; - batch->draw(cmd->v_first, cmd->v_count, cmd->i_first, cmd->i_count); + cmd->v_first -= v_first_; + batch_->draw(cmd->v_first, cmd->v_count, cmd->i_first, cmd->i_count); } /* Reuse the same data. */ command_offset_ -= command_len_ * sizeof(GLDrawCommandIndexed); @@ -232,7 +223,7 @@ void GLDrawList::submit(void) else { GLDrawCommand *cmd = (GLDrawCommand *)data_; for (int i = 0; i < command_len_; i++, cmd++) { - batch->draw(cmd->v_first, cmd->v_count, cmd->i_first, cmd->i_count); + batch_->draw(cmd->v_first, cmd->v_count, cmd->i_first, cmd->i_count); } /* Reuse the same data. */ command_offset_ -= command_len_ * sizeof(GLDrawCommand); diff --git a/source/blender/gpu/opengl/gl_drawlist.hh b/source/blender/gpu/opengl/gl_drawlist.hh index b690b8f8a98..3a731559e3a 100644 --- a/source/blender/gpu/opengl/gl_drawlist.hh +++ b/source/blender/gpu/opengl/gl_drawlist.hh @@ -55,7 +55,7 @@ class GLDrawList : public DrawList { void init(void); /** Batch for which we are recording commands for. */ - GPUBatch *batch_; + GLBatch *batch_; /** Mapped memory bounds. */ GLbyte *data_; /** Length of the mapped buffer (in byte). */ diff --git a/source/blender/gpu/opengl/gl_index_buffer.cc b/source/blender/gpu/opengl/gl_index_buffer.cc new file mode 100644 index 00000000000..03a9607a00b --- /dev/null +++ b/source/blender/gpu/opengl/gl_index_buffer.cc @@ -0,0 +1,62 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#include "gl_backend.hh" +#include "gl_debug.hh" + +#include "gl_index_buffer.hh" + +namespace blender::gpu { + +GLIndexBuf::~GLIndexBuf() +{ + GLBackend::get()->buf_free(ibo_id_); +} + +void GLIndexBuf::bind(void) +{ + if (is_subrange_) { + static_cast<GLIndexBuf *>(src_)->bind(); + return; + } + + if (ibo_id_ == 0) { + glGenBuffers(1, &ibo_id_); + + if (data_ == nullptr) { + debug::raise_gl_error("Trying to use Index Buffer but the buffer contains no data"); + } + } + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id_); + + if (data_ != nullptr) { + size_t size = this->size_get(); + /* Sends data to GPU. */ + glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data_, GL_STATIC_DRAW); + /* No need to keep copy of data in system memory. */ + MEM_SAFE_FREE(data_); + } +} + +} // namespace blender::gpu
\ No newline at end of file diff --git a/source/blender/gpu/opengl/gl_index_buffer.hh b/source/blender/gpu/opengl/gl_index_buffer.hh new file mode 100644 index 00000000000..b84934bb77f --- /dev/null +++ b/source/blender/gpu/opengl/gl_index_buffer.hh @@ -0,0 +1,68 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#include "MEM_guardedalloc.h" + +#include "gpu_index_buffer_private.hh" + +#include "glew-mx.h" + +namespace blender::gpu { + +class GLIndexBuf : public IndexBuf { + friend class GLBatch; + friend class GLDrawList; + + private: + GLuint ibo_id_ = 0; + + public: + ~GLIndexBuf(); + + void bind(void); + + void *offset_ptr(uint additional_vertex_offset) const + { + additional_vertex_offset += index_start_; + if (index_type_ == GPU_INDEX_U32) { + return (GLuint *)0 + additional_vertex_offset; + } + return (GLushort *)0 + additional_vertex_offset; + } + + GLuint restart_index(void) const + { + return (index_type_ == GPU_INDEX_U16) ? 0xFFFFu : 0xFFFFFFFFu; + } + + MEM_CXX_CLASS_ALLOC_FUNCS("GLIndexBuf") +}; + +static inline GLenum to_gl(GPUIndexBufType type) +{ + return (type == GPU_INDEX_U32) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; +} + +} // namespace blender::gpu diff --git a/source/blender/gpu/opengl/gl_vertex_array.cc b/source/blender/gpu/opengl/gl_vertex_array.cc index 64d44c39587..358b92a9979 100644 --- a/source/blender/gpu/opengl/gl_vertex_array.cc +++ b/source/blender/gpu/opengl/gl_vertex_array.cc @@ -30,6 +30,7 @@ #include "gl_batch.hh" #include "gl_context.hh" +#include "gl_index_buffer.hh" #include "gl_vertex_array.hh" @@ -151,7 +152,7 @@ void GLVertArray::update_bindings(const GLuint vao, if (batch->elem) { /* Binds the index buffer. This state is also saved in the VAO. */ - GPU_indexbuf_use(batch->elem); + static_cast<GLIndexBuf *>(unwrap(batch->elem))->bind(); } } |