[Bf-blender-cvs] [09d1c6d8b1a] tmp-gldebuglayer: GL: Add fallback debug layer

Clément Foucault noreply at git.blender.org
Wed Sep 9 00:52:46 CEST 2020


Commit: 09d1c6d8b1a18efbd283fdb8fa6c9733bf56b5c0
Author: Clément Foucault
Date:   Wed Sep 9 00:47:59 2020 +0200
Branches: tmp-gldebuglayer
https://developer.blender.org/rB09d1c6d8b1a18efbd283fdb8fa6c9733bf56b5c0

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 time.

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

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

M	source/blender/gpu/CMakeLists.txt
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

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

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_debug.cc b/source/blender/gpu/opengl/gl_debug.cc
index 468d1514d60..168ac508758 100644
--- a/source/blender/gpu/opengl/gl_debug.cc
+++ b/source/blender/gpu/opengl/gl_debug.cc
@@ -114,11 +114,6 @@ static void APIENTRY debug_callback(GLenum UNUSED(source),
 
 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";
 
@@ -148,7 +143,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();
   }
 }
 
diff --git a/source/blender/gpu/opengl/gl_debug.hh b/source/blender/gpu/opengl/gl_debug.hh
index 5537147d0fe..d792a0d95c2 100644
--- a/source/blender/gpu/opengl/gl_debug.hh
+++ b/source/blender/gpu/opengl/gl_debug.hh
@@ -42,6 +42,8 @@ void check_gl_error(const char *info);
 void check_gl_resources(const char *info);
 void init_gl_callbacks(void);
 
+void init_debug_layer(void);
+
 }  // namespace debug
 }  // namespace gpu
 }  // namespace blender
diff --git a/source/blender/gpu/opengl/gl_debug_layer.cc b/source/blender/gpu/opengl/gl_debug_layer.cc
new file mode 100644
index 00000000000..3e8c4edf190
--- /dev/null
+++ b/source/blender/gpu/opengl/gl_debug_layer.cc
@@ -0,0 +1,190 @@
+/*
+ * 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) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup gpu
+ *
+ * Implement our own subset of KHR_debug extension.
+ * We just wrap some functions
+ */
+
+#include "BLI_utildefines.h"
+
+#include "glew-mx.h"
+
+#include "gl_debug.hh"
+
+namespace blender::gpu::debug {
+
+#define _VA_ARG_LIST1(t) t
+#define _VA_ARG_LIST2(t, a) t a
+#define _VA_ARG_LIST4(t, a, ...) _VA_ARG_LIST2(t, a), _VA_ARG_LIST2(__VA_ARGS__)
+#define _VA_ARG_LIST6(t, a, ...) _VA_ARG_LIST2(t, a), _VA_ARG_LIST4(__VA_ARGS__)
+#define _VA_ARG_LIST8(t, a, ...) _VA_ARG_LIST2(t, a), _VA_ARG_LIST6(__VA_ARGS__)
+#define _VA_ARG_LIST10(t, a, ...) _VA_ARG_LIST2(t, a), _VA_ARG_LIST8(__VA_ARGS__)
+#define _VA_ARG_LIST12(t, a, ...) _VA_ARG_LIST2(t, a), _VA_ARG_LIST10(__VA_ARGS__)
+#define _VA_ARG_LIST14(t, a, ...) _VA_ARG_LIST2(t, a), _VA_ARG_LIST12(__VA_ARGS__)
+#define _VA_ARG_LIST16(t, a, ...) _VA_ARG_LIST2(t, a), _VA_ARG_LIST14(__VA_ARGS__)
+#define _VA_ARG_LIST18(t, a, ...) _VA_ARG_LIST2(t, a), _VA_ARG_LIST16(__VA_ARGS__)
+#define _VA_ARG_LIST20(t, a, ...) _VA_ARG_LIST2(t, a), _VA_ARG_LIST18(__VA_ARGS__)
+#define ARG_LIST(...) VA_NARGS_CALL_OVERLOAD(_VA_ARG_LIST, __VA_ARGS__)
+
+#define _VA_ARG_LIST_CALL1(t)
+#define _VA_ARG_LIST_CALL2(t, a) a
+#define _VA_ARG_LIST_CALL4(t, a, ...) _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL2(__VA_ARGS__)
+#define _VA_ARG_LIST_CALL6(t, a, ...) _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL4(__VA_ARGS__)
+#define _VA_ARG_LIST_CALL8(t, a, ...) _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL6(__VA_ARGS__)
+#define _VA_ARG_LIST_CALL10(t, a, ...) _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL8(__VA_ARGS__)
+#define _VA_ARG_LIST_CALL12(t, a, ...) _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL10(__VA_ARGS__)
+#define _VA_ARG_LIST_CALL14(t, a, ...) _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL12(__VA_ARGS__)
+#define _VA_ARG_LIST_CALL16(t, a, ...) _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL14(__VA_ARGS__)
+#define _VA_ARG_LIST_CALL18(t, a, ...) _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL16(__VA_ARGS__)
+#define _VA_ARG_LIST_CALL20(t, a, ...) _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL18(__VA_ARGS__)
+#define ARG_LIST_CALL(...) VA_NARGS_CALL_OVERLOAD(_VA_ARG_LIST_CALL, __VA_ARGS__)
+
+#define DEBUG_FUNC_DECLARE_VAL(pfn, rtn_type, fn, ...) \
+  pfn real_##fn; \
+  static rtn_type GLAPIENTRY debug_##fn(ARG_LIST(__VA_ARGS__)) \
+  { \
+    check_gl_error("generated before " #fn); \
+    rtn_type ret = real_##fn(ARG_LIST_CALL(__VA_ARGS__)); \
+    check_gl_error("" #fn); \
+    return ret; \
+  }
+
+#define DEBUG_FUNC_DECLARE(pfn, fn, ...) \
+  pfn real_##fn; \
+  static void GLAPIENTRY debug_##fn(ARG_LIST(__VA_ARGS__)) \
+  { \
+    check_gl_error("generated before " #fn); \
+    real_##fn(ARG_LIST_CALL(__VA_ARGS__)); \
+    check_gl_error("" #fn); \
+  }
+
+#define DEBUG_FUNC_DUMMY(pfn, fn, ...) \
+  pfn real_##fn; \
+  static void GLAPIENTRY debug_##fn(ARG_LIST(__VA_ARGS__)) \
+  { \
+    UNUSED_VARS(ARG_LIST_CALL(__VA_ARGS__)); \
+  }
+
+/* List of wrapped functions. We dont have to support all of them.
+ * Some functions might be declared as extern in GLEW. We cannot override them in this case.
+ * Keep the list in alphabetical order. */
+
+/* Avoid very long declarations. */
+/* clang-format off */
+DEBUG_FUNC_DECLARE_VAL(PFNGLMAPBUFFERRANGEPROC, void *, glMapBufferRange, GLenum, target, GLintptr, offset, GLsizeiptr, length, GLbitfield, access);
+DEBUG_FUNC_DECLARE_VAL(PFNGLUNMAPBUFFERPROC, GLboolean, glUnmapBuffer, GLenum, target);
+DEBUG_FUNC_DECLARE(PFNGLBEGINQUERYPROC, glBeginQuery, GLenum, target, GLuint, id);
+DEBUG_FUNC_DECLARE(PFNGLBEGINTRANSFORMFEEDBACKPROC, glBeginTransformFeedback, GLenum, primitiveMode);
+DEBUG_FUNC_DECLARE(PFNGLBINDBUFFERBASEPROC, glBindBufferBase, GLenum, target, GLuint, index, GLuint, buffer);
+DEBUG_FUNC_DECLARE(PFNGLBINDBUFFERPROC, glBindBuffer, GLenum, target, GLuint, buffer);
+DEBUG_FUNC_DECLARE(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer, GLenum, target, GLuint, framebuffer);
+DEBUG_FUNC_DECLARE(PFNGLBINDSAMPLERPROC, glBindSampler, GLuint, unit, GLuint, sampler);
+DEBUG_FUNC_DECLARE(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray, GLuint, array);
+DEBUG_FUNC_DECLARE(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer, GLint, srcX0, GLint, srcY0, GLint, srcX1, GLint, srcY1, GLint, dstX0, GLint, dstY0, GLint, dstX1, GLint, dstY1, GLbitfield, mask, GLenum, filter);
+DEBUG_FUNC_DECLARE(PFNGLBUFFERDATAPROC, glBufferData, GLenum, target, GLsizeiptr, size, const void *, data, GLenum, usage);
+DEBUG_FUNC_DECLARE(PFNGLBUFFERSUBDATAPROC, glBufferSubData, GLenum, target, GLintptr, offset, GLsizeiptr, size, const void *, data);
+DEBUG_FUNC_DECLARE(PFNGLDELETEBUFFERSPROC, glDeleteBuffers, GLsizei, n, const GLuint *, buffers);
+DEBUG_FUNC_DECLARE(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers, GLsizei, n, const GLuint*, framebuffers);
+DEBUG_FUNC_DECLARE(PFNGLDELETEPROGRAMPROC, glDeleteProgram, GLuint, program);
+DEBUG_FUNC_DECLARE(PFNGLDELETEQUERIESPROC, glDeleteQueries, GLsizei, n, const GLuint *, ids);
+DEBUG_FUNC_DECLARE(PFNGLDELETESAMPLERSPROC, glDeleteSamplers, GLsizei, count, const GLuint *, samplers);
+DEBUG_FUNC_DECLARE(PFNGLDELETESHADERPROC, glDeleteShader, GLuint, shader);
+DEBUG_FUNC_DECLARE(PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays, GLsizei, n, const GLuint *, arrays);
+DEBUG_FUNC_DECLARE(PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC, glDrawArraysInstancedBaseInstance, GLenum, mode, GLint, first, GLsizei, count, GLsizei, primcount, GLuint, baseinstance);
+DEBUG_FUNC_DECLARE(PFNGLDRAWARRAYSINSTANCEDPROC, glDrawArraysInstanced, GLenum, mode, GLint, first, GLsizei, count, GLsizei, primcount);
+DEBUG_FUNC_DECLARE(PFNGLDRAWBUFFERSPROC, glDrawBuffers, GLsizei, n, const GLenum*, bufs);
+DEBUG_FUNC_DECLARE(PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC, glDrawElementsInstancedBaseVertexBaseInstance, GLenum, mode, GLsizei, count, GLenum, type, const void *, indices, GLsizei, primcount, GLint, basevertex, GLuint, baseinstance);
+DEBUG_FUNC_DECLARE(PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC, glDrawElementsInstancedBaseVertex, GLenum, mode, GLsizei, count, GLenum, type, const void *, indices, GLsizei, instancecount, GLint, basevertex);
+DEBUG_FUNC_DECLARE(PFNGLENDQUERYPROC, glEndQuery, GLenum, target);
+DEBUG_FUNC_DECLARE(PFNGLENDTRANSFORMFEEDBACKPROC, glEndTransformFeedback, void);
+DEBUG_FUNC_DECLARE(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D, GLenum, target, GLenum, attachment, GLenum, textarget, GLuint, texture, GLint, level);
+DEBUG_FUNC_DECLARE(PFNGLFRAMEBUFFERTEXTURELAYERPROC, glFramebufferTextureLayer, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level, GLint, layer);
+DEBUG_FUNC_DECLARE(PFNGLFRAMEBUFFERTEXTUREPROC, glFramebufferTexture, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level);
+DEBUG_FUNC_DECLARE(PFNGLGENBUFFERSPROC, glGenBuffers, GLsizei, n, GLuint *, buffers);
+DEBUG_FUNC_DECLARE(PFNGLGENERATEMIPMAPPROC, glGenerateMipmap, GLenum, target);
+DEBUG_FUNC_DECLARE(PFNGLGENERATETEXTUREMIPMAPPROC, glGenerateTextureMipmap, GLuint, texture);
+DEBUG_FUNC_DECLARE(PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers, GLsizei, n, GLuint *, framebuffers);
+DEBUG_FUNC_DECLARE(PFNGLGENQUERIESPROC, glGenQueries, GLsizei, n, GLuint *, ids);
+DEBUG_FUNC_DECLARE(PFNGLGENSAMPLERSPROC, glGenSamplers, GLsizei, n, GLuint *, samplers);
+DEBUG_FUNC_DECLARE(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays, GLsizei, n, GLuint *, arrays);
+DEBUG_FUNC_DECLARE(PFNGLLINKPROGRAMPROC, glLinkProgram, GLuin

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list