[Bf-blender-cvs] [47bfb0f7ad2] master: GPUBatch: Move allocator to backend

Clément Foucault noreply at git.blender.org
Thu Aug 13 14:47:19 CEST 2020


Commit: 47bfb0f7ad2f70017585fe55a68e49ae09f1150c
Author: Clément Foucault
Date:   Mon Aug 10 11:41:22 2020 +0200
Branches: master
https://developer.blender.org/rB47bfb0f7ad2f70017585fe55a68e49ae09f1150c

GPUBatch: Move allocator to backend

===================================================================

M	source/blender/draw/intern/draw_cache_inline.h
M	source/blender/draw/intern/draw_instance_data.c
M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/GPU_batch.h
M	source/blender/gpu/intern/gpu_backend.hh
M	source/blender/gpu/intern/gpu_batch.cc
M	source/blender/gpu/intern/gpu_batch_private.hh
M	source/blender/gpu/opengl/gl_backend.hh
A	source/blender/gpu/opengl/gl_batch.cc
A	source/blender/gpu/opengl/gl_batch.hh

===================================================================

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/intern/gpu_batch_private.hh b/source/blender/gpu/opengl/gl_batch.cc
similarity index 62%
copy from source/blender/gpu/intern/gpu_batch_private.hh
copy to source/blender/gpu/opengl/gl_batch.cc
index a5a863310a1..62d81ad9f5a 100644
--- a/source/blender/gpu/intern/gpu_batch_private.hh
+++ b/source/blender/gpu/opengl/gl_batch.cc
@@ -20,14 +20,31 @@
 /** \file
  * \ingroup gpu
  *
- * GPU geometry batch
- * Contains VAOs + VBOs + Shader representing a drawable entity.
+ * 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.
  */
 
-#pragma once
+#include "BLI_assert.h"
 
-#include "GPU_batch.h"
-#include "GPU_context.h"
-#include "GPU_shader_interface.h"
+#include "glew-mx.h"
 
-void gpu_batch_remove_interface_ref(GPUBatch *batch, const GPUShaderInterface *interface);
+#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



More information about the Bf-blender-cvs mailing list