summaryrefslogtreecommitdiff
path: root/gfx/gl
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2026-01-16 02:53:57 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2026-01-16 03:18:29 +0000
commit09533ab9379a675a89638132fb6831b420ebb8f4 (patch)
tree984985821bcad18e0d8d93831150407e0d5b1a8e /gfx/gl
parentTidy thirdparty jam, use -isystem for thirdparty includes (diff)
downloadilt-09533ab9379a675a89638132fb6831b420ebb8f4.tar.bz2
ilt-09533ab9379a675a89638132fb6831b420ebb8f4.tar.xz
ilt-09533ab9379a675a89638132fb6831b420ebb8f4.zip
Add glDebugScope
Wrapper for glPushDebugGroup/glPopDebugGroup which allows neatly grouping OpenGL calls in diagnostic tools.
Diffstat (limited to 'gfx/gl')
-rw-r--r--gfx/gl/gldebug.cpp20
-rw-r--r--gfx/gl/gldebug.h52
-rw-r--r--gfx/gl/program.cpp3
-rw-r--r--gfx/gl/program.h5
-rw-r--r--gfx/gl/sceneRenderer.cpp99
-rw-r--r--gfx/gl/sceneRenderer.h4
-rw-r--r--gfx/gl/shadowMapper.cpp3
-rw-r--r--gfx/gl/shadowStenciller.cpp4
8 files changed, 144 insertions, 46 deletions
diff --git a/gfx/gl/gldebug.cpp b/gfx/gl/gldebug.cpp
new file mode 100644
index 0000000..518d4fb
--- /dev/null
+++ b/gfx/gl/gldebug.cpp
@@ -0,0 +1,20 @@
+#if GLDEBUG == 2
+// Level 2 is out of line because its "complex"
+
+# include "gldebug.h"
+# include <format>
+
+glDebugScope::glDebugScope(GLuint id, const std::source_location & location)
+{
+ const auto fullMsg = std::format("{} ({}:{})", location.function_name(), location.file_name(), location.line());
+ glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, id, static_cast<GLsizei>(fullMsg.length()), fullMsg.c_str());
+}
+
+glDebugScope::glDebugScope(GLuint id, const std::string_view msg, const std::source_location & location)
+{
+ const auto fullMsg
+ = std::format("{} @ {} ({}:{})", msg, location.function_name(), location.file_name(), location.line());
+ glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, id, static_cast<GLsizei>(fullMsg.length()), fullMsg.c_str());
+}
+
+#endif
diff --git a/gfx/gl/gldebug.h b/gfx/gl/gldebug.h
new file mode 100644
index 0000000..5cfd099
--- /dev/null
+++ b/gfx/gl/gldebug.h
@@ -0,0 +1,52 @@
+#pragma once
+#ifndef GLDEBUG
+# define GLDEBUG 0
+#endif
+
+#include "special_members.h"
+#include <glad/gl.h>
+#include <source_location>
+#include <string_view>
+
+class [[nodiscard]] glDebugScope {
+public:
+ explicit glDebugScope(GLuint id, const std::source_location & = std::source_location::current());
+ explicit glDebugScope(
+ GLuint id, std::string_view msg, const std::source_location & = std::source_location::current());
+
+ ~glDebugScope();
+
+ constexpr
+ operator bool() const
+ {
+ return true;
+ }
+
+ NO_MOVE(glDebugScope);
+ NO_COPY(glDebugScope);
+};
+
+#if GLDEBUG > 0
+inline glDebugScope::~glDebugScope()
+{
+ glPopDebugGroup();
+}
+# if GLDEBUG == 1
+// Level 1 is inlined for performance because they're thin wrappers
+inline glDebugScope::glDebugScope(GLuint id, const std::source_location & location) :
+ glDebugScope {id, location.function_name()}
+{
+}
+
+inline glDebugScope::glDebugScope(GLuint id, const std::string_view msg, const std::source_location &)
+{
+ glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, id, static_cast<GLsizei>(msg.length()), msg.data());
+}
+# endif
+#else
+inline glDebugScope::glDebugScope(GLuint, const std::source_location &) { }
+
+inline glDebugScope::glDebugScope(GLuint, const std::string_view, const std::source_location &) { }
+
+inline glDebugScope::~glDebugScope() = default;
+#endif
diff --git a/gfx/gl/program.cpp b/gfx/gl/program.cpp
index fdd4c6f..da85456 100644
--- a/gfx/gl/program.cpp
+++ b/gfx/gl/program.cpp
@@ -1,5 +1,5 @@
#include "program.h"
-#include "shader.h"
+#include "gldebug.h"
#include <format>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/transform.hpp>
@@ -9,6 +9,7 @@
void
Program::linkAndValidate() const
{
+ glDebugScope _ {m_program};
glLinkProgram(m_program);
checkProgramError(m_program, GL_LINK_STATUS, "Error linking shader program");
diff --git a/gfx/gl/program.h b/gfx/gl/program.h
index 20be1aa..2b06d2d 100644
--- a/gfx/gl/program.h
+++ b/gfx/gl/program.h
@@ -1,5 +1,6 @@
#pragma once
+#include "gldebug.h"
#include "shader.h" // IWYU pragma: export
#include <glRef.h>
#include <glad/gl.h>
@@ -14,7 +15,9 @@ class Program {
public:
Program() = delete;
- template<typename... S> explicit Program(const S &... srcs)
+ template<typename... S> explicit Program(const S &... srcs) : Program {glDebugScope {0}, srcs...} { }
+
+ template<typename... S> explicit Program(glDebugScope, const S &... srcs)
{
(glAttachShader(m_program, srcs.compile()), ...);
linkAndValidate();
diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp
index 9a4d153..65b4609 100644
--- a/gfx/gl/sceneRenderer.cpp
+++ b/gfx/gl/sceneRenderer.cpp
@@ -14,7 +14,9 @@ static constexpr const std::array<const glm::i8vec4, 4> displayVAOdata {{
{1, -1, 1, 0},
}};
-SceneRenderer::SceneRenderer(ScreenAbsCoord s, GLuint o) :
+SceneRenderer::SceneRenderer(ScreenAbsCoord s, GLuint o) : SceneRenderer {s, o, glDebugScope {o}} { }
+
+SceneRenderer::SceneRenderer(ScreenAbsCoord s, GLuint o, glDebugScope) :
camera {{-1250000, -1250000, 35.0F}, quarter_pi, ratio(s), 100, 10000000}, size {s}, output {o},
lighting {lighting_vs, lighting_fs}, shadowMapper {{2048, 2048}}
{
@@ -59,6 +61,7 @@ SceneRenderer::SceneRenderer(ScreenAbsCoord s, GLuint o) :
void
SceneRenderer::resize(ScreenAbsCoord newSize)
{
+ glDebugScope _ {output};
size = newSize;
camera.setAspect(ratio(size));
const auto configuregdata = [this](const GLuint data, const GLint iformat, const GLenum format) {
@@ -77,55 +80,66 @@ SceneRenderer::resize(ScreenAbsCoord newSize)
void
SceneRenderer::render(const SceneProvider & scene) const
{
+ glDebugScope _ {output};
shader.setViewProjection(camera.getPosition(), camera.getViewProjection());
glViewport(0, 0, size.x, size.y);
- // Geometry/colour pass - writes albedo, normal and position textures
- glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
- glEnable(GL_BLEND);
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_DEPTH_TEST);
- glClearColor(0, 0, 0, 1);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- scene.content(shader, camera);
-
- // Environment pass -
- // * ambient - clears illumination texture - see setAmbientLight
- // * directional - updates shadowMapper, reads normal and position, writes illumination - see setDirectionalLight
- scene.environment(shader, *this);
-
- // Scene lights pass -
- // * per light - reads normal and position, writes illumination
- glBindFramebuffer(GL_FRAMEBUFFER, gBufferIll);
- glBlendFunc(GL_ONE, GL_ONE);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, gPosition);
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, gNormal);
- glActiveTexture(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_2D_ARRAY, shadowMapper);
- glDisable(GL_DEPTH_TEST);
- scene.lights(shader);
-
- // Composition pass - reads albedo and illumination, writes output
- glBindFramebuffer(GL_FRAMEBUFFER, output);
- glViewport(0, 0, size.x, size.y);
- glCullFace(GL_BACK);
- glDisable(GL_BLEND);
- glDisable(GL_DEPTH_TEST);
- glActiveTexture(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_2D, gAlbedoSpec);
- glActiveTexture(GL_TEXTURE3);
- glBindTexture(GL_TEXTURE_2D, gIllumination);
- lighting.use();
- renderQuad();
+ if (glDebugScope _ {gBuffer, "Geometry/colour pass"}) {
+ // Geometry/colour pass - writes albedo, normal and position textures
+ glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
+ glEnable(GL_BLEND);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_DEPTH_TEST);
+ glClearColor(0, 0, 0, 1);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ scene.content(shader, camera);
+ }
+
+ if (glDebugScope _ {gBufferIll, "Environment pass"}) {
+ // Environment pass -
+ // * ambient - clears illumination texture - see setAmbientLight
+ // * directional - updates shadowMapper, reads normal and position, writes illumination - see
+ // setDirectionalLight
+ scene.environment(shader, *this);
+ }
+
+ if (glDebugScope _ {gBufferIll, "Scene lighting pass"}) {
+ // Scene lights pass -
+ // * per light - reads normal and position, writes illumination
+ glBindFramebuffer(GL_FRAMEBUFFER, gBufferIll);
+ glBlendFunc(GL_ONE, GL_ONE);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, gPosition);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, gNormal);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, shadowMapper);
+ glDisable(GL_DEPTH_TEST);
+ scene.lights(shader);
+ }
+
+ if (glDebugScope _ {output, "Composition pass"}) {
+ // Composition pass - reads albedo and illumination, writes output
+ glBindFramebuffer(GL_FRAMEBUFFER, output);
+ glViewport(0, 0, size.x, size.y);
+ glCullFace(GL_BACK);
+ glDisable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, gAlbedoSpec);
+ glActiveTexture(GL_TEXTURE3);
+ glBindTexture(GL_TEXTURE_2D, gIllumination);
+ lighting.use();
+ renderQuad();
+ }
}
void
SceneRenderer::setAmbientLight(const RGB & colour) const
{
+ glDebugScope _ {output};
glBindFramebuffer(GL_FRAMEBUFFER, gBufferIll);
glClearColor(colour.r, colour.g, colour.b, 1.0F);
glClear(GL_COLOR_BUFFER_BIT);
@@ -136,6 +150,7 @@ SceneRenderer::setDirectionalLight(
const RGB & colour, const LightDirection & direction, const SceneProvider & scene) const
{
if (colour.r > 0 || colour.g > 0 || colour.b > 0) {
+ glDebugScope _ {output};
const auto lvp = shadowMapper.update(scene, direction, camera);
glBindFramebuffer(GL_FRAMEBUFFER, gBufferIll);
glBlendFunc(GL_ONE, GL_ONE);
diff --git a/gfx/gl/sceneRenderer.h b/gfx/gl/sceneRenderer.h
index 31f0cda..05921a1 100644
--- a/gfx/gl/sceneRenderer.h
+++ b/gfx/gl/sceneRenderer.h
@@ -2,6 +2,7 @@
#include "gfx/lightDirection.h"
#include "glArrays.h"
+#include "gldebug.h"
#include "program.h"
#include "sceneProvider.h"
#include "sceneShader.h"
@@ -11,7 +12,8 @@
class SceneRenderer {
public:
- explicit SceneRenderer(ScreenAbsCoord size, GLuint output);
+ SceneRenderer(ScreenAbsCoord size, GLuint output);
+ SceneRenderer(ScreenAbsCoord size, GLuint output, glDebugScope);
void resize(ScreenAbsCoord size);
diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp
index 3cb73f7..486ba1c 100644
--- a/gfx/gl/shadowMapper.cpp
+++ b/gfx/gl/shadowMapper.cpp
@@ -16,6 +16,7 @@
#include "gfx/lightDirection.h"
#include "gfx/renderable.h"
#include "gl_traits.h"
+#include "gldebug.h"
#include "location.h"
#include "maths.h"
#include "sceneProvider.h"
@@ -32,6 +33,7 @@ ShadowMapper::ShadowMapper(const TextureAbsCoord & s) :
shadowDynamicPointInstWithTextures_fs},
size {s}
{
+ glDebugScope _ {depthMap};
glBindTexture(GL_TEXTURE_2D_ARRAY, depthMap);
glTexImage3D(
GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT, size.x, size.y, 4, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
@@ -83,6 +85,7 @@ ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightV
ShadowMapper::Definitions
ShadowMapper::update(const SceneProvider & scene, const LightDirection & dir, const Camera & camera) const
{
+ glDebugScope _ {depthMap};
glCullFace(GL_FRONT);
glEnable(GL_DEPTH_TEST);
diff --git a/gfx/gl/shadowStenciller.cpp b/gfx/gl/shadowStenciller.cpp
index 86b77e4..a6124f5 100644
--- a/gfx/gl/shadowStenciller.cpp
+++ b/gfx/gl/shadowStenciller.cpp
@@ -1,5 +1,4 @@
#include "shadowStenciller.h"
-#include "gfx/gl/program.h"
#include "gfx/gl/shaders/fs-shadowStencil.h"
#include "gfx/gl/shaders/gs-shadowStencil.h"
#include "gfx/gl/shaders/vs-shadowStencil.h"
@@ -7,12 +6,14 @@
#include "gfx/models/mesh.h"
#include "glArrays.h"
#include "gl_traits.h"
+#include "gldebug.h"
#include "maths.h"
#include <stdexcept>
ShadowStenciller::ShadowStenciller() :
shadowCaster {shadowStencil_vs, shadowStencil_gs, shadowStencil_fs}, viewProjections {}
{
+ glDebugScope _ {fbo};
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
@@ -50,6 +51,7 @@ ShadowStenciller::createStencilTexture(GLsizei width, GLsizei height)
void
ShadowStenciller::renderStencil(const glTexture & stencil, const MeshBase & mesh, const Texture::AnyPtr texture) const
{
+ glDebugScope _ {fbo};
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, stencil, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {