diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg index d7d3823afc..acbfe95031 100644 --- a/binaries/data/config/default.cfg +++ b/binaries/data/config/default.cfg @@ -118,6 +118,11 @@ cursorbackend = "sdl" ; gl - GL with GLSL shaders, should be used by default. rendererbackend = "gl" +; Enables additional debug information in renderer backend. +renderer.backend.debugmessages = "false" +renderer.backend.debuglabels = "false" +renderer.backend.debugscopedlabels = "false" + ; Should not be edited. It's used only for preventing of running fixed pipeline. renderpath = default diff --git a/source/graphics/LOSTexture.cpp b/source/graphics/LOSTexture.cpp index c1bcd89987..1c0c8a7ffb 100644 --- a/source/graphics/LOSTexture.cpp +++ b/source/graphics/LOSTexture.cpp @@ -138,6 +138,7 @@ void CLOSTexture::InterpolateLOS(Renderer::Backend::GL::CDeviceCommandContext* d if (skipSmoothLOS) return; + GPU_SCOPED_LABEL(deviceCommandContext, "Render LOS texture"); deviceCommandContext->SetFramebuffer(m_SmoothFramebuffers[m_WhichTexture].get()); m_SmoothTech->BeginPass(); diff --git a/source/graphics/MiniMapTexture.cpp b/source/graphics/MiniMapTexture.cpp index 48d627a6d6..9a41deffbc 100644 --- a/source/graphics/MiniMapTexture.cpp +++ b/source/graphics/MiniMapTexture.cpp @@ -331,6 +331,7 @@ void CMiniMapTexture::RenderFinalTexture( return; m_FinalTextureDirty = false; + GPU_SCOPED_LABEL(deviceCommandContext, "Render minimap texture"); deviceCommandContext->SetFramebuffer(m_FinalTextureFramebuffer.get()); const SViewPort oldViewPort = g_Renderer.GetViewport(); diff --git a/source/lib/ogl.cpp b/source/lib/ogl.cpp index af9e79a5b8..7a8a5fa193 100644 --- a/source/lib/ogl.cpp +++ b/source/lib/ogl.cpp @@ -59,9 +59,6 @@ static bool have_15 = false; static bool have_14 = false; static bool have_13 = false; static bool have_12 = false; -#if KHR_DEBUG_ENABLED -static bool have_KHR = false; -#endif // return a C string of unspecified length containing a space-separated @@ -375,87 +372,6 @@ void ogl_WarnIfErrorLoc(const char *file, int line) debug_printf("%s:%d: OpenGL error(s) occurred: %s (%04x)\n", file, line, ogl_GetErrorName(first_error), (unsigned int)first_error); } -#if KHR_DEBUG_ENABLED -void GLAD_API_PTR ogl_OnDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei UNUSED(length), const GLchar* message, const void* UNUSED(user_param)) -{ - std::string debugSource = "unknown"; - std::string debugType = "unknown"; - std::string debugSeverity = "unknown"; - - switch (source) - { - case GL_DEBUG_SOURCE_API: - debugSource = "the API"; - break; - case GL_DEBUG_SOURCE_WINDOW_SYSTEM: - debugSource = "the window system"; - break; - case GL_DEBUG_SOURCE_SHADER_COMPILER: - debugSource = "the shader compiler"; - break; - case GL_DEBUG_SOURCE_THIRD_PARTY: - debugSource = "a third party"; - break; - case GL_DEBUG_SOURCE_APPLICATION: - debugSource = "the application"; - break; - case GL_DEBUG_SOURCE_OTHER: - debugSource = "somewhere"; - break; - } - - switch (type) - { - case GL_DEBUG_TYPE_ERROR: - debugType = "error"; - break; - case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: - debugType = "deprecated behaviour"; - break; - case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: - debugType = "undefined behaviour"; - break; - case GL_DEBUG_TYPE_PORTABILITY: - debugType = "portability"; - break; - case GL_DEBUG_TYPE_PERFORMANCE: - debugType = "performance"; - break; - case GL_DEBUG_TYPE_OTHER: - debugType = "other"; - break; - case GL_DEBUG_TYPE_MARKER: - debugType = "marker"; - break; - case GL_DEBUG_TYPE_PUSH_GROUP: - debugType = "push group"; - break; - case GL_DEBUG_TYPE_POP_GROUP: - debugType = "pop group"; - break; - } - - switch (severity) - { - case GL_DEBUG_SEVERITY_HIGH: - debugSeverity = "high"; - break; - case GL_DEBUG_SEVERITY_MEDIUM: - debugSeverity = "medium"; - break; - case GL_DEBUG_SEVERITY_LOW: - debugSeverity = "low"; - break; - case GL_DEBUG_SEVERITY_NOTIFICATION: - debugSeverity = "notification"; - break; - } - - debug_printf("OpenGL | %s: %s source: %s id %u: %s\n", debugSeverity.c_str(), debugType.c_str(), debugSource.c_str(), id, message); -} -#endif - - // ignore and reset the specified error (as returned by glGetError). // any other errors that have occurred are reported as ogl_WarnIfError would. // @@ -575,25 +491,6 @@ bool ogl_Init(void* (load)(const char*)) glEnable(GL_TEXTURE_2D); -#if KHR_DEBUG_ENABLED -#if CONFIG2_GLES - bool is_core = ogl_HaveVersion(3, 2); -#else - bool is_core = ogl_HaveVersion(4, 3); -#endif - have_KHR = is_core || ogl_HaveExtension("GL_KHR_debug"); - if (have_KHR) - { - glEnable(GL_DEBUG_OUTPUT); - glDebugMessageCallback(ogl_OnDebugMessage, nullptr); - - // Filter out our own debug group messages - GLuint id = 0x0ad; - glDebugMessageControl(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PUSH_GROUP, GL_DONT_CARE, 1, &id, GL_FALSE); - glDebugMessageControl(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_POP_GROUP, GL_DONT_CARE, 1, &id, GL_FALSE); - } -#endif - return true; } @@ -612,21 +509,3 @@ void ogl_SetVsyncEnabled(bool enabled) UNUSED2(enabled); #endif } - -#if KHR_DEBUG_ENABLED -ogl_DebugScopedGroup::ogl_DebugScopedGroup(const char* message) -{ - if (!have_KHR) - return; - - glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0x0ad, -1, message); -} - -ogl_DebugScopedGroup::~ogl_DebugScopedGroup() -{ - if (!have_KHR) - return; - - glPopDebugGroup(); -} -#endif diff --git a/source/lib/ogl.h b/source/lib/ogl.h index 641a2b9499..2eba413ceb 100644 --- a/source/lib/ogl.h +++ b/source/lib/ogl.h @@ -150,21 +150,4 @@ extern bool ogl_SquelchError(GLenum err_to_ignore); extern GLint ogl_max_tex_size; /// [pixels] extern GLint ogl_max_tex_units; /// limit on GL_TEXTUREn - -#ifdef NDEBUG -# define KHR_DEBUG_ENABLED 0 -# define OGL_SCOPED_DEBUG_GROUP(groupName) -#else -# define KHR_DEBUG_ENABLED 1 -# define OGL_SCOPED_DEBUG_GROUP(groupName) ogl_DebugScopedGroup glDebugScopedGroup(groupName) -/** - * RAII for glPushDebugGroup() and glPopDebugGroup(). - */ -struct ogl_DebugScopedGroup -{ - ogl_DebugScopedGroup(const char* message); - ~ogl_DebugScopedGroup(); -}; -#endif - -#endif // #ifndef INCLUDED_OGL +#endif // INCLUDED_OGL diff --git a/source/ps/CLogger.cpp b/source/ps/CLogger.cpp index 51a6c0953c..258252ea6a 100644 --- a/source/ps/CLogger.cpp +++ b/source/ps/CLogger.cpp @@ -206,7 +206,6 @@ void CLogger::WriteWarning(const char* message) void CLogger::Render() { PROFILE3_GPU("logger"); - OGL_SCOPED_DEBUG_GROUP("Draw CLogger messages"); CleanupRenderQueue(); diff --git a/source/renderer/OverlayRenderer.cpp b/source/renderer/OverlayRenderer.cpp index 6dcdbeec59..d2c3901590 100644 --- a/source/renderer/OverlayRenderer.cpp +++ b/source/renderer/OverlayRenderer.cpp @@ -393,6 +393,7 @@ void OverlayRenderer::RenderOverlaysAfterWater( Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext) { PROFILE3_GPU("overlays (after)"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render overlays after water"); RenderTexturedOverlayLines(deviceCommandContext); RenderQuadOverlays(deviceCommandContext); diff --git a/source/renderer/PostprocManager.cpp b/source/renderer/PostprocManager.cpp index 80aad593a8..fc36a559ed 100644 --- a/source/renderer/PostprocManager.cpp +++ b/source/renderer/PostprocManager.cpp @@ -361,6 +361,8 @@ void CPostprocManager::ReleaseRenderOutput( { ENSURE(m_IsInitialized); + GPU_SCOPED_LABEL(deviceCommandContext, "Copy postproc to backbuffer"); + // We blit to the backbuffer from the previous active buffer. deviceCommandContext->BlitFramebuffer( deviceCommandContext->GetDevice()->GetCurrentBackbuffer(), @@ -452,6 +454,8 @@ void CPostprocManager::ApplyPostproc( if (!hasEffects && !hasAA && !hasSharp) return; + GPU_SCOPED_LABEL(deviceCommandContext, "Render postproc"); + if (hasEffects) { // First render blur textures. Note that this only happens ONLY ONCE, before any effects are applied! @@ -643,6 +647,7 @@ void CPostprocManager::ResolveMultisampleFramebuffer( if (!m_UsingMultisampleBuffer) return; + GPU_SCOPED_LABEL(deviceCommandContext, "Resolve postproc multisample"); deviceCommandContext->BlitFramebuffer( m_PingFramebuffer.get(), m_MultisampleFramebuffer.get()); deviceCommandContext->SetFramebuffer(m_PingFramebuffer.get()); diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index 11fa00c2c7..72704d27d1 100644 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -483,7 +483,7 @@ void CRenderer::RenderFrameImpl(const bool renderGUI, const bool renderLogger) if (renderGUI) { - OGL_SCOPED_DEBUG_GROUP("Draw GUI"); + GPU_SCOPED_LABEL(m->deviceCommandContext.get(), "Render GUI"); // All GUI elements are drawn in Z order to render semi-transparent // objects correctly. g_GUI->Draw(); diff --git a/source/renderer/SceneRenderer.cpp b/source/renderer/SceneRenderer.cpp index d389055717..cc32377b7c 100644 --- a/source/renderer/SceneRenderer.cpp +++ b/source/renderer/SceneRenderer.cpp @@ -294,7 +294,7 @@ void CSceneRenderer::RenderShadowMap( const CShaderDefines& context) { PROFILE3_GPU("shadow map"); - OGL_SCOPED_DEBUG_GROUP("Render shadow map"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render shadow map"); CShaderDefines shadowsContext = context; shadowsContext.Add(str_PASS_SHADOWS, str_1); @@ -337,7 +337,7 @@ void CSceneRenderer::RenderPatches( const CShaderDefines& context, int cullGroup) { PROFILE3_GPU("patches"); - OGL_SCOPED_DEBUG_GROUP("Render patches"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render patches"); #if CONFIG2_GLES #warning TODO: implement wireface/edged rendering mode GLES @@ -388,7 +388,7 @@ void CSceneRenderer::RenderModels( const CShaderDefines& context, int cullGroup) { PROFILE3_GPU("models"); - OGL_SCOPED_DEBUG_GROUP("Render models"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render models"); int flags = 0; @@ -425,7 +425,7 @@ void CSceneRenderer::RenderTransparentModels( const CShaderDefines& context, int cullGroup, ETransparentMode transparentMode) { PROFILE3_GPU("transparent models"); - OGL_SCOPED_DEBUG_GROUP("Render transparent models"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render transparent models"); int flags = 0; @@ -593,7 +593,7 @@ void CSceneRenderer::RenderReflections( const CShaderDefines& context, const CBoundingBoxAligned& scissor) { PROFILE3_GPU("water reflections"); - OGL_SCOPED_DEBUG_GROUP("Render water reflections"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render water reflections"); WaterManager& wm = m->waterManager; @@ -670,7 +670,7 @@ void CSceneRenderer::RenderRefractions( const CShaderDefines& context, const CBoundingBoxAligned &scissor) { PROFILE3_GPU("water refractions"); - OGL_SCOPED_DEBUG_GROUP("Render water refractions"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render water refractions"); WaterManager& wm = m->waterManager; @@ -733,7 +733,7 @@ void CSceneRenderer::RenderSilhouettes( const CShaderDefines& context) { PROFILE3_GPU("silhouettes"); - OGL_SCOPED_DEBUG_GROUP("Render water silhouettes"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render silhouettes"); CShaderDefines contextOccluder = context; contextOccluder.Add(str_MODE_SILHOUETTEOCCLUDER, str_1); @@ -785,7 +785,7 @@ void CSceneRenderer::RenderParticles( int cullGroup) { PROFILE3_GPU("particles"); - OGL_SCOPED_DEBUG_GROUP("Render particles"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render particles"); m->particleRenderer.RenderParticles( deviceCommandContext, cullGroup); @@ -810,7 +810,7 @@ void CSceneRenderer::RenderSubmissions( const CBoundingBoxAligned& waterScissor) { PROFILE3("render submissions"); - OGL_SCOPED_DEBUG_GROUP("Render submissions"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render submissions"); m->skyManager.LoadAndUploadSkyTexturesIfNeeded(deviceCommandContext); diff --git a/source/renderer/SkyManager.cpp b/source/renderer/SkyManager.cpp index 80b10a4e60..ef3b3e19b5 100644 --- a/source/renderer/SkyManager.cpp +++ b/source/renderer/SkyManager.cpp @@ -54,7 +54,7 @@ void SkyManager::LoadAndUploadSkyTexturesIfNeeded( if (m_SkyCubeMap) return; - OGL_SCOPED_DEBUG_GROUP("Load Sky Textures"); + GPU_SCOPED_LABEL(deviceCommandContext, "Load Sky Textures"); static const CStrW images[NUMBER_OF_TEXTURES + 1] = { L"front", L"back", @@ -193,7 +193,7 @@ std::vector SkyManager::GetSkySets() const void SkyManager::RenderSky( Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext) { - OGL_SCOPED_DEBUG_GROUP("Render Sky"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render sky"); #if CONFIG2_GLES UNUSED2(deviceCommandContext); #warning TODO: implement SkyManager::RenderSky for GLES diff --git a/source/renderer/TerrainRenderer.cpp b/source/renderer/TerrainRenderer.cpp index 3cbc1473ad..8090a4db00 100644 --- a/source/renderer/TerrainRenderer.cpp +++ b/source/renderer/TerrainRenderer.cpp @@ -363,7 +363,7 @@ bool TerrainRenderer::RenderFancyWater( const CShaderDefines& context, int cullGroup, ShadowMap* shadow) { PROFILE3_GPU("fancy water"); - OGL_SCOPED_DEBUG_GROUP("Render Fancy Water"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render fancy water"); CSceneRenderer& sceneRenderer = g_Renderer.GetSceneRenderer(); @@ -522,7 +522,7 @@ void TerrainRenderer::RenderSimpleWater( UNUSED2(cullGroup); #else PROFILE3_GPU("simple water"); - OGL_SCOPED_DEBUG_GROUP("Render Simple Water"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render Simple Water"); const WaterManager& waterManager = g_Renderer.GetSceneRenderer().GetWaterManager(); CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture(); @@ -587,6 +587,8 @@ void TerrainRenderer::RenderWaterFoamOccluders( if (!waterManager.WillRenderFancyWater()) return; + GPU_SCOPED_LABEL(deviceCommandContext, "Render water foam occluders"); + // Render normals and foam to a framebuffer if we're using fancy effects. deviceCommandContext->SetFramebuffer(waterManager.m_FancyEffectsFramebuffer.get()); diff --git a/source/renderer/WaterManager.cpp b/source/renderer/WaterManager.cpp index 551dcab00f..ce08025d2a 100644 --- a/source/renderer/WaterManager.cpp +++ b/source/renderer/WaterManager.cpp @@ -377,8 +377,6 @@ void WaterManager::RecomputeDistanceHeightmap() // This requires m_DistanceHeightmap to be defined properly. void WaterManager::CreateWaveMeshes() { - OGL_SCOPED_DEBUG_GROUP("Create Wave Meshes"); - if (m_MapSize == 0) return; @@ -766,9 +764,8 @@ void WaterManager::RenderWaves( Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, const CFrustum& frustrum) { - OGL_SCOPED_DEBUG_GROUP("Render Waves"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render Waves"); #if CONFIG2_GLES - UNUSED2(deviceCommandContext); UNUSED2(frustrum); #warning Fix WaterManager::RenderWaves on GLES #else diff --git a/source/renderer/backend/gl/Buffer.cpp b/source/renderer/backend/gl/Buffer.cpp index a3dbaf378a..55bde24f2b 100644 --- a/source/renderer/backend/gl/Buffer.cpp +++ b/source/renderer/backend/gl/Buffer.cpp @@ -49,8 +49,11 @@ std::unique_ptr CBuffer::Create( const GLenum target = type == Type::INDEX ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER; glBindBufferARB(target, buffer->m_Handle); glBufferDataARB(target, size, nullptr, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); -#if KHR_DEBUG_ENABLED && !CONFIG2_GLES - glObjectLabel(GL_BUFFER, buffer->m_Handle, -1, name); +#if !CONFIG2_GLES + if (buffer->m_Device->GetCapabilities().debugLabels) + { + glObjectLabel(GL_BUFFER, buffer->m_Handle, -1, name); + } #else UNUSED2(name); #endif diff --git a/source/renderer/backend/gl/Device.cpp b/source/renderer/backend/gl/Device.cpp index d88d196e51..07fc33e155 100644 --- a/source/renderer/backend/gl/Device.cpp +++ b/source/renderer/backend/gl/Device.cpp @@ -126,6 +126,95 @@ std::vector GetExtensionsImpl() return extensions; } +void GLAD_API_PTR OnDebugMessage( + GLenum source, GLenum type, GLuint id, GLenum severity, + GLsizei UNUSED(length), const GLchar* message, const void* UNUSED(user_param)) +{ + std::string debugSource = "unknown"; + std::string debugType = "unknown"; + std::string debugSeverity = "unknown"; + + switch (source) + { + case GL_DEBUG_SOURCE_API: + debugSource = "the API"; + break; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: + debugSource = "the window system"; + break; + case GL_DEBUG_SOURCE_SHADER_COMPILER: + debugSource = "the shader compiler"; + break; + case GL_DEBUG_SOURCE_THIRD_PARTY: + debugSource = "a third party"; + break; + case GL_DEBUG_SOURCE_APPLICATION: + debugSource = "the application"; + break; + case GL_DEBUG_SOURCE_OTHER: + debugSource = "somewhere"; + break; + } + + switch (type) + { + case GL_DEBUG_TYPE_ERROR: + debugType = "error"; + break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: + debugType = "deprecated behaviour"; + break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: + debugType = "undefined behaviour"; + break; + case GL_DEBUG_TYPE_PORTABILITY: + debugType = "portability"; + break; + case GL_DEBUG_TYPE_PERFORMANCE: + debugType = "performance"; + break; + case GL_DEBUG_TYPE_OTHER: + debugType = "other"; + break; + case GL_DEBUG_TYPE_MARKER: + debugType = "marker"; + break; + case GL_DEBUG_TYPE_PUSH_GROUP: + debugType = "push group"; + break; + case GL_DEBUG_TYPE_POP_GROUP: + debugType = "pop group"; + break; + } + + switch (severity) + { + case GL_DEBUG_SEVERITY_HIGH: + debugSeverity = "high"; + break; + case GL_DEBUG_SEVERITY_MEDIUM: + debugSeverity = "medium"; + break; + case GL_DEBUG_SEVERITY_LOW: + debugSeverity = "low"; + break; + case GL_DEBUG_SEVERITY_NOTIFICATION: + debugSeverity = "notification"; + break; + } + + if (severity == GL_DEBUG_SEVERITY_NOTIFICATION) + { + debug_printf( + "OpenGL | %s: %s source: %s id %u: %s\n", debugSeverity.c_str(), debugType.c_str(), debugSource.c_str(), id, message); + } + else + { + LOGWARNING( + "OpenGL | %s: %s source: %s id %u: %s\n", debugSeverity.c_str(), debugType.c_str(), debugSource.c_str(), id, message); + } +} + } // anonymous namespace // static @@ -236,6 +325,41 @@ std::unique_ptr CDevice::Create(SDL_Window* window, const bool arb) capabilities.maxAnisotropy = maxAnisotropy; } +#if CONFIG2_GLES + const bool isDebugInCore = ogl_HaveVersion(3, 2); +#else + const bool isDebugInCore = ogl_HaveVersion(4, 3); +#endif + const bool hasDebug = isDebugInCore || ogl_HaveExtension("GL_KHR_debug"); + if (hasDebug) + { +#ifdef NDEBUG + bool enableDebugMessages = false; + CFG_GET_VAL("renderer.backend.debugmessages", enableDebugMessages); + capabilities.debugLabels = false; + CFG_GET_VAL("renderer.backend.debuglabels", capabilities.debugLabels); + capabilities.debugScopedLabels = false; + CFG_GET_VAL("renderer.backend.debugscopedlabels", capabilities.debugScopedLabels); +#else + const bool enableDebugMessages = true; + capabilities.debugLabels = true; + capabilities.debugScopedLabels = true; +#endif + if (enableDebugMessages) + { + glEnable(GL_DEBUG_OUTPUT); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + glDebugMessageCallback(OnDebugMessage, nullptr); + + // Filter out our own debug group messages + const GLuint id = 0x0AD; + glDebugMessageControl( + GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PUSH_GROUP, GL_DONT_CARE, 1, &id, GL_FALSE); + glDebugMessageControl( + GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_POP_GROUP, GL_DONT_CARE, 1, &id, GL_FALSE); + } + } + return device; } diff --git a/source/renderer/backend/gl/Device.h b/source/renderer/backend/gl/Device.h index 4d294b1687..355462ac75 100644 --- a/source/renderer/backend/gl/Device.h +++ b/source/renderer/backend/gl/Device.h @@ -50,6 +50,8 @@ public: bool S3TC; bool ARBShaders; bool ARBShadersShadow; + bool debugLabels; + bool debugScopedLabels; bool multisampling; bool anisotropicFiltering; uint32_t maxSampleCount; diff --git a/source/renderer/backend/gl/DeviceCommandContext.cpp b/source/renderer/backend/gl/DeviceCommandContext.cpp index 3ea5f7f352..600113d310 100644 --- a/source/renderer/backend/gl/DeviceCommandContext.cpp +++ b/source/renderer/backend/gl/DeviceCommandContext.cpp @@ -336,6 +336,25 @@ void CDeviceCommandContext::UploadBufferRegion( glBindBufferARB(target, 0); } +void CDeviceCommandContext::BeginScopedLabel(const char* name) +{ + if (!m_Device->GetCapabilities().debugScopedLabels) + return; + + ++m_ScopedLabelDepth; + glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0x0AD, -1, name); +} + +void CDeviceCommandContext::EndScopedLabel() +{ + if (!m_Device->GetCapabilities().debugScopedLabels) + return; + + ENSURE(m_ScopedLabelDepth > 0); + --m_ScopedLabelDepth; + glPopDebugGroup(); +} + void CDeviceCommandContext::BindTexture(const uint32_t unit, const GLenum target, const GLuint handle) { ENSURE(unit < m_BoundTextures.size()); @@ -369,6 +388,8 @@ void CDeviceCommandContext::Flush() ResetStates(); BindTexture(0, GL_TEXTURE_2D, 0); + + ENSURE(m_ScopedLabelDepth == 0); } void CDeviceCommandContext::ResetStates() diff --git a/source/renderer/backend/gl/DeviceCommandContext.h b/source/renderer/backend/gl/DeviceCommandContext.h index 4e2757a1ab..de0c37f987 100644 --- a/source/renderer/backend/gl/DeviceCommandContext.h +++ b/source/renderer/backend/gl/DeviceCommandContext.h @@ -84,6 +84,9 @@ public: }; void SetScissors(const uint32_t scissorCount, const ScissorRect* scissors); + void BeginScopedLabel(const char* name); + void EndScopedLabel(); + // TODO: remove direct binding after moving shaders. void BindTexture(const uint32_t unit, const GLenum target, const GLuint handle); void BindBuffer(const CBuffer::Type type, CBuffer* buffer); @@ -110,6 +113,8 @@ private: // GL2.1 doesn't support more than 1 scissor. std::array m_Scissors; + uint32_t m_ScopedLabelDepth = 0; + uint32_t m_ActiveTextureUnit = 0; using BindUnit = std::pair; std::array m_BoundTextures; @@ -132,4 +137,27 @@ private: } // namespace Renderer +#define GPU_SCOPED_LABEL(deviceCommandContext, name) \ + GPUScopedLabel scopedLabel((deviceCommandContext), (name)); + +class GPUScopedLabel +{ +public: + GPUScopedLabel( + Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, + const char* name) + : m_DeviceCommandContext(deviceCommandContext) + { + m_DeviceCommandContext->BeginScopedLabel(name); + } + + ~GPUScopedLabel() + { + m_DeviceCommandContext->EndScopedLabel(); + } + +private: + Renderer::Backend::GL::CDeviceCommandContext* m_DeviceCommandContext = nullptr; +}; + #endif // INCLUDED_RENDERER_GL_DEVICECOMMANDCONTEXT diff --git a/source/renderer/backend/gl/Texture.cpp b/source/renderer/backend/gl/Texture.cpp index 402a18cb4c..71a75f397d 100644 --- a/source/renderer/backend/gl/Texture.cpp +++ b/source/renderer/backend/gl/Texture.cpp @@ -259,11 +259,10 @@ std::unique_ptr CTexture::Create(CDevice* device, const char* name, ogl_WarnIfError(); -#if KHR_DEBUG_ENABLED - glObjectLabel(GL_TEXTURE, texture->m_Handle, -1, name); -#else - UNUSED2(name); -#endif + if (texture->m_Device->GetCapabilities().debugLabels) + { + glObjectLabel(GL_TEXTURE, texture->m_Handle, -1, name); + } texture->m_Device->GetActiveCommandContext()->BindTexture(0, target, 0);