Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu/opengl')
-rw-r--r--source/blender/gpu/opengl/gl_backend.cc62
-rw-r--r--source/blender/gpu/opengl/gl_batch.cc5
-rw-r--r--source/blender/gpu/opengl/gl_context.cc6
-rw-r--r--source/blender/gpu/opengl/gl_context.hh12
-rw-r--r--source/blender/gpu/opengl/gl_debug.cc75
-rw-r--r--source/blender/gpu/opengl/gl_debug.hh103
-rw-r--r--source/blender/gpu/opengl/gl_debug_layer.cc165
-rw-r--r--source/blender/gpu/opengl/gl_drawlist.cc5
-rw-r--r--source/blender/gpu/opengl/gl_framebuffer.cc21
-rw-r--r--source/blender/gpu/opengl/gl_immediate.cc14
-rw-r--r--source/blender/gpu/opengl/gl_shader.cc49
-rw-r--r--source/blender/gpu/opengl/gl_state.cc10
-rw-r--r--source/blender/gpu/opengl/gl_state.hh4
-rw-r--r--source/blender/gpu/opengl/gl_texture.cc79
-rw-r--r--source/blender/gpu/opengl/gl_uniform_buffer.cc7
-rw-r--r--source/blender/gpu/opengl/gl_vertex_array.cc2
16 files changed, 460 insertions, 159 deletions
diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc
index c8d57a20a38..edaa84cdcf8 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,11 +207,22 @@ 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::clear_texture_support = false;
+ GLContext::copy_image_support = false;
+ GLContext::debug_layer_support = false;
+ GLContext::direct_state_access_support = false;
+ GLContext::fixed_restart_index_support = false;
+ GLContext::multi_bind_support = false;
+ GLContext::multi_draw_indirect_support = false;
+ GLContext::shader_draw_parameters_support = false;
GLContext::texture_cube_map_array_support = false;
+ GLContext::texture_filter_anisotropic_support = false;
+ GLContext::texture_gather_support = false;
+ GLContext::vertex_attrib_binding_support = false;
return;
}
@@ -266,7 +277,7 @@ static void detect_workarounds(void)
* covered since they only support GL 4.4 on windows.
* This fixes some issues with workbench anti-aliasing on Win + Intel GPU. (see T76273) */
if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) && !GLEW_VERSION_4_5) {
- GLContext::texture_copy_workaround = true;
+ GLContext::copy_image_support = false;
}
/* Special fix for theses specific GPUs.
* Without this workaround, blender crashes on startup. (see T72098) */
@@ -303,6 +314,11 @@ static void detect_workarounds(void)
strstr(version, "Mesa 19.1") || strstr(version, "Mesa 19.2"))) {
GLContext::unused_fb_slot_workaround = true;
}
+ /* There is a bug on older Nvidia GPU where GL_ARB_texture_gather
+ * is reported to be supported but yield a compile error (see T55802). */
+ if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) && !GLEW_VERSION_4_0) {
+ GLContext::texture_gather_support = false;
+ }
/* dFdx/dFdy calculation factors, those are dependent on driver. */
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY) &&
@@ -321,6 +337,15 @@ static void detect_workarounds(void)
GLContext::derivative_signs[1] = 1.0;
}
}
+
+ /* Disable multidraw if the base instance cannot be read. */
+ if (GLContext::shader_draw_parameters_support == false) {
+ GLContext::multi_draw_indirect_support = false;
+ }
+ /* Enable our own incomplete debug layer if no other is available. */
+ if (GLContext::debug_layer_support == false) {
+ GLContext::debug_layer_workaround = true;
+ }
}
/** Internal capabilities. */
@@ -330,10 +355,20 @@ GLint GLContext::max_ubo_size;
GLint GLContext::max_ubo_binds;
/** Extensions. */
bool GLContext::base_instance_support = false;
+bool GLContext::clear_texture_support = false;
+bool GLContext::copy_image_support = false;
bool GLContext::debug_layer_support = false;
+bool GLContext::direct_state_access_support = false;
+bool GLContext::fixed_restart_index_support = false;
+bool GLContext::multi_bind_support = false;
+bool GLContext::multi_draw_indirect_support = false;
+bool GLContext::shader_draw_parameters_support = false;
bool GLContext::texture_cube_map_array_support = false;
+bool GLContext::texture_filter_anisotropic_support = false;
+bool GLContext::texture_gather_support = false;
+bool GLContext::vertex_attrib_binding_support = false;
/** Workarounds. */
-bool GLContext::texture_copy_workaround = false;
+bool GLContext::debug_layer_workaround = false;
bool GLContext::unused_fb_slot_workaround = false;
float GLContext::derivative_signs[2] = {1.0f, 1.0f};
@@ -354,15 +389,26 @@ void GLBackend::capabilities_init(void)
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &GLContext::max_ubo_binds);
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &GLContext::max_ubo_size);
GLContext::base_instance_support = GLEW_ARB_base_instance;
+ GLContext::clear_texture_support = GLEW_ARB_clear_texture;
+ GLContext::copy_image_support = GLEW_ARB_copy_image;
+ GLContext::debug_layer_support = GLEW_VERSION_4_3 || GLEW_KHR_debug || GLEW_ARB_debug_output;
+ GLContext::direct_state_access_support = GLEW_ARB_direct_state_access;
+ GLContext::fixed_restart_index_support = GLEW_ARB_ES3_compatibility;
+ GLContext::multi_bind_support = GLEW_ARB_multi_bind;
+ GLContext::multi_draw_indirect_support = GLEW_ARB_multi_draw_indirect;
+ GLContext::shader_draw_parameters_support = GLEW_ARB_shader_draw_parameters;
GLContext::texture_cube_map_array_support = GLEW_ARB_texture_cube_map_array;
- GLContext::debug_layer_support = (GLEW_VERSION_4_3 || GLEW_KHR_debug);
+ GLContext::texture_filter_anisotropic_support = GLEW_EXT_texture_filter_anisotropic;
+ GLContext::texture_gather_support = GLEW_ARB_texture_gather;
+ GLContext::vertex_attrib_binding_support = GLEW_ARB_vertex_attrib_binding;
+
+ 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..ca627775e1f 100644
--- a/source/blender/gpu/opengl/gl_batch.cc
+++ b/source/blender/gpu/opengl/gl_batch.cc
@@ -307,7 +307,7 @@ void GLBatch::bind(int i_first)
#if GPU_TRACK_INDEX_RANGE
/* Can be removed if GL 4.3 is required. */
- if (!GLEW_ARB_ES3_compatibility && (elem != NULL)) {
+ if (!GLContext::fixed_restart_index_support && (elem != NULL)) {
glPrimitiveRestartIndex(this->elem_()->restart_index());
}
#endif
@@ -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..9822c842ce7 100644
--- a/source/blender/gpu/opengl/gl_context.hh
+++ b/source/blender/gpu/opengl/gl_context.hh
@@ -62,10 +62,20 @@ class GLContext : public Context {
static GLint max_ubo_binds;
/** Extensions. */
static bool base_instance_support;
+ static bool clear_texture_support;
+ static bool copy_image_support;
static bool debug_layer_support;
+ static bool direct_state_access_support;
+ static bool fixed_restart_index_support;
+ static bool multi_bind_support;
+ static bool multi_draw_indirect_support;
+ static bool shader_draw_parameters_support;
static bool texture_cube_map_array_support;
+ static bool texture_filter_anisotropic_support;
+ static bool texture_gather_support;
+ static bool vertex_attrib_binding_support;
/** Workarounds. */
- static bool texture_copy_workaround;
+ static bool debug_layer_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..db99e90d0ec 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 render-doc. 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, h, i, j, k) \
+ _VA_ARG_LIST2(t, a), _VA_ARG_LIST10(b, c, d, e, f, g, h, i, j, k)
+#define _VA_ARG_LIST14(t, a, b, c, d, e, f, g, h, i, j, k, l, m) \
+ _VA_ARG_LIST2(t, a), _VA_ARG_LIST12(b, c, d, e, f, g, h, i, j, k, l, m)
+#define _VA_ARG_LIST16(t, a, b, c, d, e, f, g, h, i, j, k, l, m, o, p) \
+ _VA_ARG_LIST2(t, a), _VA_ARG_LIST14(b, c, d, e, f, g, h, i, j, k, l, m, o, p)
+#define _VA_ARG_LIST18(t, a, b, c, d, e, f, g, h, i, j, k, l, m, o, p, q, r) \
+ _VA_ARG_LIST2(t, a), _VA_ARG_LIST16(b, c, d, e, f, g, h, i, j, k, l, m, o, p, q, r)
+#define _VA_ARG_LIST20(t, a, b, c, d, e, f, g, h, i, j, k, l, m, o, p, q, r, s, u) \
+ _VA_ARG_LIST2(t, a), _VA_ARG_LIST18(b, c, d, e, f, g, h, i, j, k, l, m, o, p, q, r, s, u)
+#define _VA_ARG_LIST22(t, a, b, c, d, e, f, g, h, i, j, k, l, m, o, p, q, r, s, u, v, w) \
+ _VA_ARG_LIST2(t, a), _VA_ARG_LIST20(b, c, d, e, f, g, h, i, j, k, l, m, o, p, q, r, s, u, v, w)
+#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, b, c) \
+ _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL2(b, c)
+#define _VA_ARG_LIST_CALL6(t, a, b, c, d, e) \
+ _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL4(b, c, d, e)
+#define _VA_ARG_LIST_CALL8(t, a, b, c, d, e, f, g) \
+ _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL6(b, c, d, e, f, g)
+#define _VA_ARG_LIST_CALL10(t, a, b, c, d, e, f, g, h, i) \
+ _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL8(b, c, d, e, f, g, h, i)
+#define _VA_ARG_LIST_CALL12(t, a, b, c, d, e, f, g, h, i, j, k) \
+ _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL10(b, c, d, e, f, g, h, i, j, k)
+#define _VA_ARG_LIST_CALL14(t, a, b, c, d, e, f, g, h, i, j, k, l, m) \
+ _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL12(b, c, d, e, f, g, h, i, j, k, l, m)
+#define _VA_ARG_LIST_CALL16(t, a, b, c, d, e, f, g, h, i, j, k, l, m, o, p) \
+ _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL14(b, c, d, e, f, g, h, i, j, k, l, m, o, p)
+#define _VA_ARG_LIST_CALL18(t, a, b, c, d, e, f, g, h, i, j, k, l, m, o, p, q, r) \
+ _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL16(b, c, d, e, f, g, h, i, j, k, l, m, o, p, q, r)
+#define _VA_ARG_LIST_CALL20(t, a, b, c, d, e, f, g, h, i, j, k, l, m, o, p, q, r, s, u) \
+ _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL18(b, c, d, e, f, g, h, i, j, k, l, m, o, p, q, r, s, u)
+#define _VA_ARG_LIST_CALL22(t, a, b, c, d, e, f, g, h, i, j, k, l, m, o, p, q, r, s, u, v, w) \
+ _VA_ARG_LIST_CALL2(t, a), _VA_ARG_LIST_CALL20(b, c, d, e, f, g, h, i, j, k, l, m, o, p, q, r, s, u, v, w)
+#define ARG_LIST_CALL(...) VA_NARGS_CALL_OVERLOAD(_VA_ARG_LIST_CALL, __VA_ARGS__)
+/* clang-format on */
#ifdef DEBUG
# define GL_CHECK_RESOURCES(info) debug::check_gl_resources(info)
@@ -37,11 +81,52 @@ namespace debug {
# define GL_CHECK_RESOURCES(info)
#endif
+namespace blender {
+namespace gpu {
+namespace debug {
+
void raise_gl_error(const char *info);
void check_gl_error(const char *info);
void check_gl_resources(const char *info);
void init_gl_callbacks(void);
+void init_debug_layer(void);
+
+void object_label(GLenum type, GLuint object, const char *name);
+
} // namespace debug
+
+#define DEBUG_FUNC_OVERRIDE(func, ...) \
+ inline void func(ARG_LIST(__VA_ARGS__)) \
+ { \
+ if (GLContext::debug_layer_workaround) { \
+ debug::check_gl_error("generated before " #func); \
+ ::func(ARG_LIST_CALL(__VA_ARGS__)); \
+ debug::check_gl_error("" #func); \
+ } \
+ else { \
+ ::func(ARG_LIST_CALL(__VA_ARGS__)); \
+ } \
+ }
+
+/* Avoid very long declarations. */
+/* clang-format off */
+DEBUG_FUNC_OVERRIDE(glClear, GLbitfield, mask);
+DEBUG_FUNC_OVERRIDE(glDeleteTextures, GLsizei, n, const GLuint *, textures);
+DEBUG_FUNC_OVERRIDE(glDrawArrays, GLenum, mode, GLint, first, GLsizei, count);
+DEBUG_FUNC_OVERRIDE(glFinish, void);
+DEBUG_FUNC_OVERRIDE(glFlush, void);
+DEBUG_FUNC_OVERRIDE(glGenTextures, GLsizei, n, GLuint *, textures);
+DEBUG_FUNC_OVERRIDE(glGetTexImage, GLenum, target, GLint, level, GLenum, format, GLenum, type, void *, pixels);
+DEBUG_FUNC_OVERRIDE(glReadBuffer, GLenum, mode);
+DEBUG_FUNC_OVERRIDE(glReadPixels, GLint, x, GLint, y, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, void *, pixels);
+DEBUG_FUNC_OVERRIDE(glTexImage1D, GLenum, target, GLint, level, GLint, internalformat, GLsizei, width, GLint, border, GLenum, format, GLenum, type, const void *, pixels);
+DEBUG_FUNC_OVERRIDE(glTexImage2D, GLenum, target, GLint, level, GLint, internalformat, GLsizei, width, GLsizei, height, GLint, border, GLenum, format, GLenum, type, const void *, pixels);
+DEBUG_FUNC_OVERRIDE(glTexParameteri, GLenum, target, GLenum, pname, GLint, param);
+DEBUG_FUNC_OVERRIDE(glTexParameteriv, GLenum, target, GLenum, pname, const GLint *, params);
+DEBUG_FUNC_OVERRIDE(glTexSubImage1D, GLenum, target, GLint, level, GLint, xoffset, GLsizei, width, GLenum, format, GLenum, type, const void *, pixels);
+DEBUG_FUNC_OVERRIDE(glTexSubImage2D, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, const void *, pixels);
+/* clang-format on */
+
} // 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..801cb9dbfbd
--- /dev/null
+++ b/source/blender/gpu/opengl/gl_debug_layer.cc
@@ -0,0 +1,165 @@
+/*
+ * 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 override the functions pointers by our own implementation that just checks glGetError.
+ */
+
+#include "BLI_utildefines.h"
+
+#include "glew-mx.h"
+
+#include "gl_debug.hh"
+
+typedef void *GPUvoidptr;
+
+#define GPUvoidptr_set void *ret =
+#define GPUvoidptr_ret return ret
+
+#define GLboolean_set GLboolean ret =
+#define GLboolean_ret return ret
+
+#define void_set
+#define void_ret
+
+#define DEBUG_FUNC_DECLARE(pfn, rtn_type, fn, ...) \
+ pfn real_##fn; \
+ static rtn_type GLAPIENTRY debug_##fn(ARG_LIST(__VA_ARGS__)) \
+ { \
+ debug::check_gl_error("generated before " #fn); \
+ rtn_type##_set real_##fn(ARG_LIST_CALL(__VA_ARGS__)); \
+ debug::check_gl_error("" #fn); \
+ rtn_type##_ret; \
+ }
+
+namespace blender::gpu::debug {
+
+/* 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(PFNGLBEGINQUERYPROC, void, glBeginQuery, GLenum, target, GLuint, id);
+DEBUG_FUNC_DECLARE(PFNGLBEGINTRANSFORMFEEDBACKPROC, void, glBeginTransformFeedback, GLenum, primitiveMode);
+DEBUG_FUNC_DECLARE(PFNGLBINDBUFFERBASEPROC, void, glBindBufferBase, GLenum, target, GLuint, index, GLuint, buffer);
+DEBUG_FUNC_DECLARE(PFNGLBINDBUFFERPROC, void, glBindBuffer, GLenum, target, GLuint, buffer);
+DEBUG_FUNC_DECLARE(PFNGLBINDFRAMEBUFFERPROC, void, glBindFramebuffer, GLenum, target, GLuint, framebuffer);
+DEBUG_FUNC_DECLARE(PFNGLBINDSAMPLERPROC, void, glBindSampler, GLuint, unit, GLuint, sampler);
+DEBUG_FUNC_DECLARE(PFNGLBINDVERTEXARRAYPROC, void, glBindVertexArray, GLuint, array);
+DEBUG_FUNC_DECLARE(PFNGLBLITFRAMEBUFFERPROC, void, 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, void, glBufferData, GLenum, target, GLsizeiptr, size, const void *, data, GLenum, usage);
+DEBUG_FUNC_DECLARE(PFNGLBUFFERSUBDATAPROC, void, glBufferSubData, GLenum, target, GLintptr, offset, GLsizeiptr, size, const void *, data);
+DEBUG_FUNC_DECLARE(PFNGLDELETEBUFFERSPROC, void, glDeleteBuffers, GLsizei, n, const GLuint *, buffers);
+DEBUG_FUNC_DECLARE(PFNGLDELETEFRAMEBUFFERSPROC, void, glDeleteFramebuffers, GLsizei, n, const GLuint*, framebuffers);
+DEBUG_FUNC_DECLARE(PFNGLDELETEPROGRAMPROC, void, glDeleteProgram, GLuint, program);
+DEBUG_FUNC_DECLARE(PFNGLDELETEQUERIESPROC, void, glDeleteQueries, GLsizei, n, const GLuint *, ids);
+DEBUG_FUNC_DECLARE(PFNGLDELETESAMPLERSPROC, void, glDeleteSamplers, GLsizei, count, const GLuint *, samplers);
+DEBUG_FUNC_DECLARE(PFNGLDELETESHADERPROC, void, glDeleteShader, GLuint, shader);
+DEBUG_FUNC_DECLARE(PFNGLDELETEVERTEXARRAYSPROC, void, glDeleteVertexArrays, GLsizei, n, const GLuint *, arrays);
+DEBUG_FUNC_DECLARE(PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC, void, glDrawArraysInstancedBaseInstance, GLenum, mode, GLint, first, GLsizei, count, GLsizei, primcount, GLuint, baseinstance);
+DEBUG_FUNC_DECLARE(PFNGLDRAWARRAYSINSTANCEDPROC, void, glDrawArraysInstanced, GLenum, mode, GLint, first, GLsizei, count, GLsizei, primcount);
+DEBUG_FUNC_DECLARE(PFNGLDRAWBUFFERSPROC, void, glDrawBuffers, GLsizei, n, const GLenum*, bufs);
+DEBUG_FUNC_DECLARE(PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC, void, glDrawElementsInstancedBaseVertexBaseInstance, GLenum, mode, GLsizei, count, GLenum, type, const void *, indices, GLsizei, primcount, GLint, basevertex, GLuint, baseinstance);
+DEBUG_FUNC_DECLARE(PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC, void, glDrawElementsInstancedBaseVertex, GLenum, mode, GLsizei, count, GLenum, type, const void *, indices, GLsizei, instancecount, GLint, basevertex);
+DEBUG_FUNC_DECLARE(PFNGLENDQUERYPROC, void, glEndQuery, GLenum, target);
+DEBUG_FUNC_DECLARE(PFNGLENDTRANSFORMFEEDBACKPROC, void, glEndTransformFeedback, void);
+DEBUG_FUNC_DECLARE(PFNGLFRAMEBUFFERTEXTURE2DPROC, void, glFramebufferTexture2D, GLenum, target, GLenum, attachment, GLenum, textarget, GLuint, texture, GLint, level);
+DEBUG_FUNC_DECLARE(PFNGLFRAMEBUFFERTEXTURELAYERPROC, void, glFramebufferTextureLayer, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level, GLint, layer);
+DEBUG_FUNC_DECLARE(PFNGLFRAMEBUFFERTEXTUREPROC, void, glFramebufferTexture, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level);
+DEBUG_FUNC_DECLARE(PFNGLGENBUFFERSPROC, void, glGenBuffers, GLsizei, n, GLuint *, buffers);
+DEBUG_FUNC_DECLARE(PFNGLGENERATEMIPMAPPROC, void, glGenerateMipmap, GLenum, target);
+DEBUG_FUNC_DECLARE(PFNGLGENERATETEXTUREMIPMAPPROC, void, glGenerateTextureMipmap, GLuint, texture);
+DEBUG_FUNC_DECLARE(PFNGLGENFRAMEBUFFERSPROC, void, glGenFramebuffers, GLsizei, n, GLuint *, framebuffers);
+DEBUG_FUNC_DECLARE(PFNGLGENQUERIESPROC, void, glGenQueries, GLsizei, n, GLuint *, ids);
+DEBUG_FUNC_DECLARE(PFNGLGENSAMPLERSPROC, void, glGenSamplers, GLsizei, n, GLuint *, samplers);
+DEBUG_FUNC_DECLARE(PFNGLGENVERTEXARRAYSPROC, void, glGenVertexArrays, GLsizei, n, GLuint *, arrays);
+DEBUG_FUNC_DECLARE(PFNGLLINKPROGRAMPROC, void, glLinkProgram, GLuint, program);
+DEBUG_FUNC_DECLARE(PFNGLMAPBUFFERRANGEPROC, GPUvoidptr, glMapBufferRange, GLenum, target, GLintptr, offset, GLsizeiptr, length, GLbitfield, access);
+DEBUG_FUNC_DECLARE(PFNGLTEXBUFFERPROC, void, glTexBuffer, GLenum, target, GLenum, internalFormat, GLuint, buffer);
+DEBUG_FUNC_DECLARE(PFNGLTEXIMAGE3DPROC, void, glTexImage3D, GLenum, target, GLint, level, GLint, internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, GLint, border, GLenum, format, GLenum, type, const GLvoid *,pixels);
+DEBUG_FUNC_DECLARE(PFNGLTEXSUBIMAGE3DPROC, void, glTexSubImage3D, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, format, GLenum, type, const GLvoid *, pixels);
+DEBUG_FUNC_DECLARE(PFNGLTEXTUREBUFFERPROC, void, glTextureBuffer, GLuint, texture, GLenum, internalformat, GLuint, buffer);
+DEBUG_FUNC_DECLARE(PFNGLUNMAPBUFFERPROC, GLboolean, glUnmapBuffer, GLenum, target);
+DEBUG_FUNC_DECLARE(PFNGLUSEPROGRAMPROC, void, glUseProgram, GLuint, program);
+/* clang-format on */
+
+#undef DEBUG_FUNC_DECLARE
+
+/* Init a fallback layer (to KHR_debug) that covers only some functions.
+ * We override the functions pointers by our own implementation that just checks glGetError.
+ * Some additional functions (not overridable) are covered inside the header using wrappers. */
+void init_debug_layer(void)
+{
+#define DEBUG_WRAP(function) \
+ do { \
+ real_##function = ::function; \
+ ::function = &debug_##function; \
+ } while (0)
+
+ DEBUG_WRAP(glBeginQuery);
+ DEBUG_WRAP(glBeginTransformFeedback);
+ DEBUG_WRAP(glBindBuffer);
+ DEBUG_WRAP(glBindBufferBase);
+ DEBUG_WRAP(glBindFramebuffer);
+ DEBUG_WRAP(glBindSampler);
+ DEBUG_WRAP(glBindVertexArray);
+ DEBUG_WRAP(glBlitFramebuffer);
+ DEBUG_WRAP(glBufferData);
+ DEBUG_WRAP(glBufferSubData);
+ DEBUG_WRAP(glDeleteBuffers);
+ DEBUG_WRAP(glDeleteFramebuffers);
+ DEBUG_WRAP(glDeleteProgram);
+ DEBUG_WRAP(glDeleteQueries);
+ DEBUG_WRAP(glDeleteSamplers);
+ DEBUG_WRAP(glDeleteShader);
+ DEBUG_WRAP(glDeleteVertexArrays);
+ DEBUG_WRAP(glDrawArraysInstanced);
+ DEBUG_WRAP(glDrawArraysInstancedBaseInstance);
+ DEBUG_WRAP(glDrawBuffers);
+ DEBUG_WRAP(glDrawElementsInstancedBaseVertex);
+ DEBUG_WRAP(glDrawElementsInstancedBaseVertexBaseInstance);
+ DEBUG_WRAP(glEndQuery);
+ DEBUG_WRAP(glEndTransformFeedback);
+ DEBUG_WRAP(glFramebufferTexture);
+ DEBUG_WRAP(glFramebufferTexture2D);
+ DEBUG_WRAP(glFramebufferTextureLayer);
+ DEBUG_WRAP(glGenBuffers);
+ DEBUG_WRAP(glGenerateMipmap);
+ DEBUG_WRAP(glGenerateTextureMipmap);
+ DEBUG_WRAP(glGenFramebuffers);
+ DEBUG_WRAP(glGenQueries);
+ DEBUG_WRAP(glGenSamplers);
+ DEBUG_WRAP(glGenVertexArrays);
+ DEBUG_WRAP(glLinkProgram);
+ DEBUG_WRAP(glMapBufferRange);
+ DEBUG_WRAP(glTexBuffer);
+ DEBUG_WRAP(glTexImage3D);
+ DEBUG_WRAP(glTexSubImage3D);
+ DEBUG_WRAP(glTextureBuffer);
+ DEBUG_WRAP(glUnmapBuffer);
+ DEBUG_WRAP(glUseProgram);
+
+#undef DEBUG_WRAP
+}
+
+} // namespace blender::gpu::debug \ No newline at end of file
diff --git a/source/blender/gpu/opengl/gl_drawlist.cc b/source/blender/gpu/opengl/gl_drawlist.cc
index 6e3b1107b9c..990e1a8014b 100644
--- a/source/blender/gpu/opengl/gl_drawlist.cc
+++ b/source/blender/gpu/opengl/gl_drawlist.cc
@@ -41,8 +41,6 @@
#include <limits.h>
-#define USE_MULTI_DRAW_INDIRECT 1
-
using namespace blender::gpu;
typedef struct GLDrawCommand {
@@ -75,8 +73,7 @@ GLDrawList::GLDrawList(int length)
data_size_ = 0;
data_ = NULL;
- if (USE_MULTI_DRAW_INDIRECT && GLEW_ARB_multi_draw_indirect &&
- GLContext::base_instance_support) {
+ if (GLContext::multi_draw_indirect_support) {
/* Alloc the biggest possible command list, which is indexed. */
buffer_size_ = sizeof(GLDrawCommandIndexed) * length;
}
diff --git a/source/blender/gpu/opengl/gl_framebuffer.cc b/source/blender/gpu/opengl/gl_framebuffer.cc
index bfc8a2f74eb..1578c5fa619 100644
--- a/source/blender/gpu/opengl/gl_framebuffer.cc
+++ b/source/blender/gpu/opengl/gl_framebuffer.cc
@@ -26,10 +26,12 @@
#include "GPU_capabilities.h"
#include "gl_backend.hh"
-#include "gl_framebuffer.hh"
+#include "gl_debug.hh"
#include "gl_state.hh"
#include "gl_texture.hh"
+#include "gl_framebuffer.hh"
+
namespace blender::gpu {
/* -------------------------------------------------------------------- */
@@ -63,10 +65,8 @@ GLFrameBuffer::GLFrameBuffer(
viewport_[2] = scissor_[2] = w;
viewport_[3] = scissor_[3] = h;
- if (fbo_id_ && GLContext::debug_layer_support) {
- char sh_name[32];
- SNPRINTF(sh_name, "FrameBuffer-%s", name);
- glObjectLabel(GL_FRAMEBUFFER, fbo_id_, -1, sh_name);
+ if (fbo_id_) {
+ debug::object_label(GL_FRAMEBUFFER, fbo_id_, name_);
}
}
@@ -97,14 +97,11 @@ void GLFrameBuffer::init(void)
context_ = GLContext::get();
state_manager_ = static_cast<GLStateManager *>(context_->state_manager);
glGenFramebuffers(1, &fbo_id_);
+ /* Binding before setting the label is needed on some drivers.
+ * This is not an issue since we call this function only before binding. */
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_);
- if (GLContext::debug_layer_support) {
- char sh_name[64];
- SNPRINTF(sh_name, "FrameBuffer-%s", name_);
- /* Binding before setting the label is needed on some drivers. */
- glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_);
- glObjectLabel(GL_FRAMEBUFFER, fbo_id_, -1, sh_name);
- }
+ debug::object_label(GL_FRAMEBUFFER, fbo_id_, name_);
}
/** \} */
diff --git a/source/blender/gpu/opengl/gl_immediate.cc b/source/blender/gpu/opengl/gl_immediate.cc
index 7afbbf9965c..fd31d77cc80 100644
--- a/source/blender/gpu/opengl/gl_immediate.cc
+++ b/source/blender/gpu/opengl/gl_immediate.cc
@@ -60,11 +60,9 @@ GLImmediate::GLImmediate()
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
- if (GLContext::debug_layer_support) {
- glObjectLabel(GL_VERTEX_ARRAY, vao_id_, -1, "VAO-Immediate");
- glObjectLabel(GL_BUFFER, buffer.vbo_id, -1, "VBO-ImmediateBuffer");
- glObjectLabel(GL_BUFFER, buffer_strict.vbo_id, -1, "VBO-ImmediateBufferStrict");
- }
+ debug::object_label(GL_VERTEX_ARRAY, vao_id_, "Immediate");
+ debug::object_label(GL_BUFFER, buffer.vbo_id, "ImmediateVbo");
+ debug::object_label(GL_BUFFER, buffer_strict.vbo_id, "ImmediateVboStrict");
}
GLImmediate::~GLImmediate()
@@ -89,7 +87,6 @@ uchar *GLImmediate::begin()
const size_t available_bytes = buffer_size() - buffer_offset();
GL_CHECK_RESOURCES("Immediate");
- GL_CHECK_ERROR("Immediate Pre-Begin");
glBindBuffer(GL_ARRAY_BUFFER, vbo_id());
@@ -133,7 +130,6 @@ uchar *GLImmediate::begin()
}
void *data = glMapBufferRange(GL_ARRAY_BUFFER, buffer_offset(), bytes_needed, access);
BLI_assert(data != NULL);
- GL_CHECK_ERROR("Immediate Post-Begin");
bytes_mapped_ = bytes_needed;
return (uchar *)data;
@@ -155,8 +151,6 @@ void GLImmediate::end(void)
}
glUnmapBuffer(GL_ARRAY_BUFFER);
- GL_CHECK_ERROR("Immediate Post-Unmap");
-
if (vertex_len > 0) {
GLContext::get()->state_manager->apply_state();
@@ -180,8 +174,6 @@ void GLImmediate::end(void)
* They are not required so just comment them. (T55722) */
// glBindBuffer(GL_ARRAY_BUFFER, 0);
// glBindVertexArray(0);
-
- GL_CHECK_ERROR("Immediate Post-drawing");
}
buffer_offset() += buffer_bytes_used;
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc
index 4314ecfa6be..c400f218f5a 100644
--- a/source/blender/gpu/opengl/gl_shader.cc
+++ b/source/blender/gpu/opengl/gl_shader.cc
@@ -28,6 +28,7 @@
#include "GPU_platform.h"
#include "gl_backend.hh"
+#include "gl_debug.hh"
#include "gl_vertex_buffer.hh"
#include "gl_shader.hh"
@@ -48,11 +49,7 @@ GLShader::GLShader(const char *name) : Shader(name)
#endif
shader_program_ = glCreateProgram();
- if (GLContext::debug_layer_support) {
- char sh_name[64];
- SNPRINTF(sh_name, "ShaderProgram-%s", name);
- glObjectLabel(GL_PROGRAM, shader_program_, -1, sh_name);
- }
+ debug::object_label(GL_PROGRAM, shader_program_, name);
}
GLShader::~GLShader(void)
@@ -88,25 +85,15 @@ char *GLShader::glsl_patch_get(void)
/* Enable extensions for features that are not part of our base GLSL version
* don't use an extension for something already available! */
- if (GLEW_ARB_texture_gather) {
- /* There is a bug on older Nvidia GPU where GL_ARB_texture_gather
- * is reported to be supported but yield a compile error (see T55802). */
- if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) || GLEW_VERSION_4_0) {
- STR_CONCAT(patch, slen, "#extension GL_ARB_texture_gather: enable\n");
-
- /* Some drivers don't agree on GLEW_ARB_texture_gather and the actual support in the
- * shader so double check the preprocessor define (see T56544). */
- if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) && !GLEW_VERSION_4_0) {
- STR_CONCAT(patch, slen, "#ifdef GL_ARB_texture_gather\n");
- STR_CONCAT(patch, slen, "# define GPU_ARB_texture_gather\n");
- STR_CONCAT(patch, slen, "#endif\n");
- }
- else {
- STR_CONCAT(patch, slen, "#define GPU_ARB_texture_gather\n");
- }
- }
+ if (GLContext::texture_gather_support) {
+ STR_CONCAT(patch, slen, "#extension GL_ARB_texture_gather: enable\n");
+ /* Some drivers don't agree on GLEW_ARB_texture_gather and the actual support in the
+ * shader so double check the preprocessor define (see T56544). */
+ STR_CONCAT(patch, slen, "#ifdef GL_ARB_texture_gather\n");
+ STR_CONCAT(patch, slen, "# define GPU_ARB_texture_gather\n");
+ STR_CONCAT(patch, slen, "#endif\n");
}
- if (GLEW_ARB_shader_draw_parameters) {
+ if (GLContext::shader_draw_parameters_support) {
STR_CONCAT(patch, slen, "#extension GL_ARB_shader_draw_parameters : enable\n");
STR_CONCAT(patch, slen, "#define GPU_ARB_shader_draw_parameters\n");
}
@@ -163,21 +150,7 @@ GLuint GLShader::create_shader_stage(GLenum gl_stage, MutableSpan<const char *>
return 0;
}
- if (GLContext::debug_layer_support) {
- char sh_name[64];
- switch (gl_stage) {
- case GL_VERTEX_SHADER:
- BLI_snprintf(sh_name, sizeof(sh_name), "VertShader-%s", name);
- break;
- case GL_GEOMETRY_SHADER:
- BLI_snprintf(sh_name, sizeof(sh_name), "GeomShader-%s", name);
- break;
- case GL_FRAGMENT_SHADER:
- BLI_snprintf(sh_name, sizeof(sh_name), "FragShader-%s", name);
- break;
- }
- glObjectLabel(GL_SHADER, shader, -1, sh_name);
- }
+ debug::object_label(gl_stage, shader, name);
glAttachShader(shader_program_, shader);
return shader;
diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc
index 6dcb56288e8..1678760e9cd 100644
--- a/source/blender/gpu/opengl/gl_state.cc
+++ b/source/blender/gpu/opengl/gl_state.cc
@@ -30,6 +30,7 @@
#include "glew-mx.h"
#include "gl_context.hh"
+#include "gl_debug.hh"
#include "gl_framebuffer.hh"
#include "gl_texture.hh"
@@ -55,7 +56,7 @@ GLStateManager::GLStateManager(void) : GPUStateManager()
glPrimitiveRestartIndex((GLuint)0xFFFFFFFF);
/* TODO: Should become default. But needs at least GL 4.3 */
- if (GLEW_ARB_ES3_compatibility) {
+ if (GLContext::fixed_restart_index_support) {
/* Takes precedence over #GL_PRIMITIVE_RESTART. */
glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
}
@@ -140,13 +141,13 @@ void GLStateManager::set_mutable_state(const GPUStateMutable &state)
GPUStateMutable changed = state ^ current_mutable_;
/* TODO remove, should be uniform. */
- if (changed.point_size != 0) {
+ if (float_as_uint(changed.point_size) != 0) {
if (state.point_size > 0.0f) {
glEnable(GL_PROGRAM_POINT_SIZE);
- glPointSize(state.point_size);
}
else {
glDisable(GL_PROGRAM_POINT_SIZE);
+ glPointSize(fabsf(state.point_size));
}
}
@@ -453,7 +454,6 @@ void GLStateManager::texture_bind(Texture *tex_, eGPUSamplerState sampler_type,
/* Bind the texture to slot 0 for editing purpose. Used by legacy pipeline. */
void GLStateManager::texture_bind_temp(GLTexture *tex)
{
- // BLI_assert(!GLEW_ARB_direct_state_access);
glActiveTexture(GL_TEXTURE0);
glBindTexture(tex->target_, tex->tex_id_);
/* Will reset the first texture that was originally bound to slot 0 back before drawing. */
@@ -505,7 +505,7 @@ void GLStateManager::texture_bind_apply(void)
int last = 64 - bitscan_reverse_uint64(dirty_bind);
int count = last - first;
- if (GLEW_ARB_multi_bind) {
+ if (GLContext::multi_bind_support) {
glBindTextures(first, count, textures_ + first);
glBindSamplers(first, count, samplers_ + first);
}
diff --git a/source/blender/gpu/opengl/gl_state.hh b/source/blender/gpu/opengl/gl_state.hh
index db9b9721ad5..fb2ed3403f7 100644
--- a/source/blender/gpu/opengl/gl_state.hh
+++ b/source/blender/gpu/opengl/gl_state.hh
@@ -42,8 +42,8 @@ class GLTexture;
**/
class GLStateManager : public GPUStateManager {
public:
- /** Anothter reference to tje active framebuffer. */
- GLFrameBuffer *active_fb;
+ /** Anothter reference to the active framebuffer. */
+ GLFrameBuffer *active_fb = nullptr;
private:
/** Current state of the GL implementation. Avoids resetting the whole state for every change. */
diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc
index ec08b736af2..ef4b2d1d4d3 100644
--- a/source/blender/gpu/opengl/gl_texture.cc
+++ b/source/blender/gpu/opengl/gl_texture.cc
@@ -89,21 +89,14 @@ bool GLTexture::init_internal(void)
this->ensure_mipmaps(0);
/* Avoid issue with incomplete textures. */
- if (GLEW_ARB_direct_state_access) {
+ if (GLContext::direct_state_access_support) {
glTextureParameteri(tex_id_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
else {
glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
- if (GLContext::debug_layer_support) {
- char sh_name[64];
- SNPRINTF(sh_name, "Texture-%s", name_);
- /* Binding before setting the label is needed on some drivers. */
- glObjectLabel(GL_TEXTURE, tex_id_, -1, sh_name);
- }
-
- GL_CHECK_ERROR("Post-texture creation");
+ debug::object_label(GL_TEXTURE, tex_id_, name_);
return true;
}
@@ -118,21 +111,15 @@ bool GLTexture::init_internal(GPUVertBuf *vbo)
GLenum internal_format = to_gl_internal_format(format_);
- if (GLEW_ARB_direct_state_access) {
+ if (GLContext::direct_state_access_support) {
glTextureBuffer(tex_id_, internal_format, gl_vbo->vbo_id_);
}
else {
glTexBuffer(target_, internal_format, gl_vbo->vbo_id_);
}
- if (GLContext::debug_layer_support) {
- char sh_name[64];
- SNPRINTF(sh_name, "Texture-%s", name_);
- /* Binding before setting the label is needed on some drivers. */
- glObjectLabel(GL_TEXTURE, tex_id_, -1, sh_name);
- }
+ debug::object_label(GL_TEXTURE, tex_id_, name_);
- GL_CHECK_ERROR("Post-texture buffer creation");
return true;
}
@@ -193,8 +180,6 @@ void GLTexture::ensure_mipmaps(int miplvl)
break;
}
}
-
- GL_CHECK_ERROR("Post-mipmap creation");
}
this->mip_range_set(0, mipmaps_);
@@ -240,7 +225,6 @@ void GLTexture::update_sub_direct_state_access(
break;
}
}
- GL_CHECK_ERROR("Post-update_sub_direct_state_access");
}
void GLTexture::update_sub(
@@ -260,8 +244,8 @@ void GLTexture::update_sub(
GLenum gl_format = to_gl_data_format(format_);
GLenum gl_type = to_gl(type);
- /* Some drivers have issues with cubemap & glTextureSubImage3D even if it correct. */
- if (GLEW_ARB_direct_state_access && (type_ != GPU_TEXTURE_CUBE)) {
+ /* Some drivers have issues with cubemap & glTextureSubImage3D even if it is correct. */
+ if (GLContext::direct_state_access_support && (type_ != GPU_TEXTURE_CUBE)) {
this->update_sub_direct_state_access(mip, offset, extent, gl_format, gl_type, data);
return;
}
@@ -304,8 +288,6 @@ void GLTexture::update_sub(
break;
}
}
-
- GL_CHECK_ERROR("Post-update_sub");
}
/** This will create the mipmap images and populate them with filtered data from base level.
@@ -324,7 +306,7 @@ void GLTexture::generate_mipmap(void)
}
/* Downsample from mip 0 using implementation. */
- if (GLEW_ARB_direct_state_access) {
+ if (GLContext::direct_state_access_support) {
glGenerateTextureMipmap(tex_id_);
}
else {
@@ -337,7 +319,7 @@ void GLTexture::clear(eGPUDataFormat data_format, const void *data)
{
BLI_assert(validate_data_format(format_, data_format));
- if (GLEW_ARB_clear_texture && !(G.debug & G_DEBUG_GPU_FORCE_WORKAROUNDS)) {
+ if (GLContext::clear_texture_support) {
int mip = 0;
GLenum gl_format = to_gl_data_format(format_);
GLenum gl_type = to_gl(data_format);
@@ -366,8 +348,7 @@ void GLTexture::copy_to(Texture *dst_)
/* TODO support array / 3D textures. */
BLI_assert(dst->d_ == 0);
- if (GLEW_ARB_copy_image && !GLContext::texture_copy_workaround) {
- /* Opengl 4.3 */
+ if (GLContext::copy_image_support) {
int mip = 0;
/* NOTE: mip_size_get() won't override any dimension that is equal to 0. */
int extent[3] = {1, 1, 1};
@@ -403,7 +384,7 @@ void *GLTexture::read(int mip, eGPUDataFormat type)
GLenum gl_format = to_gl_data_format(format_);
GLenum gl_type = to_gl(type);
- if (GLEW_ARB_direct_state_access) {
+ if (GLContext::direct_state_access_support) {
glGetTextureImage(tex_id_, mip, gl_format, gl_type, texture_size, data);
}
else {
@@ -434,7 +415,7 @@ void GLTexture::swizzle_set(const char swizzle[4])
(GLint)swizzle_to_gl(swizzle[1]),
(GLint)swizzle_to_gl(swizzle[2]),
(GLint)swizzle_to_gl(swizzle[3])};
- if (GLEW_ARB_direct_state_access) {
+ if (GLContext::direct_state_access_support) {
glTextureParameteriv(tex_id_, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle);
}
else {
@@ -448,7 +429,7 @@ void GLTexture::mip_range_set(int min, int max)
BLI_assert(min <= max && min >= 0 && max <= mipmaps_);
mip_min_ = min;
mip_max_ = max;
- if (GLEW_ARB_direct_state_access) {
+ if (GLContext::direct_state_access_support) {
glTextureParameteri(tex_id_, GL_TEXTURE_BASE_LEVEL, min);
glTextureParameteri(tex_id_, GL_TEXTURE_MAX_LEVEL, max);
}
@@ -510,22 +491,20 @@ void GLTexture::samplers_init(void)
* - GL_TEXTURE_LOD_BIAS is 0.0f.
**/
- if (GLContext::debug_layer_support) {
- char sampler_name[128];
- SNPRINTF(sampler_name,
- "Sampler%s%s%s%s%s%s%s%s%s%s",
- (state == GPU_SAMPLER_DEFAULT) ? "_default" : "",
- (state & GPU_SAMPLER_FILTER) ? "_filter" : "",
- (state & GPU_SAMPLER_MIPMAP) ? "_mipmap" : "",
- (state & GPU_SAMPLER_REPEAT) ? "_repeat-" : "",
- (state & GPU_SAMPLER_REPEAT_S) ? "S" : "",
- (state & GPU_SAMPLER_REPEAT_T) ? "T" : "",
- (state & GPU_SAMPLER_REPEAT_R) ? "R" : "",
- (state & GPU_SAMPLER_CLAMP_BORDER) ? "_clamp_border" : "",
- (state & GPU_SAMPLER_COMPARE) ? "_compare" : "",
- (state & GPU_SAMPLER_ANISO) ? "_aniso" : "");
- glObjectLabel(GL_SAMPLER, samplers_[i], -1, sampler_name);
- }
+ char sampler_name[128] = "\0\0";
+ SNPRINTF(sampler_name,
+ "%s%s%s%s%s%s%s%s%s%s",
+ (state == GPU_SAMPLER_DEFAULT) ? "_default" : "",
+ (state & GPU_SAMPLER_FILTER) ? "_filter" : "",
+ (state & GPU_SAMPLER_MIPMAP) ? "_mipmap" : "",
+ (state & GPU_SAMPLER_REPEAT) ? "_repeat-" : "",
+ (state & GPU_SAMPLER_REPEAT_S) ? "S" : "",
+ (state & GPU_SAMPLER_REPEAT_T) ? "T" : "",
+ (state & GPU_SAMPLER_REPEAT_R) ? "R" : "",
+ (state & GPU_SAMPLER_CLAMP_BORDER) ? "_clamp_border" : "",
+ (state & GPU_SAMPLER_COMPARE) ? "_compare" : "",
+ (state & GPU_SAMPLER_ANISO) ? "_aniso" : "");
+ debug::object_label(GL_SAMPLER, samplers_[i], &sampler_name[1]);
}
samplers_update();
@@ -535,14 +514,12 @@ void GLTexture::samplers_init(void)
glSamplerParameteri(icon_sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glSamplerParameterf(icon_sampler, GL_TEXTURE_LOD_BIAS, -0.5f);
- if (GLContext::debug_layer_support) {
- glObjectLabel(GL_SAMPLER, icon_sampler, -1, "Sampler-icons");
- }
+ debug::object_label(GL_SAMPLER, icon_sampler, "icons");
}
void GLTexture::samplers_update(void)
{
- if (!GLEW_EXT_texture_filter_anisotropic) {
+ if (!GLContext::texture_filter_anisotropic_support) {
return;
}
diff --git a/source/blender/gpu/opengl/gl_uniform_buffer.cc b/source/blender/gpu/opengl/gl_uniform_buffer.cc
index 74453a08bfe..dd305fca555 100644
--- a/source/blender/gpu/opengl/gl_uniform_buffer.cc
+++ b/source/blender/gpu/opengl/gl_uniform_buffer.cc
@@ -29,6 +29,7 @@
#include "gpu_context_private.hh"
#include "gl_backend.hh"
+#include "gl_debug.hh"
#include "gl_uniform_buffer.hh"
namespace blender::gpu {
@@ -62,11 +63,7 @@ void GLUniformBuf::init(void)
glBindBuffer(GL_UNIFORM_BUFFER, ubo_id_);
glBufferData(GL_UNIFORM_BUFFER, size_in_bytes_, NULL, GL_DYNAMIC_DRAW);
- if (GLContext::debug_layer_support) {
- char sh_name[64];
- SNPRINTF(sh_name, "UBO-%s", name_);
- glObjectLabel(GL_BUFFER, ubo_id_, -1, sh_name);
- }
+ debug::object_label(GL_UNIFORM_BUFFER, ubo_id_, name_);
}
void GLUniformBuf::update(const void *data)
diff --git a/source/blender/gpu/opengl/gl_vertex_array.cc b/source/blender/gpu/opengl/gl_vertex_array.cc
index 732221cfab3..14a7b4deb7d 100644
--- a/source/blender/gpu/opengl/gl_vertex_array.cc
+++ b/source/blender/gpu/opengl/gl_vertex_array.cc
@@ -135,7 +135,7 @@ void GLVertArray::update_bindings(const GLuint vao,
}
}
- if (attr_mask != 0 && GLEW_ARB_vertex_attrib_binding) {
+ if (attr_mask != 0 && GLContext::vertex_attrib_binding_support) {
for (uint16_t mask = 1, a = 0; a < 16; a++, mask <<= 1) {
if (attr_mask & mask) {
GLContext *ctx = GLContext::get();