[Bf-blender-cvs] [9d5977f5e1f] master: GL: Add fallback debug layer

Clément Foucault noreply at git.blender.org
Thu Sep 10 14:19:12 CEST 2020


Commit: 9d5977f5e1fa2eac782278c61c3cc86685cc1b5a
Author: Clément Foucault
Date:   Wed Sep 9 00:47:59 2020 +0200
Branches: master
https://developer.blender.org/rB9d5977f5e1fa2eac782278c61c3cc86685cc1b5a

GL: Add fallback debug layer

This is to improve debugging on older hardware that may not support
4.3 debug capabilities (like Macs).

This avoids sprinkling glGetErrors manually. This might still be needed
to find the root cause since not all functions are covered.

This overrides the functions pointers that GLEW have already init.

This is only enabled if using --debug-gpu option and the debug extension
are not available.

This also cleanup the usage of GLContext::debug_layer_support and use
wrapper to set object labels.

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

M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/opengl/gl_backend.cc
M	source/blender/gpu/opengl/gl_batch.cc
M	source/blender/gpu/opengl/gl_context.cc
M	source/blender/gpu/opengl/gl_context.hh
M	source/blender/gpu/opengl/gl_debug.cc
M	source/blender/gpu/opengl/gl_debug.hh
A	source/blender/gpu/opengl/gl_debug_layer.cc
M	source/blender/gpu/opengl/gl_framebuffer.cc
M	source/blender/gpu/opengl/gl_immediate.cc
M	source/blender/gpu/opengl/gl_shader.cc
M	source/blender/gpu/opengl/gl_state.cc
M	source/blender/gpu/opengl/gl_state.hh
M	source/blender/gpu/opengl/gl_texture.cc
M	source/blender/gpu/opengl/gl_uniform_buffer.cc

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

diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index bb50cd3744f..72dc610f3c8 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_debug.cc
+  opengl/gl_debug_layer.cc
   opengl/gl_framebuffer.cc
   opengl/gl_immediate.cc
   opengl/gl_index_buffer.cc
diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc
index c8d57a20a38..7285b9ad35c 100644
--- a/source/blender/gpu/opengl/gl_backend.cc
+++ b/source/blender/gpu/opengl/gl_backend.cc
@@ -178,7 +178,7 @@ static bool detect_mip_render_workaround(void)
   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
   glClear(GL_COLOR_BUFFER_BIT);
   glBindFramebuffer(GL_FRAMEBUFFER, 0);
-  glDrawBuffer(GL_BACK);
+
   /* Read mip 1. If color is not the same as the clear_color, the rendering failed. */
   glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1, GL_RGBA, GL_FLOAT, source_pix);
   bool enable_workaround = !equals_v4v4(clear_color, source_pix);
@@ -207,10 +207,12 @@ static void detect_workarounds(void)
     printf("    version: %s\n\n", version);
     GCaps.depth_blitting_workaround = true;
     GCaps.mip_render_workaround = true;
+    GLContext::debug_layer_workaround = true;
     GLContext::unused_fb_slot_workaround = true;
     GLContext::texture_copy_workaround = true;
     /* Turn off extensions. */
     GLContext::base_instance_support = false;
+    GLContext::debug_layer_support = false;
     GLContext::texture_cube_map_array_support = false;
     return;
   }
@@ -321,6 +323,10 @@ static void detect_workarounds(void)
       GLContext::derivative_signs[1] = 1.0;
     }
   }
+  /* Enable our own incomplete debug layer if no other is available. */
+  if (GLContext::debug_layer_support == false) {
+    GLContext::debug_layer_workaround = true;
+  }
 }
 
 /** Internal capabilities. */
@@ -333,6 +339,7 @@ bool GLContext::base_instance_support = false;
 bool GLContext::debug_layer_support = false;
 bool GLContext::texture_cube_map_array_support = false;
 /** Workarounds. */
+bool GLContext::debug_layer_workaround = false;
 bool GLContext::texture_copy_workaround = false;
 bool GLContext::unused_fb_slot_workaround = false;
 float GLContext::derivative_signs[2] = {1.0f, 1.0f};
@@ -355,14 +362,15 @@ void GLBackend::capabilities_init(void)
   glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &GLContext::max_ubo_size);
   GLContext::base_instance_support = GLEW_ARB_base_instance;
   GLContext::texture_cube_map_array_support = GLEW_ARB_texture_cube_map_array;
-  GLContext::debug_layer_support = (GLEW_VERSION_4_3 || GLEW_KHR_debug);
+  GLContext::debug_layer_support = GLEW_VERSION_4_3 || GLEW_KHR_debug || GLEW_ARB_debug_output;
 
+  detect_workarounds();
+
+  /* Disable this feature entirely when not debugging. */
   if ((G.debug & G_DEBUG_GPU) == 0) {
-    /* Disable this feature entierly when not debugging. */
     GLContext::debug_layer_support = false;
+    GLContext::debug_layer_workaround = false;
   }
-
-  detect_workarounds();
 }
 
 /** \} */
diff --git a/source/blender/gpu/opengl/gl_batch.cc b/source/blender/gpu/opengl/gl_batch.cc
index b25bafad6a3..17bc1013a78 100644
--- a/source/blender/gpu/opengl/gl_batch.cc
+++ b/source/blender/gpu/opengl/gl_batch.cc
@@ -324,7 +324,6 @@ void GLBatch::bind(int i_first)
 void GLBatch::draw(int v_first, int v_count, int i_first, int i_count)
 {
   GL_CHECK_RESOURCES("Batch");
-  GL_CHECK_ERROR("Batch Pre drawing");
 
   this->bind(i_first);
 
@@ -346,7 +345,6 @@ void GLBatch::draw(int v_first, int v_count, int i_first, int i_count)
       glDrawElementsInstancedBaseVertex(
           gl_type, v_count, index_type, v_first_ofs, i_count, base_index);
     }
-    GL_CHECK_ERROR("Batch Post-drawing Indexed");
   }
   else {
 #ifdef __APPLE__
@@ -361,7 +359,6 @@ void GLBatch::draw(int v_first, int v_count, int i_first, int i_count)
 #ifdef __APPLE__
     glEnable(GL_PRIMITIVE_RESTART);
 #endif
-    GL_CHECK_ERROR("Batch Post-drawing Non-indexed");
   }
 }
 
diff --git a/source/blender/gpu/opengl/gl_context.cc b/source/blender/gpu/opengl/gl_context.cc
index 6b3b06ef12b..9c98953f469 100644
--- a/source/blender/gpu/opengl/gl_context.cc
+++ b/source/blender/gpu/opengl/gl_context.cc
@@ -74,6 +74,9 @@ GLContext::GLContext(void *ghost_window, GLSharedOrphanLists &shared_orphan_list
     GHOST_DisposeRectangle(bounds);
 
     if (default_fbo != 0) {
+      /* Bind default framebuffer, otherwise state might be undefined because of
+       * detect_mip_render_workaround(). */
+      glBindFramebuffer(GL_FRAMEBUFFER, default_fbo);
       front_left = new GLFrameBuffer("front_left", this, GL_COLOR_ATTACHMENT0, default_fbo, w, h);
       back_left = new GLFrameBuffer("back_left", this, GL_COLOR_ATTACHMENT0, default_fbo, w, h);
     }
@@ -81,6 +84,7 @@ GLContext::GLContext(void *ghost_window, GLSharedOrphanLists &shared_orphan_list
       front_left = new GLFrameBuffer("front_left", this, GL_FRONT_LEFT, 0, w, h);
       back_left = new GLFrameBuffer("back_left", this, GL_BACK_LEFT, 0, w, h);
     }
+
     GLboolean supports_stereo_quad_buffer = GL_FALSE;
     glGetBooleanv(GL_STEREO, &supports_stereo_quad_buffer);
     if (supports_stereo_quad_buffer) {
@@ -95,7 +99,7 @@ GLContext::GLContext(void *ghost_window, GLSharedOrphanLists &shared_orphan_list
 
   active_fb = back_left;
   static_cast<GLStateManager *>(state_manager)->active_fb = static_cast<GLFrameBuffer *>(
-      back_left);
+      active_fb);
 }
 
 GLContext::~GLContext()
diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh
index 10ae396d138..1cef6e61425 100644
--- a/source/blender/gpu/opengl/gl_context.hh
+++ b/source/blender/gpu/opengl/gl_context.hh
@@ -65,6 +65,7 @@ class GLContext : public Context {
   static bool debug_layer_support;
   static bool texture_cube_map_array_support;
   /** Workarounds. */
+  static bool debug_layer_workaround;
   static bool texture_copy_workaround;
   static bool unused_fb_slot_workaround;
   static float derivative_signs[2];
diff --git a/source/blender/gpu/opengl/gl_debug.cc b/source/blender/gpu/opengl/gl_debug.cc
index 468d1514d60..de88fdc154c 100644
--- a/source/blender/gpu/opengl/gl_debug.cc
+++ b/source/blender/gpu/opengl/gl_debug.cc
@@ -112,17 +112,13 @@ static void APIENTRY debug_callback(GLenum UNUSED(source),
 
 #undef APIENTRY
 
+/* This function needs to be called once per context. */
 void init_gl_callbacks(void)
 {
-#ifdef __APPLE__
-  fprintf(stderr, "GPUDebug: OpenGL debug callback is not available on Apple\n");
-  return;
-#endif /* not Apple */
-
   char msg[256] = "";
   const char format[] = "Successfully hooked OpenGL debug callback using %s";
 
-  if (GLContext::debug_layer_support) {
+  if (GLEW_VERSION_4_3 || GLEW_KHR_debug) {
     SNPRINTF(msg, format, GLEW_VERSION_4_3 ? "OpenGL 4.3" : "KHR_debug extension");
     glEnable(GL_DEBUG_OUTPUT);
     glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
@@ -148,7 +144,8 @@ void init_gl_callbacks(void)
                             msg);
   }
   else {
-    fprintf(stderr, "GPUDebug: Failed to hook OpenGL debug callback\n");
+    fprintf(stderr, "GPUDebug: Failed to hook OpenGL debug callback. Use fallback debug layer.\n");
+    init_debug_layer();
   }
 }
 
@@ -243,4 +240,68 @@ void raise_gl_error(const char *info)
 
 /** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name Object Label
+ *
+ * Useful for debugging through renderdoc. Only defined if using --debug-gpu.
+ * Make sure to bind the object first so that it gets defined by the GL implementation.
+ * \{ */
+
+static const char *to_str_prefix(GLenum type)
+{
+  switch (type) {
+    case GL_FRAGMENT_SHADER:
+    case GL_GEOMETRY_SHADER:
+    case GL_VERTEX_SHADER:
+    case GL_SHADER:
+    case GL_PROGRAM:
+      return "SHD-";
+    case GL_SAMPLER:
+      return "SAM-";
+    case GL_TEXTURE:
+      return "TEX-";
+    case GL_FRAMEBUFFER:
+      return "FBO-";
+    case GL_VERTEX_ARRAY:
+      return "VAO-";
+    case GL_UNIFORM_BUFFER:
+      return "UBO-";
+    case GL_BUFFER:
+      return "BUF-";
+    default:
+      return "";
+  }
+}
+static const char *to_str_suffix(GLenum type)
+{
+  switch (type) {
+    case GL_FRAGMENT_SHADER:
+      return "-Frag";
+    case GL_GEOMETRY_SHADER:
+      return "-Geom";
+    case GL_VERTEX_SHADER:
+      return "-Vert";
+    default:
+      return "";
+  }
+}
+
+void object_label(GLenum type, GLuint object, const char *name)
+{
+  if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) {
+    char label[64];
+    SNPRINTF(label, "%s%s%s", to_str_prefix(type), name, to_str_suffix(type));
+    /* Small convenience for caller. */
+    if (ELEM(type, GL_FRAGMENT_SHADER, GL_GEOMETRY_SHADER, GL_VERTEX_SHADER)) {
+      type = GL_SHADER;
+    }
+    if (ELEM(type, GL_UNIFORM_BUFFER)) {
+      type = GL_BUFFER;
+    }
+    glObjectLabel(type, object, -1, label);
+  }
+}
+
+/** \} */
+
 }  // namespace blender::gpu::debug
diff --git a/source/blender/gpu/opengl/gl_debug.hh b/source/blender/gpu/opengl/gl_debug.hh
index 5537147d0fe..892fb1d2ddb 100644
--- a/source/blender/gpu/opengl/gl_debug.hh
+++ b/source/blender/gpu/opengl/gl_debug.hh
@@ -20,16 +20,60 @@
 
 #pragma once
 
-namespace blender {
-namespace gpu {
-namespace debug {
+#include "gl_context.hh"
 
-/* Enabled on MacOS by default since there is no support for debug callbacks. */
-#if defined(DEBUG) && defined(__APPLE__)
-#  define GL_CHECK_ERROR(info) debug::check_gl_error(info)
-#else
-#  define GL_CHECK_ERROR(info)
-#endif
+#include "glew-mx.h"
+
+/* Manual line breaks for readability. */
+/* clang-format off */
+#define _VA_ARG_LIST1(t) t
+#define _VA_ARG_LIST2(t, a) t a
+#define _VA_ARG_LIST4(t, a, b, c) \
+  _VA_ARG_LIST2(t, a), _VA_ARG_LIST2(b, c)
+#define _VA_ARG_LIST6(t, a, b, c, d, e) \
+  _VA_ARG_LIST2(t, a), _VA_ARG_LIST4(b, c, d, e)
+#define _VA_ARG_LIST8(t, a, b, c, d, e, f, g) \
+  _VA_ARG_LIST2(t, a), _VA_ARG_LIST6(b, c, d, e, f, g)
+#define _VA_ARG_LIST10(t, a, b, c, d, e, f, g, h, i) \
+  _VA_ARG_LIST2(t, a), _VA_ARG_LIST8(b, c, d, e, f, g, h, i)
+#define _VA_ARG_LIST12(t, a, b, c, d, e, f, g, 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list