From a9db47323103300847864a062e14e3abd755d19b Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Thu, 28 Jun 2018 23:53:15 +0200 Subject: [PATCH] Check for GL debug extensions before use --- hw/xbox/nv2a/gl/gloffscreen.h | 1 - hw/xbox/nv2a/gl/gloffscreen_cgl.c | 5 -- hw/xbox/nv2a/nv2a_debug.c | 80 +++++++++++++++++++++---------- hw/xbox/nv2a/nv2a_debug.h | 5 ++ hw/xbox/nv2a/nv2a_pgraph.c | 4 +- 5 files changed, 62 insertions(+), 33 deletions(-) diff --git a/hw/xbox/nv2a/gl/gloffscreen.h b/hw/xbox/nv2a/gl/gloffscreen.h index 11ab64b3f7..e8aed3143b 100644 --- a/hw/xbox/nv2a/gl/gloffscreen.h +++ b/hw/xbox/nv2a/gl/gloffscreen.h @@ -35,7 +35,6 @@ #if defined(__APPLE__) /* macOS-Specific GL Includes */ #include -#include #include #elif defined(_WIN32) /* Windows-Specific GL Includes */ #include diff --git a/hw/xbox/nv2a/gl/gloffscreen_cgl.c b/hw/xbox/nv2a/gl/gloffscreen_cgl.c index c1e79d0fe0..882fbf2c10 100644 --- a/hw/xbox/nv2a/gl/gloffscreen_cgl.c +++ b/hw/xbox/nv2a/gl/gloffscreen_cgl.c @@ -66,11 +66,6 @@ GloContext *glo_context_create(void) return context; } -void* glo_get_extension_proc(const char* ext_proc) -{ - return dlsym(RTLD_NEXT, ext_proc); -} - /* Set current context */ void glo_set_current(GloContext *context) { diff --git a/hw/xbox/nv2a/nv2a_debug.c b/hw/xbox/nv2a/nv2a_debug.c index 28aa261978..e14d2cac92 100644 --- a/hw/xbox/nv2a/nv2a_debug.c +++ b/hw/xbox/nv2a/nv2a_debug.c @@ -18,27 +18,48 @@ * along with this program; if not, see . */ +#include "nv2a_debug.h" + #ifdef DEBUG_NV2A_GL -#include "qemu/osdep.h" - #include +#include #include #include -#include "nv2a_debug.h" -#include "gl/glextensions.h" - +static bool has_GL_GREMEDY_frame_terminator = false; +static bool has_GL_KHR_debug = false; void gl_debug_initialize(void) { - if (glo_check_extension("GL_KHR_debug")) { + has_GL_KHR_debug = glo_check_extension("GL_KHR_debug"); + has_GL_GREMEDY_frame_terminator = glo_check_extension("GL_GREMEDY_frame_terminator"); + + if (has_GL_KHR_debug) { +#if defined(__APPLE__) + /* On macOS, calling glEnable(GL_DEBUG_OUTPUT) will result in error + * GL_INVALID_ENUM. + * + * According to GL_KHR_debug this should work, therefore probably + * not a bug in our code. + * + * It appears however that we can safely ignore this error, and the + * debug functions which we depend on will still work as expected, + * so skip the call for this platform. + */ +#else glEnable(GL_DEBUG_OUTPUT); + assert(glGetError() == GL_NO_ERROR); +#endif } } void gl_debug_message(bool cc, const char *fmt, ...) { + if (!has_GL_KHR_debug) { + return; + } + size_t n; char buffer[1024]; va_list ap; @@ -47,10 +68,8 @@ void gl_debug_message(bool cc, const char *fmt, ...) assert(n <= sizeof(buffer)); va_end(ap); - if(glDebugMessageInsert) { - glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, - 0, GL_DEBUG_SEVERITY_NOTIFICATION, n, buffer); - } + glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, + 0, GL_DEBUG_SEVERITY_NOTIFICATION, n, buffer); if (cc) { fwrite(buffer, sizeof(char), n, stdout); fputc('\n', stdout); @@ -59,20 +78,21 @@ void gl_debug_message(bool cc, const char *fmt, ...) void gl_debug_group_begin(const char *fmt, ...) { - size_t n; - char buffer[1024]; - va_list ap; - va_start(ap, fmt); - n = vsnprintf(buffer, sizeof(buffer), fmt, ap); - assert(n <= sizeof(buffer)); - va_end(ap); + /* Debug group begin */ + if (has_GL_KHR_debug) { + size_t n; + char buffer[1024]; + va_list ap; + va_start(ap, fmt); + n = vsnprintf(buffer, sizeof(buffer), fmt, ap); + assert(n <= sizeof(buffer)); + va_end(ap); - /* Check for errors before entering group */ - assert(glGetError() == GL_NO_ERROR); - - if (glPushDebugGroup) { glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, n, buffer); } + + /* Check for errors before starting real commands in group */ + assert(glGetError() == GL_NO_ERROR); } void gl_debug_group_end(void) @@ -80,13 +100,18 @@ void gl_debug_group_end(void) /* Check for errors when leaving group */ assert(glGetError() == GL_NO_ERROR); - if (glPopDebugGroup) { + /* Debug group end */ + if (has_GL_KHR_debug) { glPopDebugGroup(); } } void gl_debug_label(GLenum target, GLuint name, const char *fmt, ...) { + if (!has_GL_KHR_debug) { + return; + } + size_t n; char buffer[1024]; va_list ap; @@ -95,9 +120,16 @@ void gl_debug_label(GLenum target, GLuint name, const char *fmt, ...) assert(n <= sizeof(buffer)); va_end(ap); - if (glObjectLabel) { - glObjectLabel(target, name, n, buffer); + glObjectLabel(target, name, n, buffer); +} + +void gl_debug_frame_terminator(void) +{ + if (!has_GL_GREMEDY_frame_terminator) { + return; } + + glFrameTerminatorGREMEDY(); } #endif diff --git a/hw/xbox/nv2a/nv2a_debug.h b/hw/xbox/nv2a/nv2a_debug.h index dab2be6427..a4b865e1c0 100644 --- a/hw/xbox/nv2a/nv2a_debug.h +++ b/hw/xbox/nv2a/nv2a_debug.h @@ -34,10 +34,12 @@ #include #include "gl/gloffscreen.h" +void gl_debug_initialize(void); void gl_debug_message(bool cc, const char *fmt, ...); void gl_debug_group_begin(const char *fmt, ...); void gl_debug_group_end(void); void gl_debug_label(GLenum target, GLuint name, const char *fmt, ...); +void gl_debug_frame_terminator(void); # define NV2A_GL_DPRINTF(cc, format, ...) \ gl_debug_message(cc, "nv2a: " format, ## __VA_ARGS__) @@ -47,6 +49,8 @@ void gl_debug_label(GLenum target, GLuint name, const char *fmt, ...); gl_debug_group_end() # define NV2A_GL_DLABEL(target, name, format, ...) \ gl_debug_label(target, name, "nv2a: { " format " }", ## __VA_ARGS__) +#define NV2A_GL_DFRAME_TERMINATOR() \ + gl_debug_frame_terminator() #else # define NV2A_GL_DPRINTF(cc, format, ...) do { \ @@ -55,6 +59,7 @@ void gl_debug_label(GLenum target, GLuint name, const char *fmt, ...); # define NV2A_GL_DGROUP_BEGIN(format, ...) do { } while (0) # define NV2A_GL_DGROUP_END() do { } while (0) # define NV2A_GL_DLABEL(target, name, format, ...) do { } while (0) +# define NV2A_GL_DFRAME_TERMINATOR() do { } while (0) #endif #endif diff --git a/hw/xbox/nv2a/nv2a_pgraph.c b/hw/xbox/nv2a/nv2a_pgraph.c index c45b68e26f..dd7ffb91db 100644 --- a/hw/xbox/nv2a/nv2a_pgraph.c +++ b/hw/xbox/nv2a/nv2a_pgraph.c @@ -650,9 +650,7 @@ static void pgraph_method(NV2AState *d, GET_MASK(pg->regs[NV_PGRAPH_SURFACE], NV_PGRAPH_SURFACE_WRITE_3D)); - if (glFrameTerminatorGREMEDY) { - glFrameTerminatorGREMEDY(); - } + NV2A_GL_DFRAME_TERMINATOR(); break; }