diff --git a/CMakeLists.txt b/CMakeLists.txt index 34542f84..74c2d429 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,8 @@ endif() project(Alber) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +option(GPU_DEBUG_INFO "Enable additional GPU debugging info" OFF) + include_directories(${PROJECT_SOURCE_DIR}/include/) include_directories(${PROJECT_SOURCE_DIR}/include/kernel) include_directories (${FMT_INCLUDE_DIR}) @@ -138,4 +140,9 @@ source_group("Source Files\\Third Party" FILES ${THIRD_PARTY_SOURCE_FILES}) add_executable(Alber ${SOURCE_FILES} ${FS_SOURCE_FILES} ${KERNEL_SOURCE_FILES} ${LOADER_SOURCE_FILES} ${SERVICE_SOURCE_FILES} ${PICA_SOURCE_FILES} ${RENDERER_GL_SOURCE_FILES} ${THIRD_PARTY_SOURCE_FILES} ${HEADER_FILES}) -target_link_libraries(Alber PRIVATE dynarmic SDL2-static glad) \ No newline at end of file +target_link_libraries(Alber PRIVATE dynarmic SDL2-static glad) + + +if(GPU_DEBUG_INFO) + target_compile_definitions(Alber PRIVATE GPU_DEBUG_INFO=1) +endif() \ No newline at end of file diff --git a/include/opengl.hpp b/include/opengl.hpp index 16ed8221..67c45689 100644 --- a/include/opengl.hpp +++ b/include/opengl.hpp @@ -20,6 +20,7 @@ #pragma once #include #include +#include #include #include #include @@ -43,6 +44,19 @@ #include #endif +#if defined(GPU_DEBUG_INFO) +#define OPENGL_DEBUG_INFO +#endif + +#ifdef _MSC_VER +#include +#define OPENGL_PRINTF_FORMAT _Printf_format_string_ +#define OPENGL_PRINTF_FORMAT_ATTR(format_arg_index, dots_arg_index) +#else +#define OPENGL_PRINTF_FORMAT +#define OPENGL_PRINTF_FORMAT_ATTR(format_arg_index, dots_arg_index) __attribute__((__format__(__printf__, format_arg_index, dots_arg_index))) +#endif + // Uncomment the following define if you want GL objects to automatically free themselves when their lifetime ends // #define OPENGL_DESTRUCTORS @@ -53,7 +67,50 @@ namespace OpenGL { template constexpr std::false_type AlwaysFalse{}; - struct VertexArray { + OPENGL_PRINTF_FORMAT_ATTR(3, 4) + static void setObjectLabel(GLenum identifier, GLuint name, OPENGL_PRINTF_FORMAT const char* format, ...) { +#if defined(OPENGL_DEBUG_INFO) + GLchar label[256] = {}; + va_list args; + va_start(args, format); + const GLsizei length = vsnprintf(label, std::size(label), format, args); + va_end(args); + glObjectLabel(identifier, name, length, label); +#endif + } + + class DebugScope { +#if defined(OPENGL_DEBUG_INFO) + inline static GLuint scopeDepth = 0; + const GLuint m_scope_depth; +#endif + + public: + OPENGL_PRINTF_FORMAT_ATTR(2, 3) + DebugScope(OPENGL_PRINTF_FORMAT const char* format, ...) +#if defined(OPENGL_DEBUG_INFO) + : m_scope_depth(scopeDepth++) { + GLchar message[256] = {}; + va_list args; + va_start(args, format); + const GLsizei length = vsnprintf(message, std::size(message), format, args); + va_end(args); + glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, m_scope_depth, length, message); + } +#else + { + } +#endif + + ~DebugScope() { +#if defined(OPENGL_DEBUG_INFO) + glPopDebugGroup(); + scopeDepth--; +#endif + } + }; + + struct VertexArray { GLuint m_handle = 0; void create() {