diff options
Diffstat (limited to 'source/blender/gpu/opengl')
-rw-r--r-- | source/blender/gpu/opengl/gl_backend.cc | 62 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_batch.cc | 5 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_context.cc | 6 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_context.hh | 12 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_debug.cc | 75 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_debug.hh | 103 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_debug_layer.cc | 165 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_drawlist.cc | 5 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_framebuffer.cc | 21 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_immediate.cc | 14 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_shader.cc | 49 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_state.cc | 10 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_state.hh | 4 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_texture.cc | 79 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_uniform_buffer.cc | 7 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_vertex_array.cc | 2 |
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(); |