[Bf-blender-cvs] [1804eb57fd2] master: GPUImmediate: GL backend isolation

Clément Foucault noreply at git.blender.org
Mon Aug 31 15:17:04 CEST 2020


Commit: 1804eb57fd27fceb0ed113e3ef2f4a55db0d03c8
Author: Clément Foucault
Date:   Mon Aug 31 15:14:47 2020 +0200
Branches: master
https://developer.blender.org/rB1804eb57fd27fceb0ed113e3ef2f4a55db0d03c8

GPUImmediate: GL backend isolation

This is part of the Vulkan backend task T68990.

This is mostly a cleanup, however, there is a small change:
We don't use a special Vertex Array binding function for Immediate
anymore and just reuse the one for batches.
This might create a bit more state changes but this could be fixed
easily if it causes perf regression.

# Conflicts:
#	source/blender/gpu/intern/gpu_context.cc

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

M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/intern/gpu_context.cc
M	source/blender/gpu/intern/gpu_context_private.hh
M	source/blender/gpu/intern/gpu_immediate.cc
A	source/blender/gpu/intern/gpu_immediate_private.hh
M	source/blender/gpu/opengl/gl_context.cc
A	source/blender/gpu/opengl/gl_immediate.cc
A	source/blender/gpu/opengl/gl_immediate.hh
A	source/blender/gpu/opengl/gl_primitive.hh
M	source/blender/gpu/opengl/gl_vertex_array.cc
M	source/blender/gpu/opengl/gl_vertex_array.hh

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

diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 1cb13d815a2..6dadde398b9 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -93,6 +93,7 @@ set(SRC
   opengl/gl_context.cc
   opengl/gl_drawlist.cc
   opengl/gl_framebuffer.cc
+  opengl/gl_immediate.cc
   opengl/gl_shader.cc
   opengl/gl_shader_interface.cc
   opengl/gl_state.cc
@@ -136,6 +137,7 @@ set(SRC
   intern/gpu_context_private.hh
   intern/gpu_drawlist_private.hh
   intern/gpu_framebuffer_private.hh
+  intern/gpu_immediate_private.hh
   intern/gpu_material_library.h
   intern/gpu_matrix_private.h
   intern/gpu_node_graph.h
@@ -153,6 +155,8 @@ set(SRC
   opengl/gl_context.hh
   opengl/gl_drawlist.hh
   opengl/gl_framebuffer.hh
+  opengl/gl_immediate.hh
+  opengl/gl_primitive.hh
   opengl/gl_shader.hh
   opengl/gl_shader_interface.hh
   opengl/gl_state.hh
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc
index f188f5e9fda..229456f9aa5 100644
--- a/source/blender/gpu/intern/gpu_context.cc
+++ b/source/blender/gpu/intern/gpu_context.cc
@@ -75,6 +75,7 @@ GPUContext::~GPUContext()
   delete back_left;
   delete front_right;
   delete back_right;
+  delete imm;
 }
 
 bool GPUContext::is_active_on_thread(void)
diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh
index 04b347d1bff..b32406bfc44 100644
--- a/source/blender/gpu/intern/gpu_context_private.hh
+++ b/source/blender/gpu/intern/gpu_context_private.hh
@@ -30,6 +30,7 @@
 #include "GPU_context.h"
 
 #include "gpu_framebuffer_private.hh"
+#include "gpu_immediate_private.hh"
 #include "gpu_shader_private.hh"
 #include "gpu_state_private.hh"
 
@@ -48,6 +49,7 @@ struct GPUContext {
   blender::gpu::FrameBuffer *active_fb = NULL;
   GPUMatrixState *matrix_state = NULL;
   blender::gpu::GPUStateManager *state_manager = NULL;
+  blender::gpu::Immediate *imm = NULL;
 
   /**
    * All 4 window framebuffers.
diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc
index b0deb1d9551..51843917f58 100644
--- a/source/blender/gpu/intern/gpu_immediate.cc
+++ b/source/blender/gpu/intern/gpu_immediate.cc
@@ -20,7 +20,7 @@
 /** \file
  * \ingroup gpu
  *
- * GPU immediate mode work-alike
+ * Mimics old style opengl immediate mode drawing.
  */
 
 #ifndef GPU_STANDALONE
@@ -34,122 +34,53 @@
 
 #include "gpu_attr_binding_private.h"
 #include "gpu_context_private.hh"
+#include "gpu_immediate_private.hh"
 #include "gpu_primitive_private.h"
 #include "gpu_shader_private.hh"
 #include "gpu_vertex_format_private.h"
 
-#include <stdlib.h>
-#include <string.h>
-
-typedef struct ImmediateDrawBuffer {
-  GLuint vbo_id;
-  GLubyte *buffer_data;
-  uint buffer_offset;
-  uint buffer_size;
-} ImmediateDrawBuffer;
-
-typedef struct {
-  GPUBatch *batch;
-  GPUContext *context;
-
-  /* current draw call */
-  bool strict_vertex_len;
-  uint vertex_len;
-  uint buffer_bytes_mapped;
-  ImmediateDrawBuffer *active_buffer;
-  GPUPrimType prim_type;
-  GPUVertFormat vertex_format;
-  ImmediateDrawBuffer draw_buffer;
-  ImmediateDrawBuffer draw_buffer_strict;
-
-  /* current vertex */
-  uint vertex_idx;
-  GLubyte *vertex_data;
-  /** which attributes of current vertex have not been given values? */
-  uint16_t unassigned_attr_bits;
-
-  GLuint vao_id;
-
-  GPUShader *bound_program;
-  GPUAttrBinding attr_binding;
-  uint16_t prev_enabled_attr_bits; /* <-- only affects this VAO, so we're ok */
-} Immediate;
-
-/* size of internal buffer */
-#define DEFAULT_INTERNAL_BUFFER_SIZE (4 * 1024 * 1024)
-
-static bool initialized = false;
-static Immediate imm;
+using namespace blender::gpu;
+
+static Immediate *imm = NULL;
 
 void immInit(void)
 {
-  BLI_assert(!initialized);
-
-  memset(&imm, 0, sizeof(Immediate));
-
-  imm.draw_buffer.vbo_id = GPU_buf_alloc();
-  imm.draw_buffer.buffer_size = DEFAULT_INTERNAL_BUFFER_SIZE;
-  glBindBuffer(GL_ARRAY_BUFFER, imm.draw_buffer.vbo_id);
-  glBufferData(GL_ARRAY_BUFFER, imm.draw_buffer.buffer_size, NULL, GL_DYNAMIC_DRAW);
-
-  imm.draw_buffer_strict.vbo_id = GPU_buf_alloc();
-  imm.draw_buffer_strict.buffer_size = DEFAULT_INTERNAL_BUFFER_SIZE;
-  glBindBuffer(GL_ARRAY_BUFFER, imm.draw_buffer_strict.vbo_id);
-  glBufferData(GL_ARRAY_BUFFER, imm.draw_buffer_strict.buffer_size, NULL, GL_DYNAMIC_DRAW);
-
-  imm.prim_type = GPU_PRIM_NONE;
-  imm.strict_vertex_len = true;
-
-  glBindBuffer(GL_ARRAY_BUFFER, 0);
-  initialized = true;
+  /* TODO Remove */
 }
 
 void immActivate(void)
 {
-  BLI_assert(initialized);
-  BLI_assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we're not between a Begin/End pair */
-  BLI_assert(imm.vao_id == 0);
-
-  imm.vao_id = GPU_vao_alloc();
-  imm.context = GPU_context_active_get();
+  imm = GPU_context_active_get()->imm;
 }
 
 void immDeactivate(void)
 {
-  BLI_assert(initialized);
-  BLI_assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we're not between a Begin/End pair */
-  BLI_assert(imm.vao_id != 0);
-
-  GPU_vao_free(imm.vao_id, imm.context);
-  imm.vao_id = 0;
-  imm.prev_enabled_attr_bits = 0;
+  imm = NULL;
 }
 
 void immDestroy(void)
 {
-  GPU_buf_free(imm.draw_buffer.vbo_id);
-  GPU_buf_free(imm.draw_buffer_strict.vbo_id);
-  initialized = false;
+  /* TODO Remove */
 }
 
 GPUVertFormat *immVertexFormat(void)
 {
-  GPU_vertformat_clear(&imm.vertex_format);
-  return &imm.vertex_format;
+  GPU_vertformat_clear(&imm->vertex_format);
+  return &imm->vertex_format;
 }
 
 void immBindShader(GPUShader *shader)
 {
-  BLI_assert(imm.bound_program == NULL);
+  BLI_assert(imm->shader == NULL);
 
-  imm.bound_program = shader;
+  imm->shader = shader;
 
-  if (!imm.vertex_format.packed) {
-    VertexFormat_pack(&imm.vertex_format);
+  if (!imm->vertex_format.packed) {
+    VertexFormat_pack(&imm->vertex_format);
+    imm->enabled_attr_bits = 0xFFFFu & ~(0xFFFFu << imm->vertex_format.attr_len);
   }
 
   GPU_shader_bind(shader);
-  get_attr_locations(&imm.vertex_format, &imm.attr_binding, shader);
   GPU_matrix_bind(shader);
   GPU_shader_set_srgb_uniform(shader);
 }
@@ -162,16 +93,16 @@ void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
 
 void immUnbindProgram(void)
 {
-  BLI_assert(imm.bound_program != NULL);
+  BLI_assert(imm->shader != NULL);
 
   GPU_shader_unbind();
-  imm.bound_program = NULL;
+  imm->shader = NULL;
 }
 
 /* XXX do not use it. Special hack to use OCIO with batch API. */
 GPUShader *immGetShader(void)
 {
-  return imm.bound_program;
+  return imm->shader;
 }
 
 #ifndef NDEBUG
@@ -205,267 +136,122 @@ static bool vertex_count_makes_sense_for_primitive(uint vertex_len, GPUPrimType
 
 void immBegin(GPUPrimType prim_type, uint vertex_len)
 {
-  BLI_assert(initialized);
-  BLI_assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we haven't already begun */
+  BLI_assert(imm->prim_type == GPU_PRIM_NONE); /* Make sure we haven't already begun. */
   BLI_assert(vertex_count_makes_sense_for_primitive(vertex_len, prim_type));
-  BLI_assert(imm.active_buffer == NULL);
-
-  GPU_context_active_get()->state_manager->apply_state();
-
-  imm.prim_type = prim_type;
-  imm.vertex_len = vertex_len;
-  imm.vertex_idx = 0;
-  imm.unassigned_attr_bits = imm.attr_binding.enabled_bits;
-
-  /* how many bytes do we need for this draw call? */
-  const uint bytes_needed = vertex_buffer_size(&imm.vertex_format, vertex_len);
-  ImmediateDrawBuffer *active_buffer = imm.strict_vertex_len ? &imm.draw_buffer_strict :
-                                                               &imm.draw_buffer;
-  imm.active_buffer = active_buffer;
-
-  glBindBuffer(GL_ARRAY_BUFFER, active_buffer->vbo_id);
-
-  /* does the current buffer have enough room? */
-  const uint available_bytes = active_buffer->buffer_size - active_buffer->buffer_offset;
-
-  bool recreate_buffer = false;
-  if (bytes_needed > active_buffer->buffer_size) {
-    /* expand the internal buffer */
-    active_buffer->buffer_size = bytes_needed;
-    recreate_buffer = true;
-  }
-  else if (bytes_needed < DEFAULT_INTERNAL_BUFFER_SIZE &&
-           active_buffer->buffer_size > DEFAULT_INTERNAL_BUFFER_SIZE) {
-    /* shrink the internal buffer */
-    active_buffer->buffer_size = DEFAULT_INTERNAL_BUFFER_SIZE;
-    recreate_buffer = true;
-  }
-
-  /* ensure vertex data is aligned */
-  /* Might waste a little space, but it's safe. */
-  const uint pre_padding = padding(active_buffer->buffer_offset, imm.vertex_format.stride);
-
-  if (!recreate_buffer && ((bytes_needed + pre_padding) <= available_bytes)) {
-    active_buffer->buffer_offset += pre_padding;
-  }
-  else {
-    /* orphan this buffer & start with a fresh one */
-    /* this method works on all platforms, old & new */
-    glBufferData(GL_ARRAY_BUFFER, active_buffer->buffer_size, NULL, GL_DYNAMIC_DRAW);
-
-    active_buffer->buffer_offset = 0;
-  }
-
-  /*  printf("mapping %u to %u\n", imm.buffer_offset, imm.buffer_offset + bytes_needed - 1); */
-
-#ifndef NDEBUG
-  {
-    GLint bufsize;
-    glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &bufsize);
-    BLI_assert(active_buffer->buffer_offset + bytes_needed <= bufsize);
-  }
-#endif
-
-  active_buffer->buffer_data = (GLubyte *)glMapBufferRange(
-      GL_ARRAY_BUFFER,
-      active_buffer->buffer_offset,
-      bytes_needed,
-      GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT |
-          (imm.strict_vertex_len ? 0 : GL_MAP_FLUSH_EXPLICIT_BIT));
 
-  BLI_assert(active_buffer->buffer_data != NULL);
+  imm->prim_type = prim_type;
+  imm->vertex_len = vertex_len;
+  imm->vertex_idx = 0;
+  imm->unassigned_attr_bits = imm->enabled_attr_bits;
 
-  imm.buffer_bytes_mapped = bytes_needed;
-  imm.vertex_data = active_buffer->buffer_data;
+  imm->vertex_data = imm->begin();
 }
 
 void immBeginAtMost(GPUPrimType prim_type, uint vertex_len)
 {
   BLI_assert(vertex_len > 0);
-
-  imm.strict_vertex_len = false;
+  imm->strict_vertex_len = false;
   immBegin(prim_type, vertex_len);
 }
 
 GPUBatch *immBeginBatch(GPUPrimType prim_type, uint vertex_len)
 {
-  BLI_assert(initialized);
-  BLI_assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we haven't already begun */
+  BLI_assert(imm->prim_type == GPU_PRIM_NONE); /* Make sure

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list