diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e002fc66f..c74c9534d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1117,6 +1117,7 @@ set( FASTMATH_SOURCES gl/shaders/gl_lensshader.cpp gl/system/gl_interface.cpp gl/system/gl_framebuffer.cpp + gl/system/gl_debug.cpp gl/system/gl_menu.cpp gl/system/gl_wipe.cpp gl/system/gl_load.c diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index a53067d8b..5f523e9eb 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -59,6 +59,7 @@ #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" #include "gl/system/gl_cvars.h" +#include "gl/system/gl_debug.h" #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_renderbuffers.h" @@ -127,6 +128,8 @@ void FGLRenderer::BloomScene() if (!gl_bloom || !FGLRenderBuffers::IsEnabled() || gl_fixedcolormap != CM_DEFAULT) return; + FGLDebug::PushGroup("BloomScene"); + FGLPostProcessState savedState; const float blurAmount = gl_bloom_amount; @@ -196,6 +199,8 @@ void FGLRenderer::BloomScene() mBloomCombineShader->BloomTexture.Set(0); RenderScreenQuad(); glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height); + + FGLDebug::PopGroup(); } //----------------------------------------------------------------------------- @@ -209,6 +214,8 @@ void FGLRenderer::TonemapScene() if (gl_tonemap == 0 || !FGLRenderBuffers::IsEnabled()) return; + FGLDebug::PushGroup("TonemapScene"); + FGLPostProcessState savedState; mBuffers->BindNextFB(); @@ -218,6 +225,8 @@ void FGLRenderer::TonemapScene() mTonemapShader->Exposure.Set(mCameraExposure); RenderScreenQuad(); mBuffers->NextTexture(); + + FGLDebug::PopGroup(); } //----------------------------------------------------------------------------- @@ -231,6 +240,8 @@ void FGLRenderer::LensDistortScene() if (gl_lens == 0 || !FGLRenderBuffers::IsEnabled()) return; + FGLDebug::PushGroup("LensDistortScene"); + float k[4] = { gl_lens_k, @@ -272,6 +283,8 @@ void FGLRenderer::LensDistortScene() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); mBuffers->NextTexture(); + + FGLDebug::PopGroup(); } //----------------------------------------------------------------------------- @@ -283,6 +296,7 @@ void FGLRenderer::LensDistortScene() void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma) { m2DDrawer->Flush(); // draw all pending 2D stuff before copying the buffer + FGLDebug::PushGroup("CopyToBackbuffer"); if (FGLRenderBuffers::IsEnabled()) { FGLPostProcessState savedState; @@ -327,6 +341,7 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma) FGLPostProcessState savedState; ClearBorders(); } + FGLDebug::PopGroup(); } //----------------------------------------------------------------------------- diff --git a/src/gl/renderer/gl_postprocessstate.cpp b/src/gl/renderer/gl_postprocessstate.cpp index 7e34a1149..058e41190 100644 --- a/src/gl/renderer/gl_postprocessstate.cpp +++ b/src/gl/renderer/gl_postprocessstate.cpp @@ -59,6 +59,7 @@ FGLPostProcessState::FGLPostProcessState() glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex); glActiveTexture(GL_TEXTURE0); glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); + glBindTexture(GL_TEXTURE_2D, 0); if (gl.flags & RFL_SAMPLER_OBJECTS) { glGetIntegerv(GL_SAMPLER_BINDING, &samplerBinding); @@ -117,8 +118,9 @@ FGLPostProcessState::~FGLPostProcessState() glUseProgram(currentProgram); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textureBinding); + glBindTexture(GL_TEXTURE_2D, 0); if (gl.flags & RFL_SAMPLER_OBJECTS) glBindSampler(0, samplerBinding); + glBindTexture(GL_TEXTURE_2D, textureBinding); glActiveTexture(activeTex); } diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index abf32500a..9c9c76979 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -47,6 +47,7 @@ #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" #include "gl/system/gl_cvars.h" +#include "gl/system/gl_debug.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderbuffers.h" #include "w_wad.h" @@ -65,6 +66,7 @@ CVAR(Bool, gl_renderbuffers, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); FGLRenderBuffers::FGLRenderBuffers() { glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*)&mOutputFB); + glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); } //========================================================================== @@ -147,7 +149,7 @@ void FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHei if (width <= 0 || height <= 0) I_FatalError("Requested invalid render buffer sizes: screen = %dx%d", width, height); - int samples = GetCvarSamples(); + int samples = clamp((int)gl_multisample, 0, mMaxSamples); GLint activeTex; GLint textureBinding; @@ -177,7 +179,7 @@ void FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHei mBloomHeight = sceneHeight; } - glBindTexture(GL_TEXTURE_BINDING_2D, textureBinding); + glBindTexture(GL_TEXTURE_2D, textureBinding); glActiveTexture(activeTex); glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -194,18 +196,18 @@ void FGLRenderBuffers::CreateScene(int width, int height, int samples) ClearScene(); if (samples > 1) - mSceneMultisample = CreateRenderBuffer(GetHdrFormat(), samples, width, height); + mSceneMultisample = CreateRenderBuffer("SceneMultisample", GetHdrFormat(), samples, width, height); if ((gl.flags & RFL_NO_DEPTHSTENCIL) != 0) { - mSceneDepth = CreateRenderBuffer(GL_DEPTH_COMPONENT24, samples, width, height); - mSceneStencil = CreateRenderBuffer(GL_STENCIL_INDEX8, samples, width, height); - mSceneFB = CreateFrameBuffer(samples > 1 ? mSceneMultisample : mPipelineTexture[0], mSceneDepth, mSceneStencil, samples > 1); + mSceneDepth = CreateRenderBuffer("SceneDepth", GL_DEPTH_COMPONENT24, samples, width, height); + mSceneStencil = CreateRenderBuffer("SceneStencil", GL_STENCIL_INDEX8, samples, width, height); + mSceneFB = CreateFrameBuffer("SceneFB", samples > 1 ? mSceneMultisample : mPipelineTexture[0], mSceneDepth, mSceneStencil, samples > 1); } else { - mSceneDepthStencil = CreateRenderBuffer(GL_DEPTH24_STENCIL8, samples, width, height); - mSceneFB = CreateFrameBuffer(samples > 1 ? mSceneMultisample : mPipelineTexture[0], mSceneDepthStencil, samples > 1); + mSceneDepthStencil = CreateRenderBuffer("SceneDepthStencil", GL_DEPTH24_STENCIL8, samples, width, height); + mSceneFB = CreateFrameBuffer("SceneFB", samples > 1 ? mSceneMultisample : mPipelineTexture[0], mSceneDepthStencil, samples > 1); } } @@ -221,8 +223,8 @@ void FGLRenderBuffers::CreatePipeline(int width, int height) for (int i = 0; i < NumPipelineTextures; i++) { - mPipelineTexture[i] = Create2DTexture(GetHdrFormat(), width, height); - mPipelineFB[i] = CreateFrameBuffer(mPipelineTexture[i]); + mPipelineTexture[i] = Create2DTexture("PipelineTexture", GetHdrFormat(), width, height); + mPipelineFB[i] = CreateFrameBuffer("PipelineFB", mPipelineTexture[i]); } } @@ -248,10 +250,10 @@ void FGLRenderBuffers::CreateBloom(int width, int height) level.Width = MAX(bloomWidth / 2, 1); level.Height = MAX(bloomHeight / 2, 1); - level.VTexture = Create2DTexture(GetHdrFormat(), level.Width, level.Height); - level.HTexture = Create2DTexture(GetHdrFormat(), level.Width, level.Height); - level.VFramebuffer = CreateFrameBuffer(level.VTexture); - level.HFramebuffer = CreateFrameBuffer(level.HTexture); + level.VTexture = Create2DTexture("Bloom.VTexture", GetHdrFormat(), level.Width, level.Height); + level.HTexture = Create2DTexture("Bloom.HTexture", GetHdrFormat(), level.Width, level.Height); + level.VFramebuffer = CreateFrameBuffer("Bloom.VFramebuffer", level.VTexture); + level.HFramebuffer = CreateFrameBuffer("Bloom.HFramebuffer", level.HTexture); bloomWidth = level.Width; bloomHeight = level.Height; @@ -269,37 +271,19 @@ GLuint FGLRenderBuffers::GetHdrFormat() return ((gl.flags & RFL_NO_RGBA16F) != 0) ? GL_RGBA8 : GL_RGBA16; } -//========================================================================== -// -// Converts the CVAR multisample value into a valid level for OpenGL -// -//========================================================================== - -int FGLRenderBuffers::GetCvarSamples() -{ - int maxSamples = 0; - glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); - - int samples = clamp((int)gl_multisample, 0, maxSamples); - - int count; - for (count = 0; samples > 0; count++) - samples >>= 1; - return count; -} - //========================================================================== // // Creates a 2D texture defaulting to linear filtering and clamp to edge // //========================================================================== -GLuint FGLRenderBuffers::Create2DTexture(GLuint format, int width, int height) +GLuint FGLRenderBuffers::Create2DTexture(const FString &name, GLuint format, int width, int height) { GLuint type = (format == GL_RGBA16) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE; GLuint handle = 0; glGenTextures(1, &handle); glBindTexture(GL_TEXTURE_2D, handle); + FGLDebug::LabelObject(GL_TEXTURE, handle, name); glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, GL_RGBA, type, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -314,23 +298,25 @@ GLuint FGLRenderBuffers::Create2DTexture(GLuint format, int width, int height) // //========================================================================== -GLuint FGLRenderBuffers::CreateRenderBuffer(GLuint format, int width, int height) +GLuint FGLRenderBuffers::CreateRenderBuffer(const FString &name, GLuint format, int width, int height) { GLuint handle = 0; glGenRenderbuffers(1, &handle); glBindRenderbuffer(GL_RENDERBUFFER, handle); + FGLDebug::LabelObject(GL_RENDERBUFFER, handle, name); glRenderbufferStorage(GL_RENDERBUFFER, format, width, height); return handle; } -GLuint FGLRenderBuffers::CreateRenderBuffer(GLuint format, int samples, int width, int height) +GLuint FGLRenderBuffers::CreateRenderBuffer(const FString &name, GLuint format, int samples, int width, int height) { if (samples <= 1) - return CreateRenderBuffer(format, width, height); + return CreateRenderBuffer(name, format, width, height); GLuint handle = 0; glGenRenderbuffers(1, &handle); glBindRenderbuffer(GL_RENDERBUFFER, handle); + FGLDebug::LabelObject(GL_RENDERBUFFER, handle, name); glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, format, width, height); return handle; } @@ -341,37 +327,40 @@ GLuint FGLRenderBuffers::CreateRenderBuffer(GLuint format, int samples, int widt // //========================================================================== -GLuint FGLRenderBuffers::CreateFrameBuffer(GLuint colorbuffer) +GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuffer) { GLuint handle = 0; glGenFramebuffers(1, &handle); glBindFramebuffer(GL_FRAMEBUFFER, handle); + FGLDebug::LabelObject(GL_FRAMEBUFFER, handle, name); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0); CheckFrameBufferCompleteness(); - ClearFrameBuffer(); + ClearFrameBuffer(false, false); return handle; } -GLuint FGLRenderBuffers::CreateFrameBuffer(GLuint colorbuffer, GLuint depthstencil, bool colorIsARenderBuffer) +GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuffer, GLuint depthstencil, bool colorIsARenderBuffer) { GLuint handle = 0; glGenFramebuffers(1, &handle); glBindFramebuffer(GL_FRAMEBUFFER, handle); + FGLDebug::LabelObject(GL_FRAMEBUFFER, handle, name); if (colorIsARenderBuffer) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuffer); else glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthstencil); CheckFrameBufferCompleteness(); - ClearFrameBuffer(); + ClearFrameBuffer(true, true); return handle; } -GLuint FGLRenderBuffers::CreateFrameBuffer(GLuint colorbuffer, GLuint depth, GLuint stencil, bool colorIsARenderBuffer) +GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuffer, GLuint depth, GLuint stencil, bool colorIsARenderBuffer) { GLuint handle = 0; glGenFramebuffers(1, &handle); glBindFramebuffer(GL_FRAMEBUFFER, handle); + FGLDebug::LabelObject(GL_FRAMEBUFFER, handle, name); if (colorIsARenderBuffer) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuffer); else @@ -379,7 +368,7 @@ GLuint FGLRenderBuffers::CreateFrameBuffer(GLuint colorbuffer, GLuint depth, GLu glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil); CheckFrameBufferCompleteness(); - ClearFrameBuffer(); + ClearFrameBuffer(true, true); return handle; } @@ -417,7 +406,7 @@ void FGLRenderBuffers::CheckFrameBufferCompleteness() // //========================================================================== -void FGLRenderBuffers::ClearFrameBuffer() +void FGLRenderBuffers::ClearFrameBuffer(bool stencil, bool depth) { GLboolean scissorEnabled; GLint stencilValue; @@ -429,7 +418,12 @@ void FGLRenderBuffers::ClearFrameBuffer() glClearColor(0.0, 0.0, 0.0, 0.0); glClearDepth(0.0); glClearStencil(0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + GLenum flags = GL_COLOR_BUFFER_BIT; + if (stencil) + flags |= GL_STENCIL_BUFFER_BIT; + if (depth) + flags |= GL_DEPTH_BUFFER_BIT; + glClear(flags); glClearStencil(stencilValue); glClearDepth(depthValue); if (scissorEnabled) @@ -452,6 +446,13 @@ void FGLRenderBuffers::BlitSceneToTexture() glBindFramebuffer(GL_READ_FRAMEBUFFER, mSceneFB); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture]); glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); + + if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0) + { + GLenum attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_STENCIL_ATTACHMENT }; + glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 2, attachments); + } + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } diff --git a/src/gl/renderer/gl_renderbuffers.h b/src/gl/renderer/gl_renderbuffers.h index 4d2c551c2..9c04eb546 100644 --- a/src/gl/renderer/gl_renderbuffers.h +++ b/src/gl/renderer/gl_renderbuffers.h @@ -47,24 +47,24 @@ private: void CreateScene(int width, int height, int samples); void CreatePipeline(int width, int height); void CreateBloom(int width, int height); - GLuint Create2DTexture(GLuint format, int width, int height); - GLuint CreateRenderBuffer(GLuint format, int width, int height); - GLuint CreateRenderBuffer(GLuint format, int samples, int width, int height); - GLuint CreateFrameBuffer(GLuint colorbuffer); - GLuint CreateFrameBuffer(GLuint colorbuffer, GLuint depthstencil, bool colorIsARenderBuffer); - GLuint CreateFrameBuffer(GLuint colorbuffer, GLuint depth, GLuint stencil, bool colorIsARenderBuffer); + GLuint Create2DTexture(const FString &name, GLuint format, int width, int height); + GLuint CreateRenderBuffer(const FString &name, GLuint format, int width, int height); + GLuint CreateRenderBuffer(const FString &name, GLuint format, int samples, int width, int height); + GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer); + GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer, GLuint depthstencil, bool colorIsARenderBuffer); + GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer, GLuint depth, GLuint stencil, bool colorIsARenderBuffer); void CheckFrameBufferCompleteness(); - void ClearFrameBuffer(); + void ClearFrameBuffer(bool stencil, bool depth); void DeleteTexture(GLuint &handle); void DeleteRenderBuffer(GLuint &handle); void DeleteFrameBuffer(GLuint &handle); - int GetCvarSamples(); GLuint GetHdrFormat(); int mWidth = 0; int mHeight = 0; int mSamples = 0; + int mMaxSamples = 0; int mBloomWidth = 0; int mBloomHeight = 0; diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 8c4baee60..9d2276b52 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -54,6 +54,7 @@ #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" #include "gl/system/gl_cvars.h" +#include "gl/system/gl_debug.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" @@ -131,6 +132,7 @@ void FGLRenderer::Initialize(int width, int height) { glGenVertexArrays(1, &mVAOID); glBindVertexArray(mVAOID); + FGLDebug::LabelObject(GL_VERTEX_ARRAY, mVAOID, "FGLRenderer.mVAOID"); } else mVAOID = 0; @@ -366,9 +368,13 @@ void FGLRenderer::FlushTextures() bool FGLRenderer::StartOffscreen() { - if (mFBID == 0) glGenFramebuffers(1, &mFBID); + bool firstBind = (mFBID == 0); + if (mFBID == 0) + glGenFramebuffers(1, &mFBID); glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mOldFBID); glBindFramebuffer(GL_FRAMEBUFFER, mFBID); + if (firstBind) + FGLDebug::LabelObject(GL_FRAMEBUFFER, mFBID, "OffscreenFB"); return true; } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 91f01adf7..b96b1d3b6 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -174,18 +174,18 @@ void FGLRenderer::Set3DViewport(bool mainview) mBuffers->BindSceneFB(); } + // Always clear all buffers with scissor test disabled. + // This is faster on newer hardware because it allows the GPU to skip + // reading from slower memory where the full buffers are stored. + glDisable(GL_SCISSOR_TEST); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + const auto &bounds = mSceneViewport; glViewport(bounds.left, bounds.top, bounds.width, bounds.height); glScissor(bounds.left, bounds.top, bounds.width, bounds.height); glEnable(GL_SCISSOR_TEST); - - #ifdef _DEBUG - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - #else - glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - #endif glEnable(GL_MULTISAMPLE); glEnable(GL_DEPTH_TEST); diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index cce8c6563..d0cc5ef3f 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -50,6 +50,7 @@ #include "cmdlib.h" #include "gl/system/gl_interface.h" +#include "gl/system/gl_debug.h" #include "gl/data/gl_data.h" #include "gl/data/gl_matrix.h" #include "gl/renderer/gl_renderer.h" @@ -179,6 +180,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * hVertProg = glCreateShader(GL_VERTEX_SHADER); hFragProg = glCreateShader(GL_FRAGMENT_SHADER); + FGLDebug::LabelObject(GL_SHADER, hVertProg, vert_prog_lump); + FGLDebug::LabelObject(GL_SHADER, hFragProg, frag_prog_lump); int vp_size = (int)vp_comb.Len(); int fp_size = (int)fp_comb.Len(); @@ -193,6 +196,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * glCompileShader(hFragProg); hShader = glCreateProgram(); + FGLDebug::LabelObject(GL_PROGRAM, hShader, name); glAttachShader(hShader, hVertProg); glAttachShader(hShader, hFragProg); diff --git a/src/gl/shaders/gl_shaderprogram.cpp b/src/gl/shaders/gl_shaderprogram.cpp index bed4a2e29..63ce09261 100644 --- a/src/gl/shaders/gl_shaderprogram.cpp +++ b/src/gl/shaders/gl_shaderprogram.cpp @@ -46,6 +46,7 @@ #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_cvars.h" +#include "gl/system/gl_debug.h" #include "gl/shaders/gl_shaderprogram.h" #include "w_wad.h" #include "i_system.h" @@ -107,6 +108,8 @@ void FShaderProgram::Compile(ShaderType type, const char *name, const FString &c const auto &handle = mShaders[type]; + FGLDebug::LabelObject(GL_SHADER, handle, name); + FString patchedCode = PatchShader(type, code, defines, maxGlslVersion); int lengths[1] = { (int)patchedCode.Len() }; const char *sources[1] = { patchedCode.GetChars() }; @@ -147,6 +150,7 @@ void FShaderProgram::SetFragDataLocation(int index, const char *name) void FShaderProgram::Link(const char *name) { + FGLDebug::LabelObject(GL_PROGRAM, mProgram, name); glLinkProgram(mProgram); GLint status = 0; diff --git a/src/gl/system/gl_cvars.h b/src/gl/system/gl_cvars.h index 4b28bb667..0c31f53a8 100644 --- a/src/gl/system/gl_cvars.h +++ b/src/gl/system/gl_cvars.h @@ -54,4 +54,7 @@ EXTERN_CVAR(Float, gl_lens_k) EXTERN_CVAR(Float, gl_lens_kcube) EXTERN_CVAR(Float, gl_lens_chromatic) +EXTERN_CVAR(Int, gl_debug_level) +EXTERN_CVAR(Bool, gl_debug_breakpoint) + #endif // _GL_INTERN_H diff --git a/src/gl/system/gl_debug.cpp b/src/gl/system/gl_debug.cpp new file mode 100644 index 000000000..9553345c9 --- /dev/null +++ b/src/gl/system/gl_debug.cpp @@ -0,0 +1,340 @@ +/* +** gl_debig.cpp +** OpenGL debugging support functions +** +**--------------------------------------------------------------------------- +** Copyright 2016 Magnus Norddahl +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** 4. When not used as part of GZDoom or a GZDoom derivative, this code will be +** covered by the terms of the GNU Lesser General Public License as published +** by the Free Software Foundation; either version 2.1 of the License, or (at +** your option) any later version. +** 5. Full disclosure of the entire project's source code, except for third +** party libraries is mandatory. (NOTE: This clause is non-negotiable!) +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "templates.h" +#include "gl/system/gl_system.h" +#include "gl/system/gl_interface.h" +#include "gl/system/gl_debug.h" +#include + +#ifndef _MSC_VER +#include +#endif + +CVAR(Int, gl_debug_level, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); +CVAR(Bool, gl_debug_breakpoint, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); + +//----------------------------------------------------------------------------- +// +// Updates OpenGL debugging state +// +//----------------------------------------------------------------------------- + +void FGLDebug::Update() +{ + SetupBreakpointMode(); + UpdateLoggingLevel(); + OutputMessageLog(); +} + +//----------------------------------------------------------------------------- +// +// Label objects so they are referenced by name in debug messages and in +// OpenGL debuggers (renderdoc) +// +//----------------------------------------------------------------------------- + +void FGLDebug::LabelObject(GLenum type, GLuint handle, const FString &name) +{ + if (gl_debug_level != 0) + { + glObjectLabel(type, handle, (GLsizei)name.Len(), name.GetChars()); + } +} + +void FGLDebug::LabelObjectPtr(void *ptr, const FString &name) +{ + if (gl_debug_level != 0) + { + glObjectPtrLabel(ptr, (GLsizei)name.Len(), name.GetChars()); + } +} + +//----------------------------------------------------------------------------- +// +// Marks which render pass/group is executing commands so that debuggers can +// display this information +// +//----------------------------------------------------------------------------- + +void FGLDebug::PushGroup(const FString &name) +{ + if (gl_debug_level != 0) + { + glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, (GLsizei)name.Len(), name.GetChars()); + } +} + +void FGLDebug::PopGroup() +{ + if (gl_debug_level != 0) + { + glPopDebugGroup(); + } +} + +//----------------------------------------------------------------------------- +// +// Turns on synchronous debugging on and off based on gl_debug_breakpoint +// +// Allows getting the debugger to break exactly at the OpenGL function emitting +// a message. +// +//----------------------------------------------------------------------------- + +void FGLDebug::SetupBreakpointMode() +{ + if (mBreakpointMode != gl_debug_breakpoint) + { + if (gl_debug_breakpoint) + { + glDebugMessageCallback(&FGLDebug::DebugCallback, this); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + } + else + { + glDebugMessageCallback(nullptr, nullptr); + glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + } + mBreakpointMode = gl_debug_breakpoint; + } +} + +//----------------------------------------------------------------------------- +// +// Tells OpenGL which debug messages we are interested in +// +//----------------------------------------------------------------------------- + +void FGLDebug::UpdateLoggingLevel() +{ + int level = gl_debug_level; + if (level != mCurrentLevel) + { + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, nullptr, level > 0); + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, nullptr, level > 1); + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, nullptr, level > 2); + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, level > 3); + mCurrentLevel = level; + } +} + +//----------------------------------------------------------------------------- +// +// The log may already contain entries for a debug level we are no longer +// interested in.. +// +//----------------------------------------------------------------------------- + +bool FGLDebug::IsFilteredByDebugLevel(GLenum severity) +{ + int severityLevel = 0; + switch (severity) + { + case GL_DEBUG_SEVERITY_HIGH: severityLevel = 1; break; + case GL_DEBUG_SEVERITY_MEDIUM: severityLevel = 2; break; + case GL_DEBUG_SEVERITY_LOW: severityLevel = 3; break; + case GL_DEBUG_SEVERITY_NOTIFICATION: severityLevel = 4; break; + } + return severityLevel > (int)gl_debug_level; +} + +//----------------------------------------------------------------------------- +// +// Prints all logged messages to the console +// +//----------------------------------------------------------------------------- + +void FGLDebug::OutputMessageLog() +{ + if (mCurrentLevel <= 0) + return; + + GLint maxDebugMessageLength = 0; + glGetIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH, &maxDebugMessageLength); + + const int maxMessages = 50; + const int messageLogSize = maxMessages * maxDebugMessageLength; + + TArray sources, types, severities; + TArray ids; + TArray lengths; + TArray messageLog; + + sources.Resize(maxMessages); + types.Resize(maxMessages); + severities.Resize(maxMessages); + ids.Resize(maxMessages); + lengths.Resize(maxMessages); + messageLog.Resize(messageLogSize); + + while (true) + { + GLuint numMessages = glGetDebugMessageLog(maxMessages, messageLogSize, &sources[0], &types[0], &ids[0], &severities[0], &lengths[0], &messageLog[0]); + if (numMessages <= 0) break; + + GLsizei offset = 0; + for (GLuint i = 0; i < numMessages; i++) + { + if (!IsFilteredByDebugLevel(severities[i])) + PrintMessage(sources[i], types[i], ids[i], severities[i], lengths[i], &messageLog[offset]); + offset += lengths[i]; + } + } +} + +//----------------------------------------------------------------------------- +// +// Print a single message to the console +// +//----------------------------------------------------------------------------- + +void FGLDebug::PrintMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message) +{ + if (type == GL_DEBUG_TYPE_PUSH_GROUP || type == GL_DEBUG_TYPE_POP_GROUP) + return; + + const int maxMessages = 50; + + static int messagesPrinted = 0; + if (messagesPrinted > maxMessages) + return; + + FString msg(message, length); + + static std::set seenMessages; + bool alreadySeen = !seenMessages.insert(msg.GetChars()).second; + if (alreadySeen) + return; + + messagesPrinted++; + if (messagesPrinted == maxMessages) + { + Printf("Max OpenGL debug messages reached. Suppressing further output.\n"); + } + else if (messagesPrinted < maxMessages) + { + FString sourceStr = SourceToString(source); + FString typeStr = TypeToString(type); + FString severityStr = SeverityToString(severity); + if (type != GL_DEBUG_TYPE_OTHER) + Printf("[%s] %s, %s: %s\n", sourceStr.GetChars(), severityStr.GetChars(), typeStr.GetChars(), msg.GetChars()); + else + Printf("[%s] %s: %s\n", sourceStr.GetChars(), severityStr.GetChars(), msg.GetChars()); + } +} + +//----------------------------------------------------------------------------- +// +// OpenGL callback function used when synchronous debugging is enabled +// +//----------------------------------------------------------------------------- + +void FGLDebug::DebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) +{ + if (IsFilteredByDebugLevel(severity)) + return; + + PrintMessage(source, type, id, severity, length, message); + + if (severity != GL_DEBUG_SEVERITY_NOTIFICATION) + { +#ifdef _MSC_VER + DebugBreak(); +#else + raise(SIGTRAP); +#endif + } +} + +//----------------------------------------------------------------------------- +// +// Enum to string helpers +// +//----------------------------------------------------------------------------- + +FString FGLDebug::SourceToString(GLenum source) +{ + FString s; + switch (source) + { + case GL_DEBUG_SOURCE_API: s = "api"; break; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: s = "window system"; break; + case GL_DEBUG_SOURCE_SHADER_COMPILER: s = "shader compiler"; break; + case GL_DEBUG_SOURCE_THIRD_PARTY: s = "third party"; break; + case GL_DEBUG_SOURCE_APPLICATION: s = "application"; break; + case GL_DEBUG_SOURCE_OTHER: s = "other"; break; + default: s.Format("%d", (int)source); + } + return s; +} + +FString FGLDebug::TypeToString(GLenum type) +{ + FString s; + switch (type) + { + case GL_DEBUG_TYPE_ERROR: s = "error"; break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: s = "deprecated"; break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: s = "undefined"; break; + case GL_DEBUG_TYPE_PORTABILITY: s = "portability"; break; + case GL_DEBUG_TYPE_PERFORMANCE: s = "performance"; break; + case GL_DEBUG_TYPE_MARKER: s = "marker"; break; + case GL_DEBUG_TYPE_PUSH_GROUP: s = "push group"; break; + case GL_DEBUG_TYPE_POP_GROUP: s = "pop group"; break; + case GL_DEBUG_TYPE_OTHER: s = "other"; break; + default: s.Format("%d", (int)type); + } + return s; +} + +FString FGLDebug::SeverityToString(GLenum severity) +{ + FString s; + switch (severity) + { + case GL_DEBUG_SEVERITY_LOW: s = "low severity"; break; + case GL_DEBUG_SEVERITY_MEDIUM: s = "medium severity"; break; + case GL_DEBUG_SEVERITY_HIGH: s = "high severity"; break; + case GL_DEBUG_SEVERITY_NOTIFICATION: s = "notification"; break; + default: s.Format("%d", (int)severity); + } + return s; +} diff --git a/src/gl/system/gl_debug.h b/src/gl/system/gl_debug.h new file mode 100644 index 000000000..1688297be --- /dev/null +++ b/src/gl/system/gl_debug.h @@ -0,0 +1,38 @@ +#ifndef __GL_DEBUG_H +#define __GL_DEBUG_H + +#include +#include "gl/system/gl_interface.h" +#include "c_cvars.h" +#include "r_defs.h" + +class FGLDebug +{ +public: + void Update(); + + static void LabelObject(GLenum type, GLuint handle, const FString &name); + static void LabelObjectPtr(void *ptr, const FString &name); + + static void PushGroup(const FString &name); + static void PopGroup(); + +private: + void SetupBreakpointMode(); + void UpdateLoggingLevel(); + void OutputMessageLog(); + + static bool IsFilteredByDebugLevel(GLenum severity); + static void PrintMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message); + + static void APIENTRY DebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam); + + static FString SourceToString(GLenum source); + static FString TypeToString(GLenum type); + static FString SeverityToString(GLenum severity); + + GLenum mCurrentLevel = 0; + bool mBreakpointMode = false; +}; + +#endif diff --git a/src/gl/system/gl_extlist.txt b/src/gl/system/gl_extlist.txt index df59c7a27..efa51ad01 100644 --- a/src/gl/system/gl_extlist.txt +++ b/src/gl/system/gl_extlist.txt @@ -12,3 +12,5 @@ EXT_framebuffer_object EXT_texture_compression_s3tc EXT_texture_filter_anisotropic EXT_texture_sRGB +KHR_debug +ARB_invalidate_subdata diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 096a33393..c74009e1f 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -65,6 +65,7 @@ #include "gl/utility/gl_templates.h" #include "gl/gl_functions.h" #include "gl/renderer/gl_2ddrawer.h" +#include "gl_debug.h" IMPLEMENT_CLASS(OpenGLFrameBuffer) EXTERN_CVAR (Float, vid_brightness) @@ -105,6 +106,8 @@ OpenGLFrameBuffer::OpenGLFrameBuffer(void *hMonitor, int width, int height, int LastCamera = NULL; InitializeState(); + mDebug = std::make_shared(); + mDebug->Update(); gl_SetupMenu(); gl_GenerateGlobalBrightmapFromColormap(); DoSetGamma(); @@ -219,6 +222,7 @@ void OpenGLFrameBuffer::Swap() Finish.Unclock(); swapped = true; FHardwareTexture::UnbindAll(); + mDebug->Update(); } //=========================================================================== diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index d648da30c..5315bb0a9 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -6,8 +6,11 @@ #include "win32gliface.h" #endif +#include + class FHardwareTexture; class FSimpleVertexBuffer; +class FGLDebug; extern long gl_frameMS; extern long gl_frameCount; @@ -117,6 +120,8 @@ private: bool HWGammaActive = false; + std::shared_ptr mDebug; + public: AActor * LastCamera; int palette_brightness; diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 6176a2be9..8c1e4cd9b 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -244,6 +244,8 @@ void gl_LoadExtensions() gl.buffermethod = BM_PERSISTENT; } + if (gl.version >= 4.3f || CheckExtension("GL_ARB_invalidate_subdata")) gl.flags |= RFL_INVALIDATE_BUFFER; + const char *lm = Args->CheckValue("-lightmethod"); if (lm != NULL) { diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index fbe4e09c8..11b0573e5 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -23,7 +23,9 @@ enum RenderFlags RFL_NO_RGBA16F = 32, RFL_NO_DEPTHSTENCIL = 64, - RFL_NO_CLIP_PLANES = 128 + RFL_NO_CLIP_PLANES = 128, + + RFL_INVALIDATE_BUFFER = 256 }; enum TexMode diff --git a/src/gl/system/gl_load.c b/src/gl/system/gl_load.c index aed4e0ff8..c686b60fc 100644 --- a/src/gl/system/gl_load.c +++ b/src/gl/system/gl_load.c @@ -87,15 +87,37 @@ static PROC WinGetProcAddress(const char *name) #endif #endif -int ogl_ext_ARB_texture_compression = ogl_LOAD_FAILED; -int ogl_ext_EXT_texture_compression_s3tc = ogl_LOAD_FAILED; +int ogl_ext_APPLE_client_storage = ogl_LOAD_FAILED; int ogl_ext_ARB_buffer_storage = ogl_LOAD_FAILED; int ogl_ext_ARB_shader_storage_buffer_object = ogl_LOAD_FAILED; -int ogl_ext_EXT_texture_sRGB = ogl_LOAD_FAILED; -int ogl_ext_EXT_texture_filter_anisotropic = ogl_LOAD_FAILED; -int ogl_ext_EXT_framebuffer_object = ogl_LOAD_FAILED; -int ogl_ext_APPLE_client_storage = ogl_LOAD_FAILED; +int ogl_ext_ARB_texture_compression = ogl_LOAD_FAILED; int ogl_ext_ARB_texture_rectangle = ogl_LOAD_FAILED; +int ogl_ext_EXT_framebuffer_object = ogl_LOAD_FAILED; +int ogl_ext_EXT_texture_compression_s3tc = ogl_LOAD_FAILED; +int ogl_ext_EXT_texture_filter_anisotropic = ogl_LOAD_FAILED; +int ogl_ext_EXT_texture_sRGB = ogl_LOAD_FAILED; +int ogl_ext_KHR_debug = ogl_LOAD_FAILED; +int ogl_ext_ARB_invalidate_subdata = ogl_LOAD_FAILED; + +void (CODEGEN_FUNCPTR *_ptrc_glBufferStorage)(GLenum target, GLsizeiptr size, const void * data, GLbitfield flags) = NULL; + +static int Load_ARB_buffer_storage(void) +{ + int numFailed = 0; + _ptrc_glBufferStorage = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizeiptr, const void *, GLbitfield))IntGetProcAddress("glBufferStorage"); + if(!_ptrc_glBufferStorage) numFailed++; + return numFailed; +} + +void (CODEGEN_FUNCPTR *_ptrc_glShaderStorageBlockBinding)(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding) = NULL; + +static int Load_ARB_shader_storage_buffer_object(void) +{ + int numFailed = 0; + _ptrc_glShaderStorageBlockBinding = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLuint))IntGetProcAddress("glShaderStorageBlockBinding"); + if(!_ptrc_glShaderStorageBlockBinding) numFailed++; + return numFailed; +} void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexImage1DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * data) = NULL; void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexImage2DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data) = NULL; @@ -125,26 +147,6 @@ static int Load_ARB_texture_compression(void) return numFailed; } -void (CODEGEN_FUNCPTR *_ptrc_glBufferStorage)(GLenum target, GLsizeiptr size, const void * data, GLbitfield flags) = NULL; - -static int Load_ARB_buffer_storage(void) -{ - int numFailed = 0; - _ptrc_glBufferStorage = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizeiptr, const void *, GLbitfield))IntGetProcAddress("glBufferStorage"); - if(!_ptrc_glBufferStorage) numFailed++; - return numFailed; -} - -void (CODEGEN_FUNCPTR *_ptrc_glShaderStorageBlockBinding)(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding) = NULL; - -static int Load_ARB_shader_storage_buffer_object(void) -{ - int numFailed = 0; - _ptrc_glShaderStorageBlockBinding = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLuint))IntGetProcAddress("glShaderStorageBlockBinding"); - if(!_ptrc_glShaderStorageBlockBinding) numFailed++; - return numFailed; -} - void (CODEGEN_FUNCPTR *_ptrc_glBindFramebufferEXT)(GLenum target, GLuint framebuffer) = NULL; void (CODEGEN_FUNCPTR *_ptrc_glBindRenderbufferEXT)(GLenum target, GLuint renderbuffer) = NULL; GLenum (CODEGEN_FUNCPTR *_ptrc_glCheckFramebufferStatusEXT)(GLenum target) = NULL; @@ -203,6 +205,71 @@ static int Load_EXT_framebuffer_object(void) return numFailed; } +void (CODEGEN_FUNCPTR *_ptrc_glDebugMessageCallback)(GLDEBUGPROC callback, const void * userParam) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDebugMessageControl)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDebugMessageInsert)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf) = NULL; +GLuint (CODEGEN_FUNCPTR *_ptrc_glGetDebugMessageLog)(GLuint count, GLsizei bufSize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetObjectLabel)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei * length, GLchar * label) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetObjectPtrLabel)(const void * ptr, GLsizei bufSize, GLsizei * length, GLchar * label) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetPointerv)(GLenum pname, void ** params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glObjectLabel)(GLenum identifier, GLuint name, GLsizei length, const GLchar * label) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glObjectPtrLabel)(const void * ptr, GLsizei length, const GLchar * label) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glPopDebugGroup)(void) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glPushDebugGroup)(GLenum source, GLuint id, GLsizei length, const GLchar * message) = NULL; + +static int Load_KHR_debug(void) +{ + int numFailed = 0; + _ptrc_glDebugMessageCallback = (void (CODEGEN_FUNCPTR *)(GLDEBUGPROC, const void *))IntGetProcAddress("glDebugMessageCallback"); + if(!_ptrc_glDebugMessageCallback) numFailed++; + _ptrc_glDebugMessageControl = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLenum, GLsizei, const GLuint *, GLboolean))IntGetProcAddress("glDebugMessageControl"); + if(!_ptrc_glDebugMessageControl) numFailed++; + _ptrc_glDebugMessageInsert = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar *))IntGetProcAddress("glDebugMessageInsert"); + if(!_ptrc_glDebugMessageInsert) numFailed++; + _ptrc_glGetDebugMessageLog = (GLuint (CODEGEN_FUNCPTR *)(GLuint, GLsizei, GLenum *, GLenum *, GLuint *, GLenum *, GLsizei *, GLchar *))IntGetProcAddress("glGetDebugMessageLog"); + if(!_ptrc_glGetDebugMessageLog) numFailed++; + _ptrc_glGetObjectLabel = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLsizei, GLsizei *, GLchar *))IntGetProcAddress("glGetObjectLabel"); + if(!_ptrc_glGetObjectLabel) numFailed++; + _ptrc_glGetObjectPtrLabel = (void (CODEGEN_FUNCPTR *)(const void *, GLsizei, GLsizei *, GLchar *))IntGetProcAddress("glGetObjectPtrLabel"); + if(!_ptrc_glGetObjectPtrLabel) numFailed++; + _ptrc_glGetPointerv = (void (CODEGEN_FUNCPTR *)(GLenum, void **))IntGetProcAddress("glGetPointerv"); + if(!_ptrc_glGetPointerv) numFailed++; + _ptrc_glObjectLabel = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLsizei, const GLchar *))IntGetProcAddress("glObjectLabel"); + if(!_ptrc_glObjectLabel) numFailed++; + _ptrc_glObjectPtrLabel = (void (CODEGEN_FUNCPTR *)(const void *, GLsizei, const GLchar *))IntGetProcAddress("glObjectPtrLabel"); + if(!_ptrc_glObjectPtrLabel) numFailed++; + _ptrc_glPopDebugGroup = (void (CODEGEN_FUNCPTR *)(void))IntGetProcAddress("glPopDebugGroup"); + if(!_ptrc_glPopDebugGroup) numFailed++; + _ptrc_glPushDebugGroup = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLsizei, const GLchar *))IntGetProcAddress("glPushDebugGroup"); + if(!_ptrc_glPushDebugGroup) numFailed++; + return numFailed; +} + +void (CODEGEN_FUNCPTR *_ptrc_glInvalidateBufferData)(GLuint buffer) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glInvalidateBufferSubData)(GLuint buffer, GLintptr offset, GLsizeiptr length) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glInvalidateFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum * attachments) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glInvalidateSubFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glInvalidateTexImage)(GLuint texture, GLint level) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glInvalidateTexSubImage)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) = NULL; + +static int Load_ARB_invalidate_subdata(void) +{ + int numFailed = 0; + _ptrc_glInvalidateBufferData = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glInvalidateBufferData"); + if(!_ptrc_glInvalidateBufferData) numFailed++; + _ptrc_glInvalidateBufferSubData = (void (CODEGEN_FUNCPTR *)(GLuint, GLintptr, GLsizeiptr))IntGetProcAddress("glInvalidateBufferSubData"); + if(!_ptrc_glInvalidateBufferSubData) numFailed++; + _ptrc_glInvalidateFramebuffer = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, const GLenum *))IntGetProcAddress("glInvalidateFramebuffer"); + if(!_ptrc_glInvalidateFramebuffer) numFailed++; + _ptrc_glInvalidateSubFramebuffer = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, const GLenum *, GLint, GLint, GLsizei, GLsizei))IntGetProcAddress("glInvalidateSubFramebuffer"); + if(!_ptrc_glInvalidateSubFramebuffer) numFailed++; + _ptrc_glInvalidateTexImage = (void (CODEGEN_FUNCPTR *)(GLuint, GLint))IntGetProcAddress("glInvalidateTexImage"); + if(!_ptrc_glInvalidateTexImage) numFailed++; + _ptrc_glInvalidateTexSubImage = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei))IntGetProcAddress("glInvalidateTexSubImage"); + if(!_ptrc_glInvalidateTexSubImage) numFailed++; + return numFailed; +} + void (CODEGEN_FUNCPTR *_ptrc_glAccum)(GLenum op, GLfloat value) = NULL; void (CODEGEN_FUNCPTR *_ptrc_glAlphaFunc)(GLenum func, GLfloat ref) = NULL; void (CODEGEN_FUNCPTR *_ptrc_glBegin)(GLenum mode) = NULL; @@ -525,7 +592,6 @@ void (CODEGEN_FUNCPTR *_ptrc_glDrawElements)(GLenum mode, GLsizei count, GLenum void (CODEGEN_FUNCPTR *_ptrc_glEdgeFlagPointer)(GLsizei stride, const void * pointer) = NULL; void (CODEGEN_FUNCPTR *_ptrc_glEnableClientState)(GLenum ren_array) = NULL; void (CODEGEN_FUNCPTR *_ptrc_glGenTextures)(GLsizei n, GLuint * textures) = NULL; -void (CODEGEN_FUNCPTR *_ptrc_glGetPointerv)(GLenum pname, void ** params) = NULL; void (CODEGEN_FUNCPTR *_ptrc_glIndexPointer)(GLenum type, GLsizei stride, const void * pointer) = NULL; void (CODEGEN_FUNCPTR *_ptrc_glIndexub)(GLubyte c) = NULL; void (CODEGEN_FUNCPTR *_ptrc_glIndexubv)(const GLubyte * c) = NULL; @@ -2311,19 +2377,21 @@ typedef struct ogl_StrToExtMap_s PFN_LOADFUNCPOINTERS LoadExtension; } ogl_StrToExtMap; -static ogl_StrToExtMap ExtensionMap[9] = { - {"GL_ARB_texture_compression", &ogl_ext_ARB_texture_compression, Load_ARB_texture_compression}, - {"GL_EXT_texture_compression_s3tc", &ogl_ext_EXT_texture_compression_s3tc, NULL}, +static ogl_StrToExtMap ExtensionMap[11] = { + {"GL_APPLE_client_storage", &ogl_ext_APPLE_client_storage, NULL}, {"GL_ARB_buffer_storage", &ogl_ext_ARB_buffer_storage, Load_ARB_buffer_storage}, {"GL_ARB_shader_storage_buffer_object", &ogl_ext_ARB_shader_storage_buffer_object, Load_ARB_shader_storage_buffer_object}, - {"GL_EXT_texture_sRGB", &ogl_ext_EXT_texture_sRGB, NULL}, - {"GL_EXT_texture_filter_anisotropic", &ogl_ext_EXT_texture_filter_anisotropic, NULL}, - {"GL_EXT_framebuffer_object", &ogl_ext_EXT_framebuffer_object, Load_EXT_framebuffer_object}, - {"GL_APPLE_client_storage", &ogl_ext_APPLE_client_storage, NULL}, + {"GL_ARB_texture_compression", &ogl_ext_ARB_texture_compression, Load_ARB_texture_compression}, {"GL_ARB_texture_rectangle", &ogl_ext_ARB_texture_rectangle, NULL}, + {"GL_EXT_framebuffer_object", &ogl_ext_EXT_framebuffer_object, Load_EXT_framebuffer_object}, + {"GL_EXT_texture_compression_s3tc", &ogl_ext_EXT_texture_compression_s3tc, NULL}, + {"GL_EXT_texture_filter_anisotropic", &ogl_ext_EXT_texture_filter_anisotropic, NULL}, + {"GL_EXT_texture_sRGB", &ogl_ext_EXT_texture_sRGB, NULL}, + {"GL_KHR_debug", &ogl_ext_KHR_debug, Load_KHR_debug}, + {"GL_ARB_invalidate_subdata", &ogl_ext_ARB_invalidate_subdata, Load_ARB_invalidate_subdata}, }; -static int g_extensionMapSize = 9; +static int g_extensionMapSize = 11; static ogl_StrToExtMap *FindExtEntry(const char *extensionName) { @@ -2340,15 +2408,17 @@ static ogl_StrToExtMap *FindExtEntry(const char *extensionName) static void ClearExtensionVars(void) { - ogl_ext_ARB_texture_compression = ogl_LOAD_FAILED; - ogl_ext_EXT_texture_compression_s3tc = ogl_LOAD_FAILED; + ogl_ext_APPLE_client_storage = ogl_LOAD_FAILED; ogl_ext_ARB_buffer_storage = ogl_LOAD_FAILED; ogl_ext_ARB_shader_storage_buffer_object = ogl_LOAD_FAILED; - ogl_ext_EXT_texture_sRGB = ogl_LOAD_FAILED; - ogl_ext_EXT_texture_filter_anisotropic = ogl_LOAD_FAILED; - ogl_ext_EXT_framebuffer_object = ogl_LOAD_FAILED; - ogl_ext_APPLE_client_storage = ogl_LOAD_FAILED; + ogl_ext_ARB_texture_compression = ogl_LOAD_FAILED; ogl_ext_ARB_texture_rectangle = ogl_LOAD_FAILED; + ogl_ext_EXT_framebuffer_object = ogl_LOAD_FAILED; + ogl_ext_EXT_texture_compression_s3tc = ogl_LOAD_FAILED; + ogl_ext_EXT_texture_filter_anisotropic = ogl_LOAD_FAILED; + ogl_ext_EXT_texture_sRGB = ogl_LOAD_FAILED; + ogl_ext_KHR_debug = ogl_LOAD_FAILED; + ogl_ext_ARB_invalidate_subdata = ogl_LOAD_FAILED; } @@ -2377,47 +2447,11 @@ static void LoadExtByName(const char *extensionName) } } -static void ProcExtsFromExtString(const char *strExtList) -{ - size_t iExtListLen = strlen(strExtList); - const char *strExtListEnd = strExtList + iExtListLen; - const char *strCurrPos = strExtList; - char strWorkBuff[256]; - while(*strCurrPos) - { - /*Get the extension at our position.*/ - int iStrLen = 0; - const char *strEndStr = strchr(strCurrPos, ' '); - int iStop = 0; - if(strEndStr == NULL) - { - strEndStr = strExtListEnd; - iStop = 1; - } - - iStrLen = (int)((ptrdiff_t)strEndStr - (ptrdiff_t)strCurrPos); - - if(iStrLen > 255) - return; - - strncpy(strWorkBuff, strCurrPos, iStrLen); - strWorkBuff[iStrLen] = '\0'; - - LoadExtByName(strWorkBuff); - - strCurrPos = strEndStr + 1; - if(iStop) break; - } -} - -static int ProcExtsFromExtList(void) +static void ProcExtsFromExtList(void) { GLint iLoop; GLint iNumExtensions = 0; - - if (_ptrc_glGetStringi == NULL) return 0; - _ptrc_glGetIntegerv(GL_NUM_EXTENSIONS, &iNumExtensions); for(iLoop = 0; iLoop < iNumExtensions; iLoop++) @@ -2425,8 +2459,6 @@ static int ProcExtsFromExtList(void) const char *strExtensionName = (const char *)_ptrc_glGetStringi(GL_EXTENSIONS, iLoop); LoadExtByName(strExtensionName); } - - return iNumExtensions; } int ogl_LoadFunctions() @@ -2437,15 +2469,9 @@ int ogl_LoadFunctions() _ptrc_glGetIntegerv = (void (CODEGEN_FUNCPTR *)(GLenum, GLint *))IntGetProcAddress("glGetIntegerv"); if(!_ptrc_glGetIntegerv) return ogl_LOAD_FAILED; _ptrc_glGetStringi = (const GLubyte * (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glGetStringi"); + if(!_ptrc_glGetStringi) return ogl_LOAD_FAILED; - if (0 == ProcExtsFromExtList()) - { - _ptrc_glGetString = (const GLubyte * (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glGetString"); - if(!_ptrc_glGetString) return ogl_LOAD_FAILED; - - ProcExtsFromExtString((const char *)_ptrc_glGetString(GL_EXTENSIONS)); - } - + ProcExtsFromExtList(); numFailed = Load_Version_3_3(); if(numFailed == 0) diff --git a/src/gl/system/gl_load.h b/src/gl/system/gl_load.h index 3360b8777..892709ccd 100644 --- a/src/gl/system/gl_load.h +++ b/src/gl/system/gl_load.h @@ -153,32 +153,19 @@ typedef unsigned int GLhandleARB; extern "C" { #endif /*__cplusplus*/ -extern int ogl_ext_ARB_texture_compression; -extern int ogl_ext_EXT_texture_compression_s3tc; +extern int ogl_ext_APPLE_client_storage; extern int ogl_ext_ARB_buffer_storage; extern int ogl_ext_ARB_shader_storage_buffer_object; -extern int ogl_ext_EXT_texture_sRGB; -extern int ogl_ext_EXT_texture_filter_anisotropic; -extern int ogl_ext_EXT_framebuffer_object; -extern int ogl_ext_APPLE_client_storage; +extern int ogl_ext_ARB_texture_compression; extern int ogl_ext_ARB_texture_rectangle; +extern int ogl_ext_EXT_framebuffer_object; +extern int ogl_ext_EXT_texture_compression_s3tc; +extern int ogl_ext_EXT_texture_filter_anisotropic; +extern int ogl_ext_EXT_texture_sRGB; +extern int ogl_ext_KHR_debug; +extern int ogl_ext_ARB_invalidate_subdata; -#define GL_COMPRESSED_ALPHA_ARB 0x84E9 -#define GL_COMPRESSED_INTENSITY_ARB 0x84EC -#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB -#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA -#define GL_COMPRESSED_RGBA_ARB 0x84EE -#define GL_COMPRESSED_RGB_ARB 0x84ED -#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 -#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 -#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF - -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 #define GL_BUFFER_IMMUTABLE_STORAGE 0x821F #define GL_BUFFER_STORAGE_FLAGS 0x8220 @@ -208,25 +195,22 @@ extern int ogl_ext_ARB_texture_rectangle; #define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 #define GL_SHADER_STORAGE_BUFFER_START 0x90D4 -#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B -#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A -#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F -#define GL_COMPRESSED_SRGB_EXT 0x8C48 -#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C -#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 -#define GL_SLUMINANCE8_EXT 0x8C47 -#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 -#define GL_SLUMINANCE_EXT 0x8C46 -#define GL_SRGB8_ALPHA8_EXT 0x8C43 -#define GL_SRGB8_EXT 0x8C41 -#define GL_SRGB_ALPHA_EXT 0x8C42 -#define GL_SRGB_EXT 0x8C40 +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF -#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF -#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 #define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 #define GL_COLOR_ATTACHMENT10_EXT 0x8CEA @@ -280,12 +264,72 @@ extern int ogl_ext_ARB_texture_rectangle; #define GL_STENCIL_INDEX4_EXT 0x8D47 #define GL_STENCIL_INDEX8_EXT 0x8D48 -#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 -#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 -#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 -#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE + +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB_EXT 0x8C40 + +#define GL_BUFFER 0x82E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 +#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_DEBUG_LOGGED_MESSAGES 0x9145 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_SEVERITY_HIGH 0x9146 +#define GL_DEBUG_SEVERITY_LOW 0x9148 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_DEBUG_SOURCE_API 0x8246 +#define GL_DEBUG_SOURCE_APPLICATION 0x824A +#define GL_DEBUG_SOURCE_OTHER 0x824B +#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_OTHER 0x8251 +#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 +#define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_TYPE_PORTABILITY 0x824F +#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E +#define GL_DISPLAY_LIST 0x82E7 +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 +#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 +#define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_PROGRAM 0x82E2 +#define GL_PROGRAM_PIPELINE 0x82E4 +#define GL_QUERY 0x82E3 +#define GL_SAMPLER 0x82E6 +#define GL_SHADER 0x82E1 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_VERTEX_ARRAY 0x8074 #define GL_2D 0x0600 #define GL_2_BYTES 0x1407 @@ -722,8 +766,8 @@ extern int ogl_ext_ARB_texture_rectangle; #define GL_SRC_ALPHA 0x0302 #define GL_SRC_ALPHA_SATURATE 0x0308 #define GL_SRC_COLOR 0x0300 -#define GL_STACK_OVERFLOW 0x0503 -#define GL_STACK_UNDERFLOW 0x0504 +/*Copied GL_STACK_OVERFLOW From: KHR_debug*/ +/*Copied GL_STACK_UNDERFLOW From: KHR_debug*/ #define GL_STENCIL 0x1802 #define GL_STENCIL_BITS 0x0D57 #define GL_STENCIL_BUFFER_BIT 0x00000400 @@ -804,7 +848,7 @@ extern int ogl_ext_ARB_texture_rectangle; #define GL_V3F 0x2A21 #define GL_VENDOR 0x1F00 #define GL_VERSION 0x1F02 -#define GL_VERTEX_ARRAY 0x8074 +/*Copied GL_VERTEX_ARRAY From: KHR_debug*/ #define GL_VERTEX_ARRAY_POINTER 0x808E #define GL_VERTEX_ARRAY_SIZE 0x807A #define GL_VERTEX_ARRAY_STRIDE 0x807C @@ -1544,6 +1588,19 @@ extern int ogl_ext_ARB_texture_rectangle; #define GL_TIME_ELAPSED 0x88BF #define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE + +#ifndef GL_ARB_buffer_storage +#define GL_ARB_buffer_storage 1 +extern void (CODEGEN_FUNCPTR *_ptrc_glBufferStorage)(GLenum target, GLsizeiptr size, const void * data, GLbitfield flags); +#define glBufferStorage _ptrc_glBufferStorage +#endif /*GL_ARB_buffer_storage*/ + +#ifndef GL_ARB_shader_storage_buffer_object +#define GL_ARB_shader_storage_buffer_object 1 +extern void (CODEGEN_FUNCPTR *_ptrc_glShaderStorageBlockBinding)(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); +#define glShaderStorageBlockBinding _ptrc_glShaderStorageBlockBinding +#endif /*GL_ARB_shader_storage_buffer_object*/ + #ifndef GL_ARB_texture_compression #define GL_ARB_texture_compression 1 extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexImage1DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * data); @@ -1563,20 +1620,6 @@ extern void (CODEGEN_FUNCPTR *_ptrc_glGetCompressedTexImageARB)(GLenum target, G #endif /*GL_ARB_texture_compression*/ -#ifndef GL_ARB_buffer_storage -#define GL_ARB_buffer_storage 1 -extern void (CODEGEN_FUNCPTR *_ptrc_glBufferStorage)(GLenum target, GLsizeiptr size, const void * data, GLbitfield flags); -#define glBufferStorage _ptrc_glBufferStorage -#endif /*GL_ARB_buffer_storage*/ - -#ifndef GL_ARB_shader_storage_buffer_object -#define GL_ARB_shader_storage_buffer_object 1 -extern void (CODEGEN_FUNCPTR *_ptrc_glShaderStorageBlockBinding)(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); -#define glShaderStorageBlockBinding _ptrc_glShaderStorageBlockBinding -#endif /*GL_ARB_shader_storage_buffer_object*/ - - - #ifndef GL_EXT_framebuffer_object #define GL_EXT_framebuffer_object 1 extern void (CODEGEN_FUNCPTR *_ptrc_glBindFramebufferEXT)(GLenum target, GLuint framebuffer); @@ -1617,6 +1660,49 @@ extern void (CODEGEN_FUNCPTR *_ptrc_glRenderbufferStorageEXT)(GLenum target, GLe + +#ifndef GL_KHR_debug +#define GL_KHR_debug 1 +extern void (CODEGEN_FUNCPTR *_ptrc_glDebugMessageCallback)(GLDEBUGPROC callback, const void * userParam); +#define glDebugMessageCallback _ptrc_glDebugMessageCallback +extern void (CODEGEN_FUNCPTR *_ptrc_glDebugMessageControl)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled); +#define glDebugMessageControl _ptrc_glDebugMessageControl +extern void (CODEGEN_FUNCPTR *_ptrc_glDebugMessageInsert)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf); +#define glDebugMessageInsert _ptrc_glDebugMessageInsert +extern GLuint (CODEGEN_FUNCPTR *_ptrc_glGetDebugMessageLog)(GLuint count, GLsizei bufSize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog); +#define glGetDebugMessageLog _ptrc_glGetDebugMessageLog +extern void (CODEGEN_FUNCPTR *_ptrc_glGetObjectLabel)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei * length, GLchar * label); +#define glGetObjectLabel _ptrc_glGetObjectLabel +extern void (CODEGEN_FUNCPTR *_ptrc_glGetObjectPtrLabel)(const void * ptr, GLsizei bufSize, GLsizei * length, GLchar * label); +#define glGetObjectPtrLabel _ptrc_glGetObjectPtrLabel +extern void (CODEGEN_FUNCPTR *_ptrc_glGetPointerv)(GLenum pname, void ** params); +#define glGetPointerv _ptrc_glGetPointerv +extern void (CODEGEN_FUNCPTR *_ptrc_glObjectLabel)(GLenum identifier, GLuint name, GLsizei length, const GLchar * label); +#define glObjectLabel _ptrc_glObjectLabel +extern void (CODEGEN_FUNCPTR *_ptrc_glObjectPtrLabel)(const void * ptr, GLsizei length, const GLchar * label); +#define glObjectPtrLabel _ptrc_glObjectPtrLabel +extern void (CODEGEN_FUNCPTR *_ptrc_glPopDebugGroup)(void); +#define glPopDebugGroup _ptrc_glPopDebugGroup +extern void (CODEGEN_FUNCPTR *_ptrc_glPushDebugGroup)(GLenum source, GLuint id, GLsizei length, const GLchar * message); +#define glPushDebugGroup _ptrc_glPushDebugGroup +#endif /*GL_KHR_debug*/ + +#ifndef GL_ARB_invalidate_subdata +#define GL_ARB_invalidate_subdata 1 +extern void (CODEGEN_FUNCPTR *_ptrc_glInvalidateBufferData)(GLuint buffer); +#define glInvalidateBufferData _ptrc_glInvalidateBufferData +extern void (CODEGEN_FUNCPTR *_ptrc_glInvalidateBufferSubData)(GLuint buffer, GLintptr offset, GLsizeiptr length); +#define glInvalidateBufferSubData _ptrc_glInvalidateBufferSubData +extern void (CODEGEN_FUNCPTR *_ptrc_glInvalidateFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum * attachments); +#define glInvalidateFramebuffer _ptrc_glInvalidateFramebuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glInvalidateSubFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height); +#define glInvalidateSubFramebuffer _ptrc_glInvalidateSubFramebuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glInvalidateTexImage)(GLuint texture, GLint level); +#define glInvalidateTexImage _ptrc_glInvalidateTexImage +extern void (CODEGEN_FUNCPTR *_ptrc_glInvalidateTexSubImage)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); +#define glInvalidateTexSubImage _ptrc_glInvalidateTexSubImage +#endif /*GL_ARB_invalidate_subdata*/ + extern void (CODEGEN_FUNCPTR *_ptrc_glAccum)(GLenum op, GLfloat value); #define glAccum _ptrc_glAccum extern void (CODEGEN_FUNCPTR *_ptrc_glAlphaFunc)(GLenum func, GLfloat ref); diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index 4f701265e..05d63f65d 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -153,7 +153,7 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type) const auto &viewport = GLRenderer->mScreenViewport; wipestartscreen = new FHardwareTexture(viewport.width, viewport.height, true); - wipestartscreen->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0); + wipestartscreen->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeStartScreen"); GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER, -1); GLRenderer->mSamplerManager->Bind(1, CLAMP_NONE, -1); glFinish(); @@ -193,7 +193,7 @@ void OpenGLFrameBuffer::WipeEndScreen() const auto &viewport = GLRenderer->mScreenViewport; wipeendscreen = new FHardwareTexture(viewport.width, viewport.height, true); - wipeendscreen->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0); + wipeendscreen->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeEndScreen"); GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER, -1); glFinish(); wipeendscreen->Bind(0, false, false); @@ -566,7 +566,7 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) // Burn the new screen on top of it. fb->wipeendscreen->Bind(0, 0, false); - BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, 1, true, 0); + BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, 1, true, 0, "BurnTexture"); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); gl_RenderState.SetEffect(EFF_NONE); diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 7d9d754fd..73c4e7b36 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -48,6 +48,7 @@ #include "gl/system/gl_interface.h" #include "gl/system/gl_cvars.h" +#include "gl/system/gl_debug.h" #include "gl/renderer/gl_renderer.h" #include "gl/textures/gl_material.h" @@ -184,7 +185,7 @@ void FHardwareTexture::Resize(int width, int height, unsigned char *src_data, un // //=========================================================================== -unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation) +unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const FString &name) { int rh,rw; int texformat=TexFormat[gl_texture_format]; @@ -198,6 +199,7 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int if (glTex->glTexID==0) glGenTextures(1,&glTex->glTexID); if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit); glBindTexture(GL_TEXTURE_2D, glTex->glTexID); + FGLDebug::LabelObject(GL_TEXTURE, glTex->glTexID, name); lastbound[texunit] = glTex->glTexID; if (!buffer) diff --git a/src/gl/textures/gl_hwtexture.h b/src/gl/textures/gl_hwtexture.h index 6b01fb437..9b7028f8c 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -77,7 +77,7 @@ public: void BindToFrameBuffer(); unsigned int Bind(int texunit, int translation, bool needmipmap); - unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation); + unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const FString &name); void Clean(bool all); void CleanUnused(SpriteHits &usedtranslations); diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 6a579b0d5..8e0ab73e6 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -337,7 +337,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla } tex->ProcessData(buffer, w, h, false); } - if (!hwtex->CreateTexture(buffer, w, h, texunit, needmipmap, translation)) + if (!hwtex->CreateTexture(buffer, w, h, texunit, needmipmap, translation, "FGLTexture.Bind")) { // could not create texture delete[] buffer; diff --git a/src/gl/textures/gl_samplers.cpp b/src/gl/textures/gl_samplers.cpp index cee2fd894..64674e63c 100644 --- a/src/gl/textures/gl_samplers.cpp +++ b/src/gl/textures/gl_samplers.cpp @@ -42,6 +42,7 @@ #include "gl/system/gl_interface.h" #include "gl/system/gl_cvars.h" +#include "gl/system/gl_debug.h" #include "gl/renderer/gl_renderer.h" #include "gl_samplers.h" #include "gl_material.h" @@ -67,6 +68,13 @@ FSamplerManager::FSamplerManager() glSamplerParameteri(mSamplers[3], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSamplerParameteri(mSamplers[4], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glSamplerParameteri(mSamplers[4], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + for (int i = 0; i < 7; i++) + { + FString name; + name.Format("mSamplers[%d]", i); + FGLDebug::LabelObject(GL_SAMPLER, mSamplers[i], name); + } } } diff --git a/src/posix/sdl/sdlglvideo.cpp b/src/posix/sdl/sdlglvideo.cpp index d79dfb94a..29c96d3ea 100644 --- a/src/posix/sdl/sdlglvideo.cpp +++ b/src/posix/sdl/sdlglvideo.cpp @@ -58,6 +58,11 @@ CUSTOM_CVAR(Int, gl_vid_multisample, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_ Printf("This won't take effect until " GAMENAME " is restarted.\n"); } +CUSTOM_CVAR(Bool, gl_debug, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) +{ + Printf("This won't take effect until " GAMENAME " is restarted.\n"); +} + // PRIVATE DATA DEFINITIONS ------------------------------------------------ // Dummy screen sizes to pass when windowed @@ -289,6 +294,8 @@ bool SDLGLVideo::SetupPixelFormat(bool allowsoftware, int multisample) SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 ); SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, multisample ); } + if (gl_debug) + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); return true; } diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index 4f8c4d49b..2edd89631 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -45,7 +45,10 @@ CUSTOM_CVAR(Int, gl_vid_multisample, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_ Printf("This won't take effect until " GAMENAME " is restarted.\n"); } -CVAR(Bool, gl_debug, false, 0) +CUSTOM_CVAR(Bool, gl_debug, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) +{ + Printf("This won't take effect until " GAMENAME " is restarted.\n"); +} EXTERN_CVAR(Bool, vr_enable_quadbuffered) EXTERN_CVAR(Int, vid_refreshrate)