diff options
-rw-r--r-- | source/blender/draw/intern/draw_cache_inline.h | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_instance_data.c | 4 | ||||
-rw-r--r-- | source/blender/gpu/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/gpu/GPU_batch.h | 2 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_backend.hh | 6 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_batch.cc | 14 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_batch_private.hh | 14 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_backend.hh | 6 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_batch.cc | 50 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_batch.hh | 84 |
10 files changed, 176 insertions, 8 deletions
diff --git a/source/blender/draw/intern/draw_cache_inline.h b/source/blender/draw/intern/draw_cache_inline.h index 415fe2479ab..0d24f2e450b 100644 --- a/source/blender/draw/intern/draw_cache_inline.h +++ b/source/blender/draw/intern/draw_cache_inline.h @@ -48,7 +48,7 @@ BLI_INLINE GPUBatch *DRW_batch_request(GPUBatch **batch) { /* XXX TODO(fclem): We are writing to batch cache here. Need to make this thread safe. */ if (*batch == NULL) { - *batch = GPU_batch_calloc(1); + *batch = GPU_batch_calloc(); } return *batch; } diff --git a/source/blender/draw/intern/draw_instance_data.c b/source/blender/draw/intern/draw_instance_data.c index 70836b9ba2c..4e08e6e5129 100644 --- a/source/blender/draw/intern/draw_instance_data.c +++ b/source/blender/draw/intern/draw_instance_data.c @@ -148,7 +148,7 @@ GPUBatch *DRW_temp_batch_instance_request(DRWInstanceDataList *idatalist, DRWTempInstancingHandle *handle = BLI_memblock_alloc(idatalist->pool_instancing); if (handle->batch == NULL) { - handle->batch = GPU_batch_calloc(1); + handle->batch = GPU_batch_calloc(); } GPUBatch *batch = handle->batch; @@ -182,7 +182,7 @@ GPUBatch *DRW_temp_batch_request(DRWInstanceDataList *idatalist, { GPUBatch **batch_ptr = BLI_memblock_alloc(idatalist->pool_batching); if (*batch_ptr == NULL) { - *batch_ptr = GPU_batch_calloc(1); + *batch_ptr = GPU_batch_calloc(); } GPUBatch *batch = *batch_ptr; diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 0d92d125402..fcbe53e599a 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -89,6 +89,7 @@ set(SRC intern/gpu_vertex_format.cc intern/gpu_viewport.c + opengl/gl_batch.cc opengl/gl_context.cc opengl/gl_drawlist.cc @@ -139,6 +140,7 @@ set(SRC intern/gpu_vertex_format_private.h opengl/gl_backend.hh + opengl/gl_batch.hh opengl/gl_context.hh opengl/gl_drawlist.hh ) diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h index b8af07cb78d..d71d4d5435f 100644 --- a/source/blender/gpu/GPU_batch.h +++ b/source/blender/gpu/GPU_batch.h @@ -118,7 +118,7 @@ typedef struct GPUBatch { }; } GPUBatch; -GPUBatch *GPU_batch_calloc(uint count); +GPUBatch *GPU_batch_calloc(void); GPUBatch *GPU_batch_create_ex(GPUPrimType prim, GPUVertBuf *vert, GPUIndexBuf *elem, diff --git a/source/blender/gpu/intern/gpu_backend.hh b/source/blender/gpu/intern/gpu_backend.hh index 4dd6036e672..ba382e3c3fc 100644 --- a/source/blender/gpu/intern/gpu_backend.hh +++ b/source/blender/gpu/intern/gpu_backend.hh @@ -27,6 +27,7 @@ #include "gpu_context_private.hh" #include "gpu_drawlist_private.hh" +#include "gpu_batch_private.hh" namespace blender { namespace gpu { @@ -38,7 +39,12 @@ class GPUBackend { static GPUBackend *get(void); virtual GPUContext *context_alloc(void *ghost_window) = 0; + + virtual Batch *batch_alloc(void) = 0; virtual DrawList *drawlist_alloc(int list_length) = 0; + // virtual FrameBuffer *framebuffer_alloc(void) = 0; + // virtual Shader *shader_alloc(void) = 0; + // virtual Texture *texture_alloc(void) = 0; }; } // namespace gpu diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc index 0a802946913..27196413b20 100644 --- a/source/blender/gpu/intern/gpu_batch.cc +++ b/source/blender/gpu/intern/gpu_batch.cc @@ -33,6 +33,7 @@ #include "GPU_platform.h" #include "GPU_shader.h" +#include "gpu_backend.hh" #include "gpu_batch_private.hh" #include "gpu_context_private.hh" #include "gpu_primitive_private.h" @@ -43,6 +44,8 @@ #include <stdlib.h> #include <string.h> +using namespace blender::gpu; + static GLuint g_default_attr_vbo = 0; static void gpu_batch_bind(GPUBatch *batch); @@ -86,9 +89,11 @@ void GPU_batch_vao_cache_clear(GPUBatch *batch) batch->context = NULL; } -GPUBatch *GPU_batch_calloc(uint count) +GPUBatch *GPU_batch_calloc(void) { - return (GPUBatch *)MEM_callocN(sizeof(GPUBatch) * count, "GPUBatch"); + GPUBatch *batch = GPUBackend::get()->batch_alloc(); + memset(batch, 0, sizeof(*batch)); + return batch; } GPUBatch *GPU_batch_create_ex(GPUPrimType prim_type, @@ -96,7 +101,7 @@ GPUBatch *GPU_batch_create_ex(GPUPrimType prim_type, GPUIndexBuf *elem, eGPUBatchFlag owns_flag) { - GPUBatch *batch = GPU_batch_calloc(1); + GPUBatch *batch = GPU_batch_calloc(); GPU_batch_init_ex(batch, prim_type, verts, elem, owns_flag); return batch; } @@ -163,7 +168,8 @@ void GPU_batch_clear(GPUBatch *batch) void GPU_batch_discard(GPUBatch *batch) { GPU_batch_clear(batch); - MEM_freeN(batch); + + delete static_cast<Batch *>(batch); } /* NOTE: Override ONLY the first instance vbo (and free them if owned). */ diff --git a/source/blender/gpu/intern/gpu_batch_private.hh b/source/blender/gpu/intern/gpu_batch_private.hh index a5a863310a1..a9293a5b206 100644 --- a/source/blender/gpu/intern/gpu_batch_private.hh +++ b/source/blender/gpu/intern/gpu_batch_private.hh @@ -30,4 +30,18 @@ #include "GPU_context.h" #include "GPU_shader_interface.h" +namespace blender { +namespace gpu { + +class Batch : public GPUBatch { + public: + Batch(){}; + virtual ~Batch(){}; + + virtual void draw(int v_first, int v_count, int i_first, int i_count) = 0; +}; + +} // namespace gpu +} // namespace blender + void gpu_batch_remove_interface_ref(GPUBatch *batch, const GPUShaderInterface *interface); diff --git a/source/blender/gpu/opengl/gl_backend.hh b/source/blender/gpu/opengl/gl_backend.hh index a1e0e53f329..eba275f0245 100644 --- a/source/blender/gpu/opengl/gl_backend.hh +++ b/source/blender/gpu/opengl/gl_backend.hh @@ -27,6 +27,7 @@ #include "BLI_vector.hh" +#include "gl_batch.hh" #include "gl_context.hh" #include "gl_drawlist.hh" @@ -43,6 +44,11 @@ class GLBackend : public GPUBackend { return new GLContext(ghost_window, shared_orphan_list_); }; + Batch *batch_alloc(void) + { + return new GLBatch(); + }; + DrawList *drawlist_alloc(int list_length) { return new GLDrawList(list_length); diff --git a/source/blender/gpu/opengl/gl_batch.cc b/source/blender/gpu/opengl/gl_batch.cc new file mode 100644 index 00000000000..62d81ad9f5a --- /dev/null +++ b/source/blender/gpu/opengl/gl_batch.cc @@ -0,0 +1,50 @@ +/* + * 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) 2016 by Mike Erwin. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + * + * GL implementation of GPUBatch. + * The only specificity of GL here is that it caches a list of + * Vertex Array Objects based on the bound shader interface. + */ + +#include "BLI_assert.h" + +#include "glew-mx.h" + +#include "gpu_batch_private.hh" +#include "gpu_primitive_private.h" + +#include "gl_batch.hh" + +using namespace blender::gpu; + +GLBatch::GLBatch(void) +{ +} + +GLBatch::~GLBatch() +{ +} + +void GLBatch::draw(int v_first, int v_count, int i_first, int i_count) +{ + UNUSED_VARS(v_first, v_count, i_first, i_count); +}
\ No newline at end of file diff --git a/source/blender/gpu/opengl/gl_batch.hh b/source/blender/gpu/opengl/gl_batch.hh new file mode 100644 index 00000000000..290c113205a --- /dev/null +++ b/source/blender/gpu/opengl/gl_batch.hh @@ -0,0 +1,84 @@ +/* + * 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. + * + * Copyright 2020, Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + * + * GPU geometry batch + * Contains VAOs + VBOs + Shader representing a drawable entity. + */ + +#pragma once + +#include "MEM_guardedalloc.h" + +#include "gpu_batch_private.hh" + +#include "glew-mx.h" + +#include "GPU_shader_interface.h" + +namespace blender { +namespace gpu { + +#define GPU_BATCH_VAO_STATIC_LEN 3 + +class GLVaoCache { + /* Vao management: remembers all geometry state (vertex attribute bindings & element buffer) + * for each shader interface. Start with a static number of vaos and fallback to dynamic count + * if necessary. Once a batch goes dynamic it does not go back. */ + bool is_dynamic_vao_count = false; + union { + /** Static handle count */ + struct { + const GPUShaderInterface *interfaces[GPU_BATCH_VAO_STATIC_LEN]; + GLuint vao_ids[GPU_BATCH_VAO_STATIC_LEN]; + } static_vaos; + /** Dynamic handle count */ + struct { + uint count; + const GPUShaderInterface **interfaces; + GLuint *vao_ids; + } dynamic_vaos; + }; + + GLuint search(const GPUShaderInterface *interface); + void insert(GLuint vao_id, const GPUShaderInterface *interface); + void clear(void); + void interface_remove(const GPUShaderInterface *interface); +}; + +class GLBatch : public Batch { + private: + /** Cached values (avoid dereferencing later). */ + GLuint vao_id; + /** All vaos corresponding to all the GPUShaderInterface this batch was drawn with. */ + GLVaoCache vaos; + + public: + GLBatch(); + ~GLBatch(); + + void draw(int v_first, int v_count, int i_first, int i_count) override; + + MEM_CXX_CLASS_ALLOC_FUNCS("GLBatch"); +}; + +} // namespace gpu +} // namespace blender |