[Bf-blender-cvs] [41406fcacf7] tmp-gpu-context-isolation: GPU: Hide GL context specificitied behind class methods

Clément Foucault noreply at git.blender.org
Fri Jul 31 18:58:25 CEST 2020


Commit: 41406fcacf74b7aad7f1c842cb9fa19eb886caac
Author: Clément Foucault
Date:   Fri Jul 31 11:56:29 2020 +0200
Branches: tmp-gpu-context-isolation
https://developer.blender.org/rB41406fcacf74b7aad7f1c842cb9fa19eb886caac

GPU: Hide GL context specificitied behind class methods

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

M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/intern/gpu_batch.cc
M	source/blender/gpu/intern/gpu_context.cc
D	source/blender/gpu/intern/gpu_context_private.h
A	source/blender/gpu/intern/gpu_context_private.hh
M	source/blender/gpu/intern/gpu_element.cc
M	source/blender/gpu/intern/gpu_framebuffer.cc
M	source/blender/gpu/intern/gpu_immediate.cc
M	source/blender/gpu/intern/gpu_matrix.cc
M	source/blender/gpu/intern/gpu_shader_interface.cc
M	source/blender/gpu/intern/gpu_texture.cc
M	source/blender/gpu/intern/gpu_uniformbuffer.cc
M	source/blender/gpu/intern/gpu_vertex_buffer.cc
A	source/blender/gpu/opengl/gl_batch.cc
A	source/blender/gpu/opengl/gl_context.cc
A	source/blender/gpu/opengl/gl_context.hh

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

diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 3ea18f72166..c18fa5f508c 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -28,6 +28,7 @@ endif()
 
 set(INC
   .
+  ./opengl
   ../blenkernel
   ../blenlib
   ../bmesh
@@ -85,6 +86,12 @@ set(SRC
   intern/gpu_vertex_format.cc
   intern/gpu_viewport.c
 
+  # opengl/ogl_context.cc
+  opengl/gl_context.hh
+
+  # vulkan/vk_context.cc
+  # vulkan/vk_context.hh
+
   GPU_attr_binding.h
   GPU_batch.h
   GPU_batch_presets.h
@@ -118,7 +125,7 @@ set(SRC
   intern/gpu_attr_binding_private.h
   intern/gpu_batch_private.h
   intern/gpu_codegen.h
-  intern/gpu_context_private.h
+  intern/gpu_context_private.hh
   intern/gpu_material_library.h
   intern/gpu_matrix_private.h
   intern/gpu_node_graph.h
diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc
index 9f9adcacfa6..d354d828044 100644
--- a/source/blender/gpu/intern/gpu_batch.cc
+++ b/source/blender/gpu/intern/gpu_batch.cc
@@ -34,7 +34,7 @@
 #include "GPU_shader.h"
 
 #include "gpu_batch_private.h"
-#include "gpu_context_private.h"
+#include "gpu_context_private.hh"
 #include "gpu_primitive_private.h"
 #include "gpu_shader_private.h"
 #include "gpu_vertex_format_private.h"
@@ -81,7 +81,7 @@ void GPU_batch_vao_cache_clear(GPUBatch *batch)
     batch->static_vaos.vao_ids[i] = 0;
     batch->static_vaos.interfaces[i] = NULL;
   }
-  gpu_context_remove_batch(batch->context, batch);
+  batch->context->batch_remove(batch);
   batch->context = NULL;
 }
 
@@ -294,7 +294,7 @@ static GLuint batch_vao_get(GPUBatch *batch)
    * Until then it can only be drawn with this context. */
   if (batch->context == NULL) {
     batch->context = GPU_context_active_get();
-    gpu_context_add_batch(batch->context, batch);
+    batch->context->batch_add(batch);
   }
 #if TRUST_NO_ONE
   else {
@@ -634,16 +634,6 @@ void GPU_batch_uniform_mat4(GPUBatch *batch, const char *name, const float data[
   glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (const float *)data);
 }
 
-static void *elem_offset(const GPUIndexBuf *el, int v_first)
-{
-#if GPU_TRACK_INDEX_RANGE
-  if (el->index_type == GPU_INDEX_U16) {
-    return (GLushort *)0 + v_first + el->index_start;
-  }
-#endif
-  return (GLuint *)0 + v_first + el->index_start;
-}
-
 /* Use when drawing with GPU_batch_draw_advanced */
 void GPU_batch_bind(GPUBatch *batch)
 {
@@ -704,90 +694,13 @@ void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_fi
     return;
   }
 
-  /* Verify there is enough data do draw. */
-  /* TODO(fclem) Nice to have but this is invalid when using procedural draw-calls.
-   * The right assert would be to check if there is an enabled attribute from each VBO
-   * and check their length. */
-  // BLI_assert(i_first + i_count <= (batch->inst ? batch->inst->vertex_len : INT_MAX));
-  // BLI_assert(v_first + v_count <=
-  //            (batch->elem ? batch->elem->index_len : batch->verts[0]->vertex_len));
-
-#ifdef __APPLE__
-  GLuint vao = 0;
-#endif
-
-  if (!GPU_arb_base_instance_is_supported()) {
-    if (i_first > 0) {
-#ifdef __APPLE__
-      /**
-       * There seems to be a nasty bug when drawing using the same VAO reconfiguring. (see T71147)
-       * We just use a throwaway VAO for that. Note that this is likely to degrade performance.
-       **/
-      glGenVertexArrays(1, &vao);
-      glBindVertexArray(vao);
-#else
-      /* If using offset drawing with instancing, we must
-       * use the default VAO and redo bindings. */
-      glBindVertexArray(GPU_vao_default());
-#endif
-      batch_update_program_bindings(batch, i_first);
-    }
-    else {
-      /* Previous call could have bind the default vao
-       * see above. */
-      glBindVertexArray(batch->vao_id);
-    }
-  }
-
-  if (batch->elem) {
-    const GPUIndexBuf *el = batch->elem;
-    GLenum index_type = INDEX_TYPE(el);
-    GLint base_index = BASE_INDEX(el);
-    void *v_first_ofs = elem_offset(el, v_first);
-
-    if (GPU_arb_base_instance_is_supported()) {
-      glDrawElementsInstancedBaseVertexBaseInstance(
-          batch->gl_prim_type, v_count, index_type, v_first_ofs, i_count, base_index, i_first);
-    }
-    else {
-      glDrawElementsInstancedBaseVertex(
-          batch->gl_prim_type, v_count, index_type, v_first_ofs, i_count, base_index);
-    }
-  }
-  else {
-#ifdef __APPLE__
-    glDisable(GL_PRIMITIVE_RESTART);
-#endif
-    if (GPU_arb_base_instance_is_supported()) {
-      glDrawArraysInstancedBaseInstance(batch->gl_prim_type, v_first, v_count, i_count, i_first);
-    }
-    else {
-      glDrawArraysInstanced(batch->gl_prim_type, v_first, v_count, i_count);
-    }
-#ifdef __APPLE__
-    glEnable(GL_PRIMITIVE_RESTART);
-#endif
-  }
-
-#ifdef __APPLE__
-  if (vao != 0) {
-    glDeleteVertexArrays(1, &vao);
-  }
-#endif
+  GPU_ctx()->draw_batch(batch, v_first, v_count, i_first, i_count);
 }
 
 /* just draw some vertices and let shader place them where we want. */
 void GPU_draw_primitive(GPUPrimType prim_type, int v_count)
 {
-  /* we cannot draw without vao ... annoying ... */
-  glBindVertexArray(GPU_vao_default());
-
-  GLenum type = convert_prim_type_to_gl(prim_type);
-  glDrawArrays(type, 0, v_count);
-
-  /* Performance hog if you are drawing with the same vao multiple time.
-   * Only activate for debugging.*/
-  // glBindVertexArray(0);
+  GPU_ctx()->draw_primitive(prim_type, v_count);
 }
 
 /* -------------------------------------------------------------------- */
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc
index 0b9104e5349..16e52cab0bd 100644
--- a/source/blender/gpu/intern/gpu_context.cc
+++ b/source/blender/gpu/intern/gpu_context.cc
@@ -35,137 +35,46 @@
 #include "GPU_framebuffer.h"
 
 #include "gpu_batch_private.h"
-#include "gpu_context_private.h"
+#include "gpu_context_private.hh"
 #include "gpu_matrix_private.h"
 
+#include "gl_context.hh"
+
 #include <mutex>
 #include <pthread.h>
 #include <string.h>
 #include <unordered_set>
 #include <vector>
 
-#if TRUST_NO_ONE
-#  if 0
-extern "C" {
-extern int BLI_thread_is_main(void); /* Blender-specific function */
-}
-
-static bool thread_is_main()
-{
-  /* "main" here means the GL context's thread */
-  return BLI_thread_is_main();
-}
-#  endif
-#endif
-
-static std::vector<GLuint> orphaned_buffer_ids;
-static std::vector<GLuint> orphaned_texture_ids;
-
-static std::mutex orphans_mutex;
-
-struct GPUContext {
-  GLuint default_vao;
-  GLuint default_framebuffer;
-  GPUFrameBuffer *current_fbo;
-  std::unordered_set<GPUBatch *> batches; /* Batches that have VAOs from this context */
-#ifdef DEBUG
-  std::unordered_set<GPUFrameBuffer *>
-      framebuffers; /* Framebuffers that have FBO from this context */
-#endif
-  struct GPUMatrixState *matrix_state;
-  std::vector<GLuint> orphaned_vertarray_ids;
-  std::vector<GLuint> orphaned_framebuffer_ids;
-  std::mutex orphans_mutex; /* todo: try spinlock instead */
-#if TRUST_NO_ONE
-  pthread_t thread; /* Thread on which this context is active. */
-  bool thread_is_used;
-#endif
-
-  GPUContext()
-  {
-#if TRUST_NO_ONE
-    thread_is_used = false;
-#endif
-    current_fbo = 0;
-  }
-};
+// TODO
+// using namespace blender::gpu;
 
 static thread_local GPUContext *active_ctx = NULL;
 
-static void orphans_add(GPUContext *ctx, std::vector<GLuint> *orphan_list, GLuint id)
+GPUContext::GPUContext()
 {
-  std::mutex *mutex = (ctx) ? &ctx->orphans_mutex : &orphans_mutex;
-
-  mutex->lock();
-  orphan_list->emplace_back(id);
-  mutex->unlock();
+  thread_ = pthread_self();
+  matrix_state = GPU_matrix_state_create();
 }
 
-static void orphans_clear(GPUContext *ctx)
+GPUContext *GPU_context_create(GLuint)
 {
-  /* need at least an active context */
-  BLI_assert(ctx);
-
-  /* context has been activated by another thread! */
-  BLI_assert(pthread_equal(pthread_self(), ctx->thread));
-
-  ctx->orphans_mutex.lock();
-  if (!ctx->orphaned_vertarray_ids.empty()) {
-    uint orphan_len = (uint)ctx->orphaned_vertarray_ids.size();
-    glDeleteVertexArrays(orphan_len, ctx->orphaned_vertarray_ids.data());
-    ctx->orphaned_vertarray_ids.clear();
-  }
-  if (!ctx->orphaned_framebuffer_ids.empty()) {
-    uint orphan_len = (uint)ctx->orphaned_framebuffer_ids.size();
-    glDeleteFramebuffers(orphan_len, ctx->orphaned_framebuffer_ids.data());
-    ctx->orphaned_framebuffer_ids.clear();
-  }
-
-  ctx->orphans_mutex.unlock();
-
-  orphans_mutex.lock();
-  if (!orphaned_buffer_ids.empty()) {
-    uint orphan_len = (uint)orphaned_buffer_ids.size();
-    glDeleteBuffers(orphan_len, orphaned_buffer_ids.data());
-    orphaned_buffer_ids.clear();
-  }
-  if (!orphaned_texture_ids.empty()) {
-    uint orphan_len = (uint)orphaned_texture_ids.size();
-    glDeleteTextures(orphan_len, orphaned_texture_ids.data());
-    orphaned_texture_ids.clear();
-  }
-  orphans_mutex.unlock();
+  GPUContext *ctx = new GLContext();
+  GPU_context_active_set(ctx);
+  return ctx;
 }
 
-GPUContext *GPU_context_create(GLuint default_framebuffer)
+bool GPUContext::is_active_on_thread(void)
 {
-  /* BLI_assert(thread_is_main()); */
-  GPUContext *ctx = new GPUContext;
-  glGenVertexArrays(1, &ctx->default_vao);
-  ctx->default_framebuffer = default_framebuffer;
-  ctx->matrix_state = GPU_matrix_state_create();
-  GPU_context_active_set(ctx);
-  return ctx;
+  return (this == active_ctx) && pthread_equal(pthread_self(), thread_);
 }
 
 /* to be called after GPU_context_active_set(ctx_to_destroy) */
 void GPU_context_discard(GPUContext *ctx)
 {
   /* Make sure no other thread has locked it. */
-  BLI_assert(ctx == active_ctx);
-  BLI_assert(pthread_equal(pthread_self(), ctx->thread));
-  BLI_assert(ctx->orphaned_vertarray_ids.empty());
-#ifdef DEBUG
-  /* For now don't allow GPUFrameBuffers to be reuse in another ctx. */
-  BLI_assert(ctx->framebuffers.empty());
-#endif
-  /* delete remaining vaos */
-  while (!ctx->batches.empty()) {
-    /* this removes the array entry */
-    GPU_batch_vao_cache_clear(*ctx->batches.begin());
-  }
-  GPU_matrix_state_discard(ctx->matrix_state);
-  glDeleteVertexArrays(1, &ctx->default_vao);
+  BLI_assert(ctx->is_active_on_thread());
+
   

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list