1
0
forked from 0ad/0ad

Add support for GL_KHR_debug in Debug Mode.

Based on a patch by: @linkmauve
Reviewed by: @vladislavbelov
Differential Revision: https://code.wildfiregames.com/D2488
This was SVN commit r26141.
This commit is contained in:
Stan 2021-12-30 15:07:17 +00:00
parent b74fd6d4a2
commit ae32055c9b
10 changed files with 165 additions and 0 deletions

View File

@ -88,6 +88,10 @@
// GL_OES_depth32
#define GL_DEPTH_COMPONENT32 GL_DEPTH_COMPONENT32_OES
// GL_KHR_debug
#define glPopDebugGroupKHR glPopDebugGroup
#define glPushDebugGroupKHR glPushDebugGroup
#endif // CONFIG2_GLES
#endif // !INCLUDED_GLES2_WRAPPER

View File

@ -59,6 +59,9 @@ 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
@ -372,6 +375,84 @@ 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);
}
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);
}
// ignore and reset the specified error (as returned by glGetError).
// any other errors that have occurred are reported as ogl_WarnIfError would.
@ -492,6 +573,25 @@ 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;
}
@ -510,3 +610,21 @@ 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

View File

@ -150,4 +150,21 @@ 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

View File

@ -471,6 +471,13 @@ static Status OglTex_reload(OglTex* ot, const PIVFS& vfs, const VfsPath& pathnam
if(ot->flags & OT_NEED_AUTO_UPLOAD)
(void)ogl_tex_upload(h);
#if KHR_DEBUG_ENABLED
const std::string name = pathname.string8();
glBindTexture(GL_TEXTURE_2D, ot->id);
glObjectLabel(GL_TEXTURE, ot->id, name.size(), name.c_str());
#endif
return INFO::OK;
}

View File

@ -22,6 +22,7 @@
#include "graphics/Canvas2D.h"
#include "graphics/FontMetrics.h"
#include "graphics/TextRenderer.h"
#include "lib/ogl.h"
#include "lib/os_path.h"
#include "lib/timer.h"
#include "lib/utf8.h"
@ -205,6 +206,7 @@ void CLogger::WriteWarning(const char* message)
void CLogger::Render()
{
PROFILE3_GPU("logger");
OGL_SCOPED_DEBUG_GROUP("Draw CLogger messages");
CleanupRenderQueue();

View File

@ -256,6 +256,7 @@ void Render()
if (g_DoRenderGui)
{
OGL_SCOPED_DEBUG_GROUP("Draw GUI");
// All GUI elements are drawn in Z order to render semi-transparent
// objects correctly.
g_GUI->Draw();

View File

@ -658,6 +658,7 @@ void CRenderer::SetClearColor(SColor4ub color)
void CRenderer::RenderShadowMap(const CShaderDefines& context)
{
PROFILE3_GPU("shadow map");
OGL_SCOPED_DEBUG_GROUP("Render shadow map");
CShaderDefines contextCast = context;
contextCast.Add(str_MODE_SHADOWCAST, str_1);
@ -701,6 +702,7 @@ void CRenderer::RenderShadowMap(const CShaderDefines& context)
void CRenderer::RenderPatches(const CShaderDefines& context, int cullGroup)
{
PROFILE3_GPU("patches");
OGL_SCOPED_DEBUG_GROUP("Render patches");
#if CONFIG2_GLES
#warning TODO: implement wireface/edged rendering mode GLES
@ -750,6 +752,7 @@ void CRenderer::RenderPatches(const CShaderDefines& context, int cullGroup)
void CRenderer::RenderModels(const CShaderDefines& context, int cullGroup)
{
PROFILE3_GPU("models");
OGL_SCOPED_DEBUG_GROUP("Render models");
int flags = 0;
@ -784,6 +787,7 @@ void CRenderer::RenderModels(const CShaderDefines& context, int cullGroup)
void CRenderer::RenderTransparentModels(const CShaderDefines& context, int cullGroup, ETransparentMode transparentMode, bool disableFaceCulling)
{
PROFILE3_GPU("transparent models");
OGL_SCOPED_DEBUG_GROUP("Render transparent models");
int flags = 0;
@ -959,6 +963,7 @@ void CRenderer::ComputeRefractionCamera(CCamera& camera, const CBoundingBoxAlign
void CRenderer::RenderReflections(const CShaderDefines& context, const CBoundingBoxAligned& scissor)
{
PROFILE3_GPU("water reflections");
OGL_SCOPED_DEBUG_GROUP("Render water reflections");
WaterManager& wm = m->waterManager;
@ -1034,6 +1039,7 @@ void CRenderer::RenderReflections(const CShaderDefines& context, const CBounding
void CRenderer::RenderRefractions(const CShaderDefines& context, const CBoundingBoxAligned &scissor)
{
PROFILE3_GPU("water refractions");
OGL_SCOPED_DEBUG_GROUP("Render water refractions");
WaterManager& wm = m->waterManager;
@ -1092,6 +1098,7 @@ void CRenderer::RenderRefractions(const CShaderDefines& context, const CBounding
void CRenderer::RenderSilhouettes(const CShaderDefines& context)
{
PROFILE3_GPU("silhouettes");
OGL_SCOPED_DEBUG_GROUP("Render water silhouettes");
CShaderDefines contextOccluder = context;
contextOccluder.Add(str_MODE_SILHOUETTEOCCLUDER, str_1);
@ -1168,6 +1175,7 @@ void CRenderer::RenderSilhouettes(const CShaderDefines& context)
void CRenderer::RenderParticles(int cullGroup)
{
PROFILE3_GPU("particles");
OGL_SCOPED_DEBUG_GROUP("Render particles");
m->particleRenderer.RenderParticles(cullGroup);
@ -1189,6 +1197,7 @@ void CRenderer::RenderParticles(int cullGroup)
void CRenderer::RenderSubmissions(const CBoundingBoxAligned& waterScissor)
{
PROFILE3("render submissions");
OGL_SCOPED_DEBUG_GROUP("Render submissions");
GetScene().GetLOSTexture().InterpolateLOS();

View File

@ -55,6 +55,7 @@ SkyManager::SkyManager()
// Load all sky textures
void SkyManager::LoadSkyTextures()
{
OGL_SCOPED_DEBUG_GROUP("Load Sky Textures");
static const CStrW images[NUMBER_OF_TEXTURES + 1] = {
L"front",
L"back",
@ -208,6 +209,7 @@ std::vector<CStrW> SkyManager::GetSkySets() const
// Render sky
void SkyManager::RenderSky()
{
OGL_SCOPED_DEBUG_GROUP("Render Sky");
#if CONFIG2_GLES
#warning TODO: implement SkyManager::RenderSky for GLES
#else

View File

@ -353,6 +353,7 @@ CBoundingBoxAligned TerrainRenderer::ScissorWater(int cullGroup, const CCamera&
bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGroup, ShadowMap* shadow)
{
PROFILE3_GPU("fancy water");
OGL_SCOPED_DEBUG_GROUP("Render Fancy Water");
WaterManager* waterManager = g_Renderer.GetWaterManager();
CShaderDefines defines = context;
@ -529,6 +530,7 @@ void TerrainRenderer::RenderSimpleWater(int cullGroup)
UNUSED2(cullGroup);
#else
PROFILE3_GPU("simple water");
OGL_SCOPED_DEBUG_GROUP("Render Simple Water");
WaterManager* WaterMgr = g_Renderer.GetWaterManager();
CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture();

View File

@ -447,6 +447,8 @@ 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;
@ -836,6 +838,7 @@ void WaterManager::CreateWaveMeshes()
void WaterManager::RenderWaves(const CFrustum& frustrum)
{
OGL_SCOPED_DEBUG_GROUP("Render Waves");
#if CONFIG2_GLES
#warning Fix WaterManager::RenderWaves on GLES
#else